當前位置:首頁 » 編程語言 » python實現rnn

python實現rnn

發布時間: 2022-04-29 22:43:24

❶ 遞歸神經網路RNN怎樣加速

原文來源:medium
作者:Illia Polosukhin
「機器人圈」編譯:多啦A亮
如果你讀過我的博客,你可能已經了解到我是一個TensorFlow的貢獻者,並在那裡建立了很多高級API。
而在2017年2月,我已經離開谷歌並創立了自己的公司——NEAR.ai。我們教機器用自然語言編寫代碼。
作為這項工作的一部分,我們正在構建以樹格式讀取或編寫代碼的深度學習模型。在試圖用TensorFlow管理這種復雜性之後,我已經決定嘗試用一下PyTorch。
PyTorch是由Facebook AI研究人員構建的框架,並且在自然語言和強化學習研究領域越來越受歡迎。它的主要優點是動態圖形構建原理——與Tensorflow相比,其中圖形一旦被構建,然後就會被「執行」多次,PyTorch可以使用簡單的python邏輯動態重建圖形,就像你正在使用numpy數組進行計算一樣。

來源: http://pytorch.org/about
這種靈活性吸引了一些人,他們使用復雜輸入/輸出數據(例如語言、樹、圖形)或需要在計算中運行一些自定義邏輯(深度強化學習)。
在這里我想談談批處理的事情。即使PyTorch利用GPU加速器快速運行,並且通常推進C模塊的計算,如果你沒有對計算進行批處理——你仍然需要付出代價。
遞歸神經網路(以樹形LSTM為例)特別難以批處理,因為每個示例都是不同的樹。
單純的實現將如下所示:
class TreeLSTM(nn.Mole):
def __init__(self, num_units):
super(TreeLSTM, self).__init__()
self.num_units = num_units
self.left = nn.Linear(num_units, 5 * num_units)
self.right = nn.Linear(num_units, 5 * num_units)
def forward(self, left_in, right_in):
lstm_in = self.left(left_in[0])
lstm_in += self.right(right_in[0])
a, i, f1, f2, o = lstm_in.chunk(5, 1)
c = (a.tanh() * i.sigmoid() + f1.sigmoid() * left_in[1] +
f2.sigmoid() * right_in[1])
h = o.sigmoid() * c.tanh()
return h, c
class SPINN(nn.Mole):
def __init__(self, n_classes, size, n_words):
super(SPINN, self).__init__()
self.size = size
self.tree_lstm = TreeLSTM(size)
self.embeddings = nn.Embedding(n_words, size)
self.out = nn.Linear(size, n_classes)
def leaf(self, word_id):
return self.embeddings(word_id), Variable(torch.FloatTensor(word_id.size()[0], self.size))
def children(self, left_h, left_c, right_h, right_c):
return self.tree_lstm((left_h, left_c), (right_h, right_c))
def logits(self, encoding):
return self.out(encoding)
def encode_tree_regular(model, tree):
def encode_node(node):
if node.is_leaf():
return model.leaf(Variable(torch.LongTensor([node.id])))
else:
left_h, left_c = encode_node(node.left)
right_h, right_c = encode_node(node.right)
return model.children(left_h, left_c, right_h, right_c)
encoding, _ = encode_node(tree.root)
return model.logits(encoding)
...
all_logits, all_labels = [], []
for tree in batch:
all_logits.append(encode_tree_regular(model, tree))
all_labels.append(tree.label)
loss = criterion(torch.cat(all_logits, 0), Variable(torch.LongTensor(all_labels)))
有一種手動批處理的方法:在每次處理輸入不同的操作之後,找出如何批處理輸入,然後解除輸出批處理。這是James Bradbury在其文章中的一個例子。
另一種選擇是,根據我們要計算的確切輸入/輸出,找到一個系統決定為我們的批處理對象。靈感來自Moshe等人的論文中描述的方法。 「動態計算圖深度學習」(在TensorFlow Fold 中實現但似乎並不被支持),在這個動畫中有很好的描繪:

