PaddlePaddle釋出新版API,簡化深度學習程式設計
PaddlePaddle是百度於2016年9月開源的一款分散式深度學習平臺,為百度內部多項產品提供深度學習演算法支援。為了使PaddlePaddle更加易用,我們已經做了一系列的工作,包括使用Kubernetes叢集管理系統來進行部署與執行。
2017年3月11日,我們很高興地釋出新API的Alpha版0.10.0rc1,以及《深度學習入門教程》。目前教程包括八個示例程式,均可以在Jupyter Notebook上執行,即使用者可以通過網頁瀏覽文件並執行程式。
使用新API,PaddlePaddle的程式程式碼將大幅縮短。下圖對比展示了一個卷積神經網路在舊API(圖左半邊)和新API(圖右半邊)的效果。
新API能達到如此顯著的程式碼簡化效果,有以下三個關鍵的設計思想。
一個新的概念模型
我們的設計原則是:讓使用者在神經網路中表達和解決實際的問題,並用更加靈活的方式來描述新的深度學習演算法。因此,新模型包含以下幾部分概念:
- 模型(model)是一個或多個拓撲結構的組合。
- 拓撲結構(topology)是一系列層的表示式。
- 層(layer)可以是任何型別的計算函式,包括損失(cost)函式。
- 有些層有梯度引數,有些層沒有,大多數損失函式沒有引數。
- 在一些拓撲結構中,層與層之間共享引數。
- 對於多個拓撲結構間存在引數共享的情況,PaddlePaddle能自動找出並建立這些引數。
下面,通過兩個例子來展示我們的一些設計思想。
層與層之間共享引數
假設我們要學習一個文字詞向量f,訓練樣本是“對查詢Q來說,搜尋結果A比B更準確”,任務目標是:sim(f(A), f(Q)) > sim(f(B), f(Q)),也就是f(A)和f(Q)的相似度,大於f(B)和f(Q)的相似度。為了學習f,我們構建了一個三分支的網路結構:
A -> f -
Q -> f --> cost
B -> f -/
這裡的模型實際上是x -> f
,但我們需要重複三次來學習f,以下虛擬碼展示瞭如何構建這樣一個模型:
def f(in): e = paddle.layer.embedding(in, parameter_name="embedding") o = paddle.layer.softmax(e, parameter_name="semantic") return o # 建立三個拓撲結構(子模型),由於它們對應每一層的引數名都相同,因此三個拓撲結構共享引數。 fA = f(paddle.layer.data(input_name="A")) fB = f(paddle.layer.data(input_name="B")) fQ = f(paddle.layer.data(input_name="Q")) # 使用交叉熵代價損失函式,並取最小值。 topology = paddle.layer.less_than( paddle.layer.cross_entropy_cost(fA, fQ), paddle.layer.corss_entropy_cost(fB, fQ)) # 自動建立引數 parameters = paddle.parameters.create(topology)
拓撲結構之間共享引數
假設GAN模型包含兩個拓撲結構d0和d1,d0和d1之間共享了引數。因此在訓練過程中,更新一個拓撲結構的引數時可能需要同時更新另一個。如果使用舊API,使用者將不得不訪問非常底層的API,這部分API介面通常相對晦澀,且文件不全。而使用新API,GAN模型僅需幾十行即可,虛擬碼如下:
def G(in):
# 生成器,本示例中假設只含有一層。
return paddle.layer.fc(in, parameter_name="G")
def D(in, parameters_mutable);
# 對抗器,本示例中假設只含有一層。
# parameters_mutable表示是否需要更新引數。
return paddle.layer.fc(in, parameters_name="D", parameters_mutable)
# 建立第一個拓撲結構d0,包括生成器G和對抗器D,但訓練過程中只更新G的引數。
d0 = paddle.layer.should_be_false(
D(G(paddle.layer.data()),
False))
# 建立第二個拓撲結構d1,只包含對抗器D,訓練過程中更新D的引數。
# 注意:d1和d0的引數是共享的。
d1 = paddle.layer.should_be_true(D(paddle.layer.data()))
# 自動建立引數
parameters = paddle.parameters.create([d0, d1])
可組合的資料載入模組
在工業屆的AI應用中,資料載入部分通常需要大量的原始碼。為了減輕使用者的這部分工作量,新API的資料介面設計包含幾個部分:
-
reader
:從本地、網路、分散式檔案系統等讀取資料,也可隨機生成資料,並返回一個或多個數據項。 -
reader creator
:一個返回reader
的函式。 -
reader decorator
:裝飾器,可組合一個或多個reader
。 -
batch reader
:與reader
類似,但可批量返回一個或多個數據項。
下面展示了一個隨機生成資料,並返回單個數據項的reader creator
函式:
def reader_creator():
def reader():
while True:
yield numpy.random.uniform(-1, 1, size=784)
return reader
新API還有助於資料載入操作的複用。例如,我們定義兩個reader
,分別是impressions()
和clicks()
,前者用於讀取搜尋引擎的日誌流資料,後者用於讀取點選流資料;然後,我們可以通過預定義的reader decorator
快取並組合這些資料,再對合並後的資料進行亂序操作:
r = paddle.reader.shuffle(
paddle.reader.compose(
paddle.reader(impressions(impression_url), buf_size=8192),
paddle.reader(clicks(click_url), buf_size=8192), 4096)
如果我們希望只使用資料集中的前5000個樣本來進行小型實驗,程式碼如下:
paddle.reader.firstn(r, 5000)
此外,我們釋出了paddle.datasets包,為教程中的八個示例程式都提供了預定義好的資料載入介面。第一次呼叫時會自動下載公共資料集並進行預處理,之後的呼叫則會從本地快取中自動讀取。
更高層次的API
PaddlePaddle是一個誕生在工業界的系統,從一開始就強調支援分散式訓練。但在編寫分散式程式時,舊API暴露了很多使用者不需要知道的細節。另外,PaddlePaddle的C++程式碼中的訓練過程是一個for迴圈結構,不能跑在互動式的Jupyter Notebook上。因此,我們釋出了新API,提供了一些更高層次的介面,如train(訓練介面)、test(測試介面)和infer(應用介面)。這些新API既能在本地執行,將來也支援在Kubernets叢集上執行分散式作業。
以上述的三分支模型和GAN模型為例,下面展示train
和infer
的使用思路。
####三分支模型####
# 訓練時,使用read_ranking_model_data讀入資料,更新topology中的parameters。
paddle.train(topology, parameters, reader=read_ranking_model_data)
# 應用時,因為fA、fB和fQ共享引數,因此只需要fA的引數即可。
[testA, testB, testQ] = read_ranking_model_data()
print "The sematic-vector of testA: ", paddle.infer(fA, parameters, testA)
####GAN模型####
# 迴圈訓練d0和d1,注意兩者的訓練資料不同。
for ...:
train(d0, parameters, reader=read_from_rng)
train(d1, parameters, reader=read_from_realistic_images)
# 使用d1來做應用:
print "D thinks a batch of images are realistic", paddle.infer(d1, parameters, read_mnist_images)
我們會持續優化新API,上述設計思想的具體實現會在0.10.0版中完成,同時也歡迎您的評論、反饋和程式碼貢獻!
參考文獻
1.PaddlePaddle’s New API Simplifies Deep Learning Programs.
2.PaddlePaddle Design Doc.
3.PaddlePaddle Python Data Reader Design Doc.
關於《深度學習入門教程》
這本書脫胎於PaddlePaddle Team的線上教材《深度學習入門》,包括新手入門、識別數字、影象分類、詞向量、情感分析、語義角色標註、機器翻譯、個性化推薦等內容。
以下是《深度學習入門》一書的目錄:
線上閱讀:http://book.paddlepaddle.org/index.html