來源:http://github.com/tensorflow/fold
我已經在一個簡單的TorchFold中實現了這個原理:
class TorchFold(object):
def __init__(self, versatible=False, cuda=False):
def add(self, op, *args):
def apply(self, nn, return_values):
現在,如果我們想用以前的gist對樹形LSTM / 模型進行編碼,那麼我們需要這樣更改代碼:
from pytorch_tools import torchfold
def encode_tree_fold(fold, tree):
return fold.add('leaf', node.id).split(2)
return fold.add('children', left_h, left_c, right_h, right_c).split(2)
return fold.add('logits', encoding)
fold = torchfold.Fold(cuda=args.cuda)
all_logits.append(encode_tree_folded(fold, tree))
res = fold.apply(model, [all_logits, all_labels])
loss = criterion(res[0], res[1])
這里,在每次調用encode_tree_folded時,通過fold.add添加節點來動態構建「折疊」圖,其中op是要調用的模型中的函數的名稱。它會自動顯示哪些op可以組合在一起,哪些應該遵循。
然後在fold.apply,調用傳遞的模型的操作,傳遞它們的批處理的輸入張量(可能在不同的步驟有不同的批處理大小),並自動輸出到接下來的步驟。
比較未折疊和折疊版本之間的速度(在這里的簡單模型https://github.com/nearai/pytorch-tools/blob/master/examples/snli/spinn-example.py):
常規:0.18秒/步(100 dim),2.19秒/步(500 dim)
折疊:0.05秒/步(100 dim),0.22秒/步(500 dim)
由於降低了計算非有效效率,提升了3-10倍的速度。
該工具通常對於任何復雜的架構(包括RNN)都是有用的,因為它至少在第一個實驗中不需要考慮批處理。
你可以在這里找到實現和示例:https://github.com/nearai/pytorch-tools
另外,在撰寫本文時,我發現最近有關於這個主題的文章 - https://arxiv.org/pdf/1705.07860.pdf, DyNet的實現。
還有就是,自從升級到PyTorch 0.2.0後,我發現TorchFold的性能略有下降,所以為了最佳速度,嘗試運行0.1.12直到穩定即可。

❷ 如何用TensorFlow構建RNN

基本使用
使用 TensorFlow, 你必須明白 TensorFlow:
使用圖 (graph) 來表示計算任務。
在被稱之為 會話 (Session) 的上下文 (context) 中執行圖。
使用 tensor 表示數據。
通過 變數 (Variable) 維護狀態。
使用 feed 和 fetch 可以為任意的操作(arbitrary operation) 賦值或者從其中獲取數據。
綜述
TensorFlow 是一個編程系統, 使用圖來表示計算任務。 圖中的節點被稱之為 op
(operation 的縮寫)。 一個 op 獲得 0 個或多個 Tensor, 執行計算,
產生 0 個或多個 Tensor. 每個 Tensor 是一個類型化的多維數組。
例如, 你可以將一小組圖像集表示為一個四維浮點數數組,
這四個維度分別是 [batch, height, width, channels].
一個 TensorFlow 圖描述了計算的過程。 為了進行計算, 圖必須在 會話 里被啟動。
會話 將圖的 op 分發到諸如 CPU 或 GPU 之類的 設備 上, 同時提供執行 op 的方法。
這些方法執行後, 將產生的 tensor 返回。 在 Python 語言中, 返回的 tensor 是
numpy ndarray 對象; 在 C 和 C++ 語言中, 返回的 tensor 是
tensorflow::Tensor 實例。
計算圖
TensorFlow 程序通常被組織成一個構建階段和一個執行階段。 在構建階段, op 的執行步驟
被描述成一個圖。 在執行階段, 使用會話執行執行圖中的 op.
例如, 通常在構建階段創建一個圖來表示和訓練神經網路, 然後在執行階段反復執行圖中的訓練 op.
TensorFlow 支持 C, C++, Python 編程語言。 目前, TensorFlow 的 Python 庫更加易用,
它提供了大量的輔助函數來簡化構建圖的工作, 這些函數尚未被 C 和 C++ 庫支持。
三種語言的會話庫 (session libraries) 是一致的。
構建圖
構建圖的第一步, 是創建源 op (source op)。 源 op 不需要任何輸入, 例如 常量 (Constant)。 源 op 的輸出被傳遞給其它 op 做運算。
Python 庫中, op 構造器的返回值代表被構造出的 op 的輸出, 這些返回值可以傳遞給其它
op 構造器作為輸入。
TensorFlow Python 庫有一個默認圖 (default graph), op 構造器可以為其增加節點。 這個默認圖對
許多程序來說已經足夠用了。 閱讀 Graph 類 文檔
來了解如何管理多個圖。
import tensorflow as tf
# 創建一個常量 op, 產生一個 1x2 矩陣。 這個 op 被作為一個節點
# 加到默認圖中。
#
# 構造器的返回值代表該常量 op 的返回值。
matrix1 = tf.constant([[3., 3.]])
# 創建另外一個常量 op, 產生一個 2x1 矩陣。
matrix2 = tf.constant([[2.],[2.]])
# 創建一個矩陣乘法 matmul op , 把 'matrix1' 和 'matrix2' 作為輸入。
# 返回值 'proct' 代表矩陣乘法的結果。
proct = tf.matmul(matrix1, matrix2)
默認圖現在有三個節點, 兩個 constant() op, 和一個matmul() op. 為了真正進行矩陣相乘運算, 並得到矩陣乘法的
結果, 你必須在會話里啟動這個圖。
在一個會話中啟動圖
構造階段完成後, 才能啟動圖。 啟動圖的第一步是創建一個 Session 對象, 如果無任何創建參數,
會話構造器將啟動默認圖。
欲了解完整的會話 API, 請閱讀Session 類。
# 啟動默認圖。
sess = tf.Session()
# 調用 sess 的 'run()' 方法來執行矩陣乘法 op, 傳入 'proct' 作為該方法的參數。
# 上面提到, 'proct' 代表了矩陣乘法 op 的輸出, 傳入它是向方法表明, 我們希望取回
# 矩陣乘法 op 的輸出。
#
# 整個執行過程是自動化的, 會話負責傳遞 op 所需的全部輸入。 op 通常是並發執行的。
#
# 函數調用 'run(proct)' 觸發了圖中三個 op (兩個常量 op 和一個矩陣乘法 op) 的執行。
#
# 返回值 'result' 是一個 numpy `ndarray` 對象。
result = sess.run(proct)
print result
# ==> [[ 12.]]
# 任務完成, 關閉會話。
sess.close()
Session 對象在使用完後需要關閉以釋放資源。 除了顯式調用 close 外, 也可以使用 "with" 代碼塊
來自動完成關閉動作。
with tf.Session() as sess:
result = sess.run([proct])
print result
在實現上, TensorFlow 將圖形定義轉換成分布式執行的操作, 以充分利用可用的計算資源(如 CPU
或 GPU)。 一般你不需要顯式指定使用 CPU 還是 GPU, TensorFlow 能自動檢測。 如果檢測到 GPU, TensorFlow
會盡可能地利用找到的第一個 GPU 來執行操作。
如果機器上有超過一個可用的 GPU, 除第一個外的其它 GPU 默認是不參與計算的。 為了讓 TensorFlow
使用這些 GPU, 你必須將 op 明確指派給它們執行。 withDevice 語句用來指派特定的 CPU 或 GPU

❸ python的機器學習是什麼

可以算很有關系,因為現在大眾說的人工智慧 指的是自動化, 在計算機領域 機器學習就是通過數據來學模型,自動做預測的
機器學習是數據分析更上一層樓的任務, 如果你能學號數據分析,那應該也能學得來機器學習
Python有很完善的機器學習工具包 就叫sklearn

❹ 百度paddle會和python一樣,成為最流行的深度學習引擎嗎

1)Caffe具有出色的CNN實現功能的開發語言,在計算機視覺領域,Caffe仍然是最流行的工具包。Caffe的開發語言支持C++和Cuda,速度很快,但是由於一些歷史性的遺留架構問題,它的靈活性不夠強。而且對遞歸網路和語言建模的支持很差。Caffe支持所有主流開發系統,上手難度屬於中等水平。

2)TensorFlow是一個理想的RNN
API實現,它使用了向量運算的符號圖方法,使得開發的速度可以很快。TensorFlow支持的比較好的系統只有各種Linux系統和OSX,不過其對語言的支持比較全面,包含了Python、C++和Cuda等,開發者文檔寫得沒有Caffe那麼全面,所以上手比較難,在性能方面,也不如Caffe及PaddlePaddle。

3)Torch沒有跟隨Python的潮流,反而選擇了C語言實現,用Lua語言進行封裝。Torch對卷積網路的支持非常好,運行在C++、C#和Jave等工業語言的速度較快,也不需要額外的編譯。但是它的上手難度也很高,對初學者缺乏規范的例子,而且需要先邁過Lua的門檻,這對初學者是很大的障礙。

4)而此次網路的PaddlePaddle性能優先並兼顧靈活,通過使用GPU異構計算來提升每台機器的數據處理能力,獲得了業內「相當簡潔、設計干凈、穩定,速度較快,顯存佔用較小」等好評。

而在關鍵的進入門檻上,相比Google TensorFlow和Facebook
Torch,PaddlePaddle的上手難度低得多,且擁有非常優秀的業界特徵,包括NLP和推薦等應用場景、對RNN很好的支持、高質量代碼、以及分布式訓練等,已經足以滿足大多數AI場景的需求。且PaddlePaddle更加務實,可解決實際問題。

據徐偉介紹,PaddlePaddle將在本月底發布最新版本,全面支持Mac操作系統、以及Cuda8.0和GCC5.4,同時進一步優化了安裝過程,可以幫助更多開放者更好地「上手」。

❺ Python要哪些要點要學習

階段一:Python開發基礎
Python全棧開發與人工智慧之Python開發基礎知識學習內容包括:Python基礎語法、數據類型、字元編碼、文件操作、函數、裝飾器、迭代器、內置方法、常用模塊等。
階段二:Python高級編程和資料庫開發
Python全棧開發與人工智慧之Python高級編程和資料庫開發知識學習內容包括:面向對象開發、Socket網路編程、線程、進程、隊列、IO多路模型、Mysql資料庫開發等。
階段三:前端開發
Python全棧開發與人工智慧之前端開發知識學習內容包括:Html、CSS、JavaScript開發、Jquery&bootstrap開發、前端框架VUE開發等。
階段四:WEB框架開發
Python全棧開發與人工智慧之WEB框架開發學習內容包括:Django框架基礎、Django框架進階、BBS+Blog實戰項目開發、緩存和隊列中間件、Flask框架學習、Tornado框架學習、Restful API等。
階段五:爬蟲開發
Python全棧開發與人工智慧之爬蟲開發學習內容包括:爬蟲開發實戰。
階段六:全棧項目實戰
Python全棧開發與人工智慧之全棧項目實戰學習內容包括:企業應用工具學習、CRM客戶關系管理系統開發、路飛學城在線教育平台開發等。
階段七:演算法&設計模式
階段八:數據分析
Python全棧開發與人工智慧之數據分析學習內容包括:金融量化分析。
階段九:機器學習、圖像識別、NLP自然語言處理
Python全棧開發與人工智慧之人工智慧學習內容包括:機器學習、圖形識別、人工智慧玩具開發等。
階段十:Linux系統&百萬級並發架構解決方案
階段十一:高並發語言GO開發
Python全棧開發與人工智慧之高並發語言GO開發學習內容包括:GO語言基礎、數據類型與文件IO操作、函數和面向對象、並發編程等。

❻ python怎麼做快速圖像分割演算法

時間序列模型最常用最強大的的工具就是遞歸神經網路(recurrent neural network, RNN)。相比與普通神經網路的各計算結果之間相互獨立的特點,RNN的每一次隱含層的計算結果都與當前輸入以及上一次的隱含層結果相關。
通過這種方法,RNN的計算結果便具備了記憶之前幾次結果的特點。

❼ 深度學習 python怎麼入門 知乎

自學深度學習是一個漫長而艱巨的過程。您需要有很強的線性代數和微積分背景,良好的Python編程技能,並扎實掌握數據科學、機器學習和數據工程。即便如此,在你開始將深度學習應用於現實世界的問題,並有可能找到一份深度學習工程師的工作之前,你可能需要一年多的學習和實踐。然而,知道從哪裡開始,對軟化學習曲線有很大幫助。如果我必須重新學習Python的深度學習,我會從Andrew Trask寫的Grokking deep learning開始。大多數關於深度學習的書籍都要求具備機器學習概念和演算法的基本知識。除了基本的數學和編程技能之外,Trask的書不需要任何先決條件就能教你深度學習的基礎知識。這本書不會讓你成為一個深度學習的向導(它也沒有做這樣的聲明),但它會讓你走上一條道路,讓你更容易從更高級的書和課程中學習。用Python構建人工神經元
大多數深度學習書籍都是基於一些流行的Python庫,如TensorFlow、PyTorch或Keras。相比之下,《運用深度學習》(Grokking Deep Learning)通過從零開始、一行一行地構建內容來教你進行深度學習。

《運用深度學習》
你首先要開發一個人工神經元,這是深度學習的最基本元素。查斯克將帶領您了解線性變換的基本知識,這是由人工神經元完成的主要計算。然後用普通的Python代碼實現人工神經元,無需使用任何特殊的庫。
這不是進行深度學習的最有效方式,因為Python有許多庫,它們利用計算機的圖形卡和CPU的並行處理能力來加速計算。但是用普通的Python編寫一切對於學習深度學習的來龍去是非常好的。
在Grokking深度學習中,你的第一個人工神經元只接受一個輸入,將其乘以一個隨機權重,然後做出預測。然後測量預測誤差,並應用梯度下降法在正確的方向上調整神經元的權重。有了單個神經元、單個輸入和單個輸出,理解和實現這個概念變得非常容易。您將逐漸增加模型的復雜性,使用多個輸入維度、預測多個輸出、應用批處理學習、調整學習速率等等。
您將通過逐步添加和修改前面章節中編寫的Python代碼來實現每個新概念,逐步創建用於進行預測、計算錯誤、應用糾正等的函數列表。當您從標量計算轉移到向量計算時,您將從普通的Python操作轉移到Numpy,這是一個特別擅長並行計算的庫,在機器學習和深度學習社區中非常流行。
Python的深度神經網路
有了這些人造神經元的基本構造塊,你就可以開始創建深層神經網路,這基本上就是你將幾層人造神經元疊放在一起時得到的結果。
當您創建深度神經網路時,您將了解激活函數,並應用它們打破堆疊層的線性並創建分類輸出。同樣,您將在Numpy函數的幫助下自己實現所有功能。您還將學習計算梯度和傳播錯誤通過層傳播校正跨不同的神經元。

隨著您越來越熟悉深度學習的基礎知識,您將學習並實現更高級的概念。這本書的特點是一些流行的正規化技術,如早期停止和退出。您還將獲得自己版本的卷積神經網路(CNN)和循環神經網路(RNN)。
在本書結束時,您將把所有內容打包到一個完整的Python深度學習庫中,創建自己的層次結構類、激活函數和神經網路體系結構(在這一部分,您將需要面向對象的編程技能)。如果您已經使用過Keras和PyTorch等其他Python庫,那麼您會發現最終的體系結構非常熟悉。如果您沒有,您將在將來更容易地適應這些庫。
在整本書中,查斯克提醒你熟能生巧;他鼓勵你用心編寫自己的神經網路,而不是復制粘貼任何東西。
代碼庫有點麻煩
並不是所有關於Grokking深度學習的東西都是完美的。在之前的一篇文章中,我說過定義一本好書的主要內容之一就是代碼庫。在這方面,查斯克本可以做得更好。
在GitHub的Grokking深度學習庫中,每一章都有豐富的jupiter Notebook文件。jupiter Notebook是一個學習Python機器學習和深度學習的優秀工具。然而,jupiter的優勢在於將代碼分解為幾個可以獨立執行和測試的小單元。Grokking深度學習的一些筆記本是由非常大的單元格組成的,其中包含大量未注釋的代碼。

這在後面的章節中會變得尤其困難,因為代碼會變得更長更復雜,在筆記本中尋找自己的方法會變得非常乏味。作為一個原則問題,教育材料的代碼應該被分解成小單元格,並在關鍵區域包含注釋。
此外,Trask在Python 2.7中編寫了這些代碼。雖然他已經確保了代碼在Python 3中也能順暢地工作,但它包含了已經被Python開發人員棄用的舊編碼技術(例如使用「for i in range(len(array))」範式在數組上迭代)。
更廣闊的人工智慧圖景
Trask已經完成了一項偉大的工作,它匯集了一本書,既可以為初學者,也可以為有經驗的Python深度學習開發人員填補他們的知識空白。
但正如泰溫·蘭尼斯特(Tywin Lannister)所說(每個工程師都會同意),「每個任務都有一個工具,每個工具都有一個任務。」深度學習並不是一根可以解決所有人工智慧問題的魔杖。事實上,對於許多問題,更簡單的機器學習演算法,如線性回歸和決策樹,將表現得和深度學習一樣好,而對於其他問題,基於規則的技術,如正則表達式和幾個if-else子句,將優於兩者。

關鍵是,你需要一整套工具和技術來解決AI問題。希望Grokking深度學習能夠幫助你開始獲取這些工具。
你要去哪裡?我當然建議選擇一本關於Python深度學習的深度書籍,比如PyTorch的深度學習或Python的深度學習。你還應該加深你對其他機器學習演算法和技術的了解。我最喜歡的兩本書是《動手機器學習》和《Python機器學習》。
你也可以通過瀏覽機器學習和深度學習論壇,如r/MachineLearning和r/deeplearning subreddits,人工智慧和深度學習Facebook組,或通過在Twitter上關注人工智慧研究人員來獲取大量知識。
AI的世界是巨大的,並且在快速擴張,還有很多東西需要學習。如果這是你關於深度學習的第一本書,那麼這是一個神奇旅程的開始。

❽ 如何用PyTorch實現遞歸神經網路

從 Siri 到谷歌翻譯,深度神經網路已經在機器理解自然語言方面取得了巨大突破。這些模型大多數將語言視為單調的單詞或字元序列,並使用一種稱為循環神經網路(recurrent neural network/RNN)的模型來處理該序列。但是許多語言學家認為語言最好被理解為具有樹形結構的層次化片語,一種被稱為遞歸神經網路(recursive neural network)的深度學習模型考慮到了這種結構,這方面已經有大量的研究。雖然這些模型非常難以實現且效率很低,但是一個全新的深度學習框架 PyTorch 能使它們和其它復雜的自然語言處理模型變得更加容易。

雖然遞歸神經網路很好地顯示了 PyTorch 的靈活性,但它也廣泛支持其它的各種深度學習框架,特別的是,它能夠對計算機視覺(computer vision)計算提供強大的支撐。PyTorch 是 Facebook AI Research 和其它幾個實驗室的開發人員的成果,該框架結合了 Torch7 高效靈活的 GPU 加速後端庫與直觀的 Python 前端,它的特點是快速成形、代碼可讀和支持最廣泛的深度學習模型。

開始 SPINN

鏈接中的文章(https://github.com/jekbradbury/examples/tree/spinn/snli)詳細介紹了一個遞歸神經網路的 PyTorch 實現,它具有一個循環跟蹤器(recurrent tracker)和 TreeLSTM 節點,也稱為 SPINN——SPINN 是深度學習模型用於自然語言處理的一個例子,它很難通過許多流行的框架構建。這里的模型實現部分運用了批處理(batch),所以它可以利用 GPU 加速,使得運行速度明顯快於不使用批處理的版本。

SPINN 的意思是堆棧增強的解析器-解釋器神經網路(Stack-augmented Parser-Interpreter Neural Network),由 Bowman 等人於 2016 年作為解決自然語言推理任務的一種方法引入,該論文中使用了斯坦福大學的 SNLI 數據集。

該任務是將語句對分為三類:假設語句 1 是一幅看不見的圖像的准確標題,那麼語句 2(a)肯定(b)可能還是(c)絕對不是一個准確的標題?(這些類分別被稱為蘊含(entailment)、中立(neutral)和矛盾(contradiction))。例如,假設一句話是「兩只狗正跑過一片場地」,蘊含可能會使這個語句對變成「戶外的動物」,中立可能會使這個語句對變成「一些小狗正在跑並試圖抓住一根棍子」,矛盾能會使這個語句對變成「寵物正坐在沙發上」。

特別地,研究 SPINN 的初始目標是在確定語句的關系之前將每個句子編碼(encoding)成固定長度的向量表示(也有其它方式,例如注意模型(attention model)中將每個句子的每個部分用一種柔焦(soft focus)的方法相互比較)。

數據集是用句法解析樹(syntactic parse tree)方法由機器生成的,句法解析樹將每個句子中的單詞分組成具有獨立意義的短語和子句,每個短語由兩個詞或子短語組成。許多語言學家認為,人類通過如上面所說的樹的分層方式來組合詞意並理解語言,所以用相同的方式嘗試構建一個神經網路是值得的。下面的例子是數據集中的一個句子,其解析樹由嵌套括弧表示:

( ( The church ) ( ( has ( cracks ( in ( the ceiling ) ) ) ) . ) )

這個句子進行編碼的一種方式是使用含有解析樹的神經網路構建一個神經網路層 Rece,這個神經網路層能夠組合詞語對(用詞嵌入(word embedding)表示,如 GloVe)、 和/或短語,然後遞歸地應用此層(函數),將最後一個 Rece 產生的結果作為句子的編碼:

X = Rece(「the」, 「ceiling」)
Y = Rece(「in」, X)
... etc.

但是,如果我希望網路以更類似人類的方式工作,從左到右閱讀並保留句子的語境,同時仍然使用解析樹組合短語?或者,如果我想訓練一個網路來構建自己的解析樹,讓解析樹根據它看到的單詞讀取句子?這是一個同樣的但方式略有不同的解析樹的寫法:

The church ) has cracks in the ceiling ) ) ) ) . ) )

或者用第 3 種方式表示,如下:

WORDS: The church has cracks in the ceiling .
PARSES: S S R S S S S S R R R R S R R

我所做的只是刪除開括弧,然後用「S」標記「shift」,並用「R」替換閉括弧用於「rece」。但是現在可以從左到右讀取信息作為一組指令來操作一個堆棧(stack)和一個類似堆棧的緩沖區(buffer),能得到與上述遞歸方法完全相同的結果:

1. 將單詞放入緩沖區。
2. 從緩沖區的前部彈出「The」,將其推送(push)到堆棧上層,緊接著是「church」。
3. 彈出前 2 個堆棧值,應用於 Rece,然後將結果推送回堆棧。
4. 從緩沖區彈出「has」,然後推送到堆棧,然後是「cracks」,然後是「in」,然後是「the」,然後是「ceiling」。
5. 重復四次:彈出 2 個堆棧值,應用於 Rece,然後推送結果。
6. 從緩沖區彈出「.」,然後推送到堆棧上層。
7. 重復兩次:彈出 2 個堆棧值,應用於 Rece,然後推送結果。
8. 彈出剩餘的堆棧值,並將其作為句子編碼返回。

我還想保留句子的語境,以便在對句子的後半部分應用 Rece 層時考慮系統已經讀取的句子部分的信息。所以我將用一個三參數函數替換雙參數的 Rece 函數,該函數的輸入值為一個左子句、一個右子句和當前句的上下文狀態。該狀態由神經網路的第二層(稱為循環跟蹤器(Tracker)的單元)創建。Tracker 在給定當前句子上下文狀態、緩沖區中的頂部條目 b 和堆棧中前兩個條目 s1\s2 時,在堆棧操作的每個步驟(即,讀取每個單詞或閉括弧)後生成一個新狀態:

context[t+1] = Tracker(context[t], b, s1, s2)

容易設想用你最喜歡的編程語言來編寫代碼做這些事情。對於要處理的每個句子,它將從緩沖區載入下一個單詞,運行跟蹤器,檢查是否將單詞推送入堆棧或執行 Rece 函數,執行該操作;然後重復,直到對整個句子完成處理。通過對單個句子的應用,該過程構成了一個大而復雜的深度神經網路,通過堆棧操作的方式一遍又一遍地應用它的兩個可訓練層。但是,如果你熟悉 TensorFlow 或 Theano 等傳統的深度學習框架,就知道它們很難實現這樣的動態過程。你值得花點時間回顧一下,探索為什麼 PyTorch 能有所不同。

圖論

圖 1:一個函數的圖結構表示

深度神經網路本質上是有大量參數的復雜函數。深度學習的目的是通過計算以損失函數(loss)度量的偏導數(梯度)來優化這些參數。如果函數表示為計算圖結構(圖 1),則向後遍歷該圖可實現這些梯度的計算,而無需冗餘工作。每個現代深度學習框架都是基於此反向傳播(backpropagation)的概念,因此每個框架都需要一個表示計算圖的方式。

在許多流行的框架中,包括 TensorFlow、Theano 和 Keras 以及 Torch7 的 nngraph 庫,計算圖是一個提前構建的靜態對象。該圖是用像數學表達式的代碼定義的,但其變數實際上是尚未保存任何數值的佔位符(placeholder)。圖中的佔位符變數被編譯進函數,然後可以在訓練集的批處理上重復運行該函數來產生輸出和梯度值。

這種靜態計算圖(static computation graph)方法對於固定結構的卷積神經網路效果很好。但是在許多其它應用中,有用的做法是令神經網路的圖結構根據數據而有所不同。在自然語言處理中,研究人員通常希望通過每個時間步驟中輸入的單詞來展開(確定)循環神經網路。上述 SPINN 模型中的堆棧操作很大程度上依賴於控制流程(如 for 和 if 語句)來定義特定句子的計算圖結構。在更復雜的情況下,你可能需要構建結構依賴於模型自身的子網路輸出的模型。

這些想法中的一些(雖然不是全部)可以被生搬硬套到靜態圖系統中,但幾乎總是以降低透明度和增加代碼的困惑度為代價。該框架必須在其計算圖中添加特殊的節點,這些節點代表如循環和條件的編程原語(programming primitive),而用戶必須學習和使用這些節點,而不僅僅是編程代碼語言中的 for 和 if 語句。這是因為程序員使用的任何控制流程語句將僅運行一次,當構建圖時程序員需要硬編碼(hard coding)單個計算路徑。

例如,通過詞向量(從初始狀態 h0 開始)運行循環神經網路單元(rnn_unit)需要 TensorFlow 中的特殊控制流節點 tf.while_loop。需要一個額外的特殊節點來獲取運行時的詞長度,因為在運行代碼時它只是一個佔位符。

# TensorFlow
# (this code runs once, ring model initialization)
# 「words」 is not a real list (it』s a placeholder variable) so
# I can』t use 「len」
cond = lambda i, h: i < tf.shape(words)[0]
cell = lambda i, h: rnn_unit(words[i], h)
i = 0
_, h = tf.while_loop(cond, cell, (i, h0))

基於動態計算圖(dynamic computation graph)的方法與之前的方法有根本性不同,它有幾十年的學術研究歷史,其中包括了哈佛的 Kayak、自動微分庫(autograd)以及以研究為中心的框架 Chainer和 DyNet。在這樣的框架(也稱為運行時定義(define-by-run))中,計算圖在運行時被建立和重建,使用相同的代碼為前向通過(forward pass)執行計算,同時也為反向傳播(backpropagation)建立所需的數據結構。這種方法能產生更直接的代碼,因為控制流程的編寫可以使用標準的 for 和 if。它還使調試更容易,因為運行時斷點(run-time breakpoint)或堆棧跟蹤(stack trace)將追蹤到實際編寫的代碼,而不是執行引擎中的編譯函數。可以在動態框架中使用簡單的 Python 的 for 循環來實現有相同變數長度的循環神經網路。

# PyTorch (also works in Chainer)
# (this code runs on every forward pass of the model)
# 「words」 is a Python list with actual values in it
h = h0
for word in words:
h = rnn_unit(word, h)

PyTorch 是第一個 define-by-run 的深度學習框架,它與靜態圖框架(如 TensorFlow)的功能和性能相匹配,使其能很好地適合從標准卷積神經網路(convolutional network)到最瘋狂的強化學習(reinforcement learning)等思想。所以讓我們來看看 SPINN 的實現。

代碼

在開始構建網路之前,我需要設置一個數據載入器(data loader)。通過深度學習,模型可以通過數據樣本的批處理進行操作,通過並行化(parallelism)加快訓練,並在每一步都有一個更平滑的梯度變化。我想在這里可以做到這一點(稍後我將解釋上述堆棧操作過程如何進行批處理)。以下 Python 代碼使用內置於 PyTorch 的文本庫的系統來載入數據,它可以通過連接相似長度的數據樣本自動生成批處理。運行此代碼之後,train_iter、dev_iter 和 test_itercontain 循環遍歷訓練集、驗證集和測試集分塊 SNLI 的批處理。

from torchtext import data, datasets
TEXT = datasets.snli.ParsedTextField(lower=True)
TRANSITIONS = datasets.snli.ShiftReceField()
LABELS = data.Field(sequential=False)train, dev, test = datasets.SNLI.splits(
TEXT, TRANSITIONS, LABELS, wv_type='glove.42B')TEXT.build_vocab(train, dev, test)
train_iter, dev_iter, test_iter = data.BucketIterator.splits(
(train, dev, test), batch_size=64)

你可以在 train.py中找到設置訓練循環和准確性(accuracy)測量的其餘代碼。讓我們繼續。如上所述,SPINN 編碼器包含參數化的 Rece 層和可選的循環跟蹤器來跟蹤句子上下文,以便在每次網路讀取單詞或應用 Rece 時更新隱藏狀態;以下代碼代表的是,創建一個 SPINN 只是意味著創建這兩個子模塊(我們將很快看到它們的代碼),並將它們放在一個容器中以供稍後使用。

import torchfrom torch import nn
# subclass the Mole class from PyTorch』s neural network package
class SPINN(nn.Mole):
def __init__(self, config):
super(SPINN, self).__init__()
self.config = config self.rece = Rece(config.d_hidden, config.d_tracker)
if config.d_tracker is not None:
self.tracker = Tracker(config.d_hidden, config.d_tracker)

當創建模型時,SPINN.__init__ 被調用了一次;它分配和初始化參數,但不執行任何神經網路操作或構建任何類型的計算圖。在每個新的批處理數據上運行的代碼由 SPINN.forward 方法定義,它是用戶實現的方法中用於定義模型向前過程的標准 PyTorch 名稱。上面描述的是堆棧操作演算法的一個有效實現,即在一般 Python 中,在一批緩沖區和堆棧上運行,每一個例子都對應一個緩沖區和堆棧。我使用轉移矩陣(transition)包含的「shift」和「rece」操作集合進行迭代,運行 Tracker(如果存在),並遍歷批處理中的每個樣本來應用「shift」操作(如果請求),或將其添加到需要「rece」操作的樣本列表中。然後在該列表中的所有樣本上運行 Rece 層,並將結果推送回到它們各自的堆棧。

def forward(self, buffers, transitions):
# The input comes in as a single tensor of word embeddings;
# I need it to be a list of stacks, one for each example in
# the batch, that we can pop from independently. The words in
# each example have already been reversed, so that they can
# be read from left to right by popping from the end of each
# list; they have also been prefixed with a null value.
buffers = [list(torch.split(b.squeeze(1), 1, 0))
for b in torch.split(buffers, 1, 1)]
# we also need two null values at the bottom of each stack,
# so we can from the nulls in the input; these nulls
# are all needed so that the tracker can run even if the
# buffer or stack is empty
stacks = [[buf[0], buf[0]] for buf in buffers]
if hasattr(self, 'tracker'):
self.tracker.reset_state()
for trans_batch in transitions:
if hasattr(self, 'tracker'):
# I described the Tracker earlier as taking 4
# arguments (context_t, b, s1, s2), but here I
# provide the stack contents as a single argument
# while storing the context inside the Tracker
# object itself.
tracker_states, _ = self.tracker(buffers, stacks)
else:
tracker_states = itertools.repeat(None)
lefts, rights, trackings = [], [], []
batch = zip(trans_batch, buffers, stacks, tracker_states)
for transition, buf, stack, tracking in batch:
if transition == SHIFT:
stack.append(buf.pop())
elif transition == REDUCE:
rights.append(stack.pop())
lefts.append(stack.pop())
trackings.append(tracking)
if rights:
reced = iter(self.rece(lefts, rights, trackings))
for transition, stack in zip(trans_batch, stacks):
if transition == REDUCE:
stack.append(next(reced))
return [stack.pop() for stack in stacks]

在調用 self.tracker 或 self.rece 時分別運行 Tracker 或 Rece 子模塊的向前方法,該方法需要在樣本列表上應用前向操作。在主函數的向前方法中,在不同的樣本上進行獨立的操作是有意義的,即為批處理中每個樣本提供分離的緩沖區和堆棧,因為所有受益於批處理執行的重度使用數學和需要 GPU 加速的操作都在 Tracker 和 Rece 中進行。為了更干凈地編寫這些函數,我將使用一些 helper(稍後將定義)將這些樣本列表轉化成批處理張量(tensor),反之亦然。

我希望 Rece 模塊自動批處理其參數以加速計算,然後解批處理(unbatch)它們,以便可以單獨推送和彈出。用於將每對左、右子短語表達組合成父短語(parent phrase)的實際組合函數是 TreeLSTM,它是普通循環神經網路單元 LSTM 的變型。該組合函數要求每個子短語的狀態實際上由兩個張量組成,一個隱藏狀態 h 和一個存儲單元(memory cell)狀態 c,而函數是使用在子短語的隱藏狀態操作的兩個線性層(nn.Linear)和將線性層的結果與子短語的存儲單元狀態相結合的非線性組合函數 tree_lstm。在 SPINN 中,這種方式通過添加在 Tracker 的隱藏狀態下運行的第 3 個線性層進行擴展。

圖 2:TreeLSTM 組合函數增加了第 3 個輸入(x,在這種情況下為 Tracker 狀態)。在下面所示的 PyTorch 實現中,5 組的三種線性變換(由藍色、黑色和紅色箭頭的三元組表示)組合為三個 nn.Linear 模塊,而 tree_lstm 函數執行位於框內的所有計算。圖來自 Chen et al. (2016)。

❾ 對於Python的學習人員需要掌握哪些技術

1. 網路編程。網路編程在生活和開發中無處不在,哪裡有通訊就有網路,它可以稱為是一切開發的「基石」。對於所有編程開發人員必須要知其然並知其所以然,所以網路部分將從協議、封包、解包等底層進行深入剖析。
2. 爬蟲開發。將網路一切數據作為資源,通過自動化程序進行有針對性的數據採集以及處理。爬蟲開發項目包含跨越防爬蟲策略、高性能非同步IO、分布式爬蟲等,並針對Scrapy框架源碼進行深入剖析,從而理解其原理並實現自定義爬蟲框架。
3.Web開發。Web開發包含前端以及後端兩大部分,前端部分,帶你從「黑白」到「彩色」世界,手把手開發動態網頁;後端部分,帶你從10行代碼開始到n萬行來實現並使用自己的微型Web框架,框架講解中涵蓋了數據、組件、安全等多領域的知識,從底層了解其工作原理並可駕馭任何業內主流的Web框架。
4. IT自動化開發。IT運維自動化是一組將靜態的設備結構轉化為根據IT服務需求動態彈性響應的策略,目的就是實現減少人工干預、降低人員成本以及出錯概率,真刀真槍的帶你開發企業中最常用的項目,從設計層面、框架選擇、靈活性、擴展性、故障處理、以及如何優化等多個層面接觸真實的且來源於各大互聯網公司真實案例,如:堡壘機、CMDB、全網監控、主機管理等。
5. 金融分析。金融分析包含金融知識和Python相關模塊的學習,手把手帶你從金融小白到開發量化交易策略的大拿。學習內容囊括Numpy\Pandas\Scipy數據分析模塊等,以及常見金融分析策略如「雙均線」、「周規則交易」、「羊駝策略」、「Dual Thrust 交易策略」等,讓夢想照進現實,進入金融行業不再是個夢。
6. 人工智慧+機器學習。人工智慧時代來臨,率先引入深度機器學習課程。其中包含機器學習的基礎概念以及常用知識,如:分類、聚類、回歸、神經網路以及常用類庫,並根據身邊事件作為案例,一步一步經過預處理、建模、訓練以及評估和參調等。

❿ Python在大數據方向的作用除了人工智慧與機器學習還有

你可以這樣理解,人工智慧是一個嬰兒的大腦,而深度學習就是讓這個嬰兒的大腦又能力看世界、聽世界、感受世界。直觀的說,深度學習只是服務於人工智慧一個工具(也許若干年後,一種全新的工具可以代替深度學習實現人工智慧),把這個工具用在語音識別領域,就能讓機器更會聽;把他用在了計算機視覺領域,就能讓機器更會看。深度學習的本質就是各種神經網路,從最早最簡單的感知機,再到多層神經網路,再到現在很火的CNN、RNN,其目的都是構建一個合適的神經網路結構,讓機器有能力「自己思考」——我們也稱之為「智能」。關於機器學習,它是比深度學習更為廣泛的概念,發展的也比較早。在人工智慧屆有一種說法:認為機器學習是人工智慧領域中最能夠體現智能的一個分支。從歷史上看,機器學習似乎也是人工智慧中發展最快的分支之一。機器學習發展早期,限於計算機計算能力、樣本量等因素,很多演算法無法實現。而近些年來,計算機的計算能力和存儲能力都有了很大的提高,數據發掘引領了大數據時代的到來,使得原來復雜度很高的演算法能夠實現,得到的結果也更為精細。理論上,只要計算機計算能力足夠強、樣本數據量足夠大,就可以不斷增加神經網路的層數以及改變神經網路的結構,這就是「深度學習」,在理論和技術上,並沒有太多的創新。只是深度學習代表了機器學習的新方向,同時也推動了機器學習的發展。

熱點內容
sqldcl 發布:2025-05-15 07:29:18 瀏覽:198
canvas的圖像上傳 發布:2025-05-15 07:29:17 瀏覽:101
離線緩存為什麼點不動 發布:2025-05-15 07:27:17 瀏覽:828
釘鼎伺服器出口ip 發布:2025-05-15 07:13:08 瀏覽:279
移動硬碟和光碟哪個存儲時間長 發布:2025-05-15 07:04:25 瀏覽:489
壓縮一定 發布:2025-05-15 06:57:30 瀏覽:289
進棧演算法 發布:2025-05-15 06:56:02 瀏覽:215
安卓和緩存 發布:2025-05-15 06:56:02 瀏覽:428
筆記本電腦台式伺服器 發布:2025-05-15 06:40:41 瀏覽:109
4k無壓縮 發布:2025-05-15 06:02:54 瀏覽:75