百度PaddlePaddle:

 

百度正式發佈PaddlePaddle深度強化學習框架PARL

近日,百度PaddlePaddle正式發佈了深度強化學習框架 PARL,同時開源了基於該框架的、在 NeurIPS 2018 強化學習賽事中奪冠的模型完整訓練代碼。c++

項目地址以下:https://github.com/PaddlePaddle/PARLgit

PARL 框架的名字來源於 PAddlepaddle Reinfocement Learning,是一款基於百度 PaddlePaddle 打造的深度強化學習框架。PARL 與現有強化學習工具和平臺相比,具備更高的可擴展性、可復現性和可複用性,支持大規模並行和稀疏特徵,可以快速 對工業級應用案例的驗證。程序員

百度正式發佈PaddlePaddle深度強化學習框架PARL

爲了幫助用戶快速搭建能夠和環境交互的機器人,PARL 抽象出數個基礎類,包括 Model、Algorithm、Agent 等。github

Model 類負責強化學習算法中的網絡前向計算(forward)部分,一般嵌套在 Algorithm 類中。web

Algorithm 類則定義了網絡的更新機制(backward),一般屬於一個 Agent。算法

Agent 類負責和環境進行交互,負責數據 I/O,而且收集數據訓練集下的 algorithm。docker

 

百度正式發佈PaddlePaddle深度強化學習框架PARL

經過這樣的設計方案,PARL 保證了算法的可擴展性:針對同一個場景,用戶想調研不一樣的網絡結構對算法效果影響的時候,好比調研 RNN 建模或者 CNN 建模,只須要重寫 model 部分便可;針對不一樣場景想用同一個算法調研的時候,也是也只需重寫 model 便可。可復現性主要體如今框架提供的 algorithm 集合上,在下一段和複用性一塊兒結合理解。編程

此外,PARL 的這種結構設計方式也保證了高複用性。倉庫內的提供了大量經典算法的例子 (algorithms 目錄內), 包括主流的 DQN 、DDQN、Dueling DQN、DDPG、PPO 等,值得注意的是,這些算法因爲和網絡結構進行了解耦(網絡結構的定義在 Model 類中),所以,算法並不針對特定任務,而至關於一個至關通用的算法抽象。用戶在經過 PARL 搭建強化學習算法來解決本身目前遇到的問題時,能夠直接 import 這些經典算法,而後只須要定義本身的網絡前向部分,便可在短期內構建出經典的 RL 算法。這種高複用性在極大地下降了用戶的開發成本以外,也讓 PARL 提供的多個算法的完整的超參數列表得以確保倉庫內模型具有復現論文級別指標的能力。瀏覽器

下圖是 PARL 官方提供的一個構建示例,展現瞭如何快速構建能夠解決 Atari 遊戲的 DQN 模型。用戶只須要定一個前向網絡(Model 類),而後調用框架算法集合裏面的 DQN algorithm 便可構建一個經典 DQN 算法了。DQN 算法裏面的繁瑣的構建 target 網絡,同步 target 網絡參數等細節,已經包含在構建的 algorithm 裏面,用戶無需再特別關注服務器

百度正式發佈PaddlePaddle深度強化學習框架PARL

百度對強化學習的關注由來已久。早在 2012 年,百度就將在 multi-armed bandit 問題上的研究成果部署到了推薦系統中,應用於搜索、對話、推薦等產品,經過點擊反饋結合在線訓練的方式,動態調整探索 (exploration) 和收益 (exploitation) 的平衡點,在下降探索風險的同時最大化推薦收益。近年來,強化學習在百度工業應用方面落地在了鳳巢,新聞 Feed 推薦等產品線上,在學術方面也在機器人控制、通用人工智能等領域發表了多篇學術論文。2018 年,在第二屆機器人控制會議 CoRL 上,百度發表了干預強化學習機制的工做。而在 NeurIPS 2018 的強化學習賽事上,百度也擊敗了 400 多支來自全球各個研究機構的參賽隊伍,得到冠軍。

隨着強化學習領域的發展,多家 AI 公司都在嘗試進行深度強化學習框架的設計,好比 Intel 的 Coach、OpenAI 的 baseline、Google 的 Dopamine 等。現在的開源社區中仍然是「百家爭鳴」態勢,並未出現一個主導的 RL 框架。

這其中主要的一個緣由是強化學習近年來發展迅猛,新的研究方向不斷涌現致使設計框架難以追趕算法自己的發展速度。從 15 年 Deepmind 發表 DQN 算法以來,大量的 DQN 算法變種紛紛涌現,包括 Double DQN、Dueling DQN、Rainbow 等,同時在連續控制 (continuous control RL),分層控制 (hierarchical RL),多機器人控制 (multi-agent RL) 上涌現出至關多的新技術,甚至和元學習(meta-learning)以及環境建模(model-based)等結合起來。當前社區中存在的開源框架都可支持上述的一部分算法,可是因爲技術迭代太快,並無一個框架可以覆蓋全部新算法。

第二個緣由是深度強化學習算法和應用,具備方法各異、超參難調、隨機性大等特色,即使是針對同一個問題,使用同一種算法,不一樣的實現方式會帶來極大的差別,學術界也一再強調強化學習可復現性問題。綜合這些因素,要實現一個統一的模型和計算平臺,是至關困難的事情。

PARL 在設計之初就將上述問題考慮在內,強調可複製(reproducible)可重用(reusable)以及可擴展(extensible)。

此外,因爲 PARL 基於百度內部的成熟應用開源,所以更能方便地定製大規模並行算法。經過調用簡單的函數接口,用戶能夠將算法從單機版擴展成 GA3C、A3C、IMPALA 等並行訓練架構。PARL 對於通信機制,數據 I/O 等也有獨特的加速處理。此外,基於 PaddlePaddle 對大規模工業級排序/推薦等稀疏模型的支持能力,PARL 也能輕鬆擴展到百億級別數據或特徵的訓練。

百度正式發佈PaddlePaddle深度強化學習框架PARL

根據百度在 NeurIPS 上作的技術分享,基於 PARL 最多能夠同時經過 8 塊 GPU 來拉動近 20000 個 CPU 節點運算,徹底發揮整個 CPU 集羣的計算潛力,在 NeurIPS 2018 強化學習賽事中,成功將須要近 5 個小時迭代一輪的 PPO 算法加速到了不到 1 分鐘每輪,實現了相對單機運算數百倍的加速比。這種目前開源社區中框架難以支持的並行提速,是他們拿下本次冠軍的關鍵因素之一。

百度正式發佈PaddlePaddle深度強化學習框架PARL
 
 

PaddlePaddle實戰NLP經典模型 BiGRU + CRF詳解

命名實體識別(Named Entity Recognition,NER)是 NLP 幾個經典任務之一,通俗易懂的來講,他就是從一段文本中抽取出需求的關鍵詞,如地名,人名等。

如上圖所示,Google、IBM、Baidu 這些都是企業名、Chinese、U.S. 都是地名。就科學研究來講,命名實體是很是通用的技術,相似任務型對話中的槽位識別(Slot Filling)、基礎語言學中的語義角色標註(Semantic Role Labelling)都變相地使用了命名實體識別的技術;而就工業應用而言,命名實體其實就是序列標註(Sequential Tagging),是除分類外最值得信賴和應用最廣的技術,例如智能客服、網絡文本分析,關鍵詞提取等。

下面咱們先帶您瞭解一些 Gated RNN 和 CRF 的背景知識,而後再教您一步一步用 Paddle Paddle 實現一個命名實體任務。另外,咱們採用經典的 CoNLL 數據集。

Part-1:RNN 基礎知識

循環神經網絡(Recurrent Neural Networks,RNN)是有效建模有時序特徵輸入的方式。它的原理實際上很是簡單,能夠被如下簡單的張量公式建模:

其中函數 f, g 是自定的,能夠非線性,也能夠就是簡單的線性變換,比較經常使用的是:

雖然理論上 RNN 能建模無限長的序列,但由於不少數值計算(如梯度彌散、過擬合等)的緣由導致 RNN 實際能收容的長度很小。等等相似的緣由催生了門機制。

大量實驗證實,基於門機制(Gate Mechanism)能夠必定程度上緩解 RNN 的梯度彌散、過擬合等問題。LSTM 是最廣爲應用的 Gated RNN,它的結構以下:

如上圖所示,運算 tanh(取值 -1 ~ 1) 和 α(Sigmoid,取值 0 – 1)表示控制濾過信息的 「門」。

除了 LSTM 外,GRU(Gated Recurrent Unit) 也是一種經常使用的 Gated RNN:

  • 因爲結構相對簡單,相比起 LSTM,GRU 的計算速度更快;
  • 因爲參數較少,在小樣本數據及上,GRU 的泛化效果更好;

事實上,一些相似機器閱讀的任務要求高效計算,你們都會採用 GRU。甚至如今有不少工做開始爲了效率而採用 Transformer 的結構。

Part-2:CRF 基礎知識

給定輸入 X=(x_1,x_2,⋯,x_n),通常 RNN 模型輸出標註序列 Y=(y_1,y_2,⋯,y_n) 的辦法就是簡單的貪心,在每一個詞上作 argmax,忽略了類別之間的時序依存關係。

線性鏈條件隨機場(Linear Chain Conditional Random Field),是基於馬爾科夫性建模時序序列的有效方法。算法上能夠利用損失 l(x)=-log⁡(exp⁡〖(x〗)) 的函數特色作前向計算;用維特比算法(其實是動態規劃,所以比貪心解碼確定好)作逆向解碼。

形式上,給定發射特徵(由 RNN 編碼器得到)矩陣 E 和轉移(CRF 參數矩陣,須要在計算圖中被損失函數反向優化)矩陣 T,可計算給定輸入輸出的匹配得分:

其中 X 是輸入詞序列,y 是預測的 label 序列。而後使如下目標最大化:

以上就是 CRF 的核心原理。固然要實現一個 CRF,尤爲是支持 batch 的 CRF,難度很是高,很是容易出 BUG 或低效的問題。以前筆者用 Pytorch 時就很是不便,一方面手動實現不是特別方便,另外一方面用截取開源代碼接口很差用。然而 PaddlePaddle 就很棒,它原生的提供了 CRF 的接口,同時支持損失函數計算和反向解碼等功能。

Part-3:建模思路

咱們數據簡單來講就是一句話。目前比較流行建模序列標註的方法是 BIO 標註,其中 B 表示 Begin,即標籤的起始;I 表示 In,即標籤的內部;O 表示 other,即非標籤詞。以下面圖所示,低端的 w_i,0≤i≤4 表示輸入,頂端的輸出表示 BIO 標註。

模型的結構也如上圖所示,咱們首先用 Bi-GRU(忽略圖中的 LSTM) 循環編碼以獲取輸入序列的特徵,而後再用 CRF 優化解碼序列,從而達到比單用 RNNs 更好的效果。

Part-4:PaddlePaddle實現

終於到了動手的部分。本節將會一步一步教您如何用 PaddlePaddle 實現 BiGRU + CRF 作序列標註。因爲是demo,咱們力求簡單,讓您可以將精力放到最核心的地方!

# 導入 PaddlePaddle 函數庫.
import paddle
from paddle import fluid

# 導入內置的 CoNLL 數據集.
from paddle.dataset import conll05

# 獲取數據集的內置字典信息.
word_dict, _, label_dict = conll05.get_dict()

WORD_DIM = 32           # 超參數: 詞向量維度.
BATCH_SIZE = 10         # 訓練時 BATCH 大小.
EPOCH_NUM = 20          # 迭代輪數數目.
HIDDEN_DIM = 512        # 模型隱層大小.
LEARNING_RATE = 1e-1    # 模型學習率大小.

# 設置輸入 word 和目標 label 的變量.
word = fluid.layers.data(name='word_data', shape=[1], dtype='int64', lod_level=1)
target = fluid.layers.data(name='target', shape=[1], dtype='int64', lod_level=1)

# 將詞用 embedding 表示並經過線性層.
embedding = fluid.layers.embedding(size=[len(word_dict), WORD_DIM], input=word,
                                  param_attr=fluid.ParamAttr(name="emb", trainable=False))
hidden_0 = fluid.layers.fc(input=embedding, size=HIDDEN_DIM, act="tanh")

# 用 RNNs 獲得輸入的提取特徵並作變換.
hidden_1 = fluid.layers.dynamic_lstm(
    input=hidden_0, size=HIDDEN_DIM,
    gate_activation='sigmoid',
    candidate_activation='relu',
    cell_activation='sigmoid')
feature_out = fluid.layers.fc(input=hidden_1, size=len(label_dict), act='tanh')

# 調用內置 CRF 函數並作狀態轉換解碼.
crf_cost = fluid.layers.linear_chain_crf(
    input=feature_out, label=target,
    param_attr=fluid.ParamAttr(name='crfw', learning_rate=LEARNING_RATE))
avg_cost = fluid.layers.mean(crf_cost)

# 調用 SGD 優化函數並優化平均損失函數.
fluid.optimizer.SGD(learning_rate=LEARNING_RATE).minimize(avg_cost)

# 聲明 PaddlePaddle 的計算引擎.
place = fluid.CPUPlace()
exe = fluid.Executor(place)
main_program = fluid.default_main_program()
exe.run(fluid.default_startup_program())

# 因爲是 DEMO 所以用測試集訓練模型.
feeder = fluid.DataFeeder(feed_list=[word, target], place=place)
shuffle_loader = paddle.reader.shuffle(paddle.dataset.conll05.test(), buf_size=8192)
train_data = paddle.batch(shuffle_loader, batch_size=BATCH_SIZE)

# 按 FOR 循環迭代訓練模型並打印損失.
batch_id = 0
for pass_id in range(EPOCH_NUM):
    for data in train_data():
        data = [[d[0], d[-1]] for d in data]
        cost = exe.run(main_program, feed=feeder.feed(data), fetch_list=[avg_cost])

        if batch_id % 10 == 0:
            print("avg_cost:\t" + str(cost[0][0]))
        batch_id = batch_id + 1

相信通過本節您已經掌握了用 PaddlePaddle 實現一個經典序列標註模型的技術~

 


 

 

PaddlePaddle-GitHub的正確打開姿式

GitHub是一個面向開源及私有軟件項目的託管平臺、也是項目版本管理工具,會使用它是程序員入門的必備技能。PaddlePaddle也不例外,全部的源碼及項目進展都在GitHub上開源公佈。但對於剛入門寫程序的同窗來講,一打開GitHub看起來雲裏霧裏,會有種無從下手的感受,本文給同窗介紹PaddlePaddle在GitHub倉庫上的快速上手指南。

PaddlePaddle項目介紹

登陸GitHub帳號後,會進入到你的主頁。在左上角的搜索處搜索PaddlePaddle便可進入PaddlePaddle項目主頁面:

在倉庫選項卡上方,已經置頂了4個最經常使用的倉庫(Repositories,如下簡稱Repo):

Paddle:這個Repo中,存放了PaddlePaddle框架的全部代碼。因爲在Python調用時的包名叫Paddle,倉庫遂起名叫Paddle。

Paddle Mobile: Paddle Mobile是移動端及嵌入式設備的深度學習框架。他與PaddlePaddle框架緊密結合,減小中間翻譯形成的性能損失,使得運行PaddlePaddle模型時運行性能極高,兼容設備很是普遍,支持安卓、iOS、ARM開發板、麒麟芯片、Mali GPU、驍龍GPU、樹莓派等,而且支持FPGA開發板。若是您在進行深度學習移動端開發,強烈建議使用Paddle Mobile框架。

Models:是PaddlePaddle官方的模型庫,裏面提供了深度學習諸多領域的經典模型復現。在每次PaddlePaddle版本更新後,咱們的測試及研發人員都會對其中每個模型在20種模擬開發環境下進行測試,以確保用戶在學習使用中避免出現問題。目前對於倉庫內大部分經典模型都應配備了相應的預訓練模型,歡迎你們來體驗。

Book:Book是Jupyter notebook的簡稱,是目前主流的機器學習案例教學方案,具備免安裝PaddlePaddle、免配置環境、提供交互式web編程頁面的優點。PaddlePaddle團隊爲初學者提供的八個典型的實驗案例,包含深度學習主流的幾個方向。Book使用Docker+jupyter的打包方案,使初學者即裝即用。

後面的部分是PaddlePaddle生態中全部的項目(repo),例如PARL是PaddlePaddle強化學習框架,FluidDoc包含了全部PaddlePaddle相關的文檔,這裏就不一一列舉了。

四大置頂項目介紹

1、GitHub Repo的功能介紹:

進入到Paddle倉庫以後(每個Repo皆是如此)

區域①: 右上角有三個按鈕: 

Watch是對Paddle倉庫保持關注,若是此倉庫有更新的動態就會推到你的我的主頁上。

Star是點贊加收藏的結合體,用戶能夠經過一個repo的star數來判斷公衆對他的承認度。您Star過的repo均可以經過點擊頭像,下拉框中的your star中找到:

Fork是將倉庫的代碼所有拷貝至你的帳戶中,除了備份功能外,未來還能夠對Paddle項目提交Pull request。

區域②: 在接下來的選項卡中:

Code就是訪問這個repo時默認打開的頁面,展現了這個repo的代碼結構

Issues是向Paddle研發人員提問的小社區,在Paddle的issues中有研發同窗24小時值班,你們有問題隨時提問喲。

Pull requests裏面給你們公示了全部貢獻者給Paddle核心分支提交代碼的審覈進度、審覈失敗的緣由以及那些代碼經過了審覈。

Projects是GitHub中的項目管理方式,裏面展現的是一個一個項目看板,看板上每個待辦的項目的進展進度。

Wiki中是Paddle項目及開發層面上的一些知識文檔和規範文檔

Insights顯示Paddle倉庫最近的活動信息、倉庫信息和該倉庫的各項指標,讓用戶輕鬆瞭解該倉庫的活動傾向。

區域③: 再下面一欄中: 

表示此項目有過21423次代碼更新,有14條項目分支,公開發布過21個版本,有180個代碼貢獻者以及遵循Apache-2.0協議規範。下面的彩虹條表示各語言的代碼在項目中所佔的比例。

2、Paddle Repo介紹:

區域④:佔頁面的最主要部分是文件內容及代碼的目錄結構:

Benchmark目錄裏存放了性能評測對比的結果、代碼以及數據

Cmake目錄裏存放的是源碼編譯之間的鏈式結構

doc目錄裏存放的是文檔文件,但此目錄已經再也不維護,已遷移至FluidDoc Repo

Go目錄裏存放的是使用go語言編寫具有高性能通訊分佈式代碼。

Paddle目錄裏存放的是Paddle底層C++以及CUDA的實現代碼

Python目錄裏存放的是Python接口的實現以及調用方式

Tool目錄裏存放的是一些工程檢測和代碼調試的工具

在實際開發過程當中,看的最多的就是Python目錄,在下圖目錄中展現了Python各類函數接口的實現方法:

這裏有在使用Paddle時用到的各類函數包,例如在Paddle中常見的data_feeder、executor、io、optimizer。若是在開發過程當中對某個函數、算子的實現、使用方式比較疑惑,能夠在這裏直接查看Python接口的源碼來弄明白問題。

3、Paddle Mobile Repo介紹:

Benchmark是Paddle Mobile框架在各個硬件平臺,用各個經典算法的運行效率測試結果。

Demo是官方提供的Paddle Mobile測試demo程序下載腳本,有安卓版和iOS版

Doc裏存放着給開發者提供的Paddle Mobile在各個硬件平臺的開發指南

Metal是iOS的一個圖形渲染框架,裏面提供了Paddle Mobile在此框架下的結合代碼

Src是source的縮寫,裏面存放的是Paddle Mobile的實現代碼

Test目錄裏放的是研發人員用來測試模型、op用的工程代碼,能夠用 CMake編譯成二進制執行文件。

Tools裏存放的大可能是在移動端所須要的調試程序,好比iOS編譯程序、安卓調試腳本、中斷監視程序。

4、Models Repo:

Models是PaddlePaddle的模型倉庫,在此repo中,展現瞭如何用 PaddlePaddle 來解決常見的機器學習任務,提供若干種不一樣的易學易用的神經網絡模型。

Models下fluid是PaddlePaddle最新版本的模型實現代碼,在這裏按照深度學習的應用方向(語音合成、圖像、天然語言處理、語音轉錄等)進行分類。

預訓練權重地址存放在每一個細分項目的readme.md文檔裏,打開細分項目的文檔,拉至最下方,例如image_classification:

能夠看到一個Released models的表格。在表格的model列是模型的名稱,這個名稱是一個超連接,連接對應的是這個模型的預訓練權重下載地址,點擊模型名稱便可下載相應的預訓練模型。

預訓練模型使用攻略可參考文章:

《PaddlePaddle預訓練模型大合集,還有官方使用說明書》 

5、Book Repo:

Book是PaddlePaddle針對初學者的一個特點教程,它是一本「交互式」電子書 —— 每一章均可以運行在一個Jupyter Notebook裏。

由項目截圖能夠看出,一共提供了8個學習項目。學習項目安排得不只按部就班,並且包含了多個目前深度學習的主流方向:圖像分類、抽象數據處理、推薦系統、文本序列化、角色語義標註、情感分析系統、機器翻譯系統。

Paddle-book將Jupyter、PaddlePaddle、以及各類被依賴的軟件都打包進一個Docker image了。因此您不須要本身來安裝各類軟件以及PaddlePaddle,只須要安裝Docker便可。

安裝Docker後,只須要在命令行窗口裏運行一步,就會從DockerHub.com下載和運行本書的Docker image:

docker run -d -p 8888:8888 paddlepaddle/book

下載完成後,在本地瀏覽器中訪問 http://localhost:8888,便可閱讀和在線編輯本書。因爲Jupyter的特性,您甚至能夠直接在上面運行代碼。

Paddle-book漫遊指南就到這裏結束了,想了解更多的小夥伴能夠登陸PaddlePaddle的GitHub體驗一下:https://github.com/PaddlePaddle/

您也能夠登陸PaddlePaddle的官網:www.paddlepaddle.org,經過右上方的連接進入: 

新年就要到啦,祝你們在新的一年裏PaddlePaddle學的愉快,用的舒心。

 


PaddlePaddle源代碼解析之:Parameter切分邏輯分析#1994

相關參數

  • --parameter_block_size - 參數服務器的參數分塊大小。若是未設置,將會自動計算出一個合適的值.

    • 類型: int32 (默認: 0).
  • --parameter_block_size_for_sparse - 參數服務器稀疏更新的參數分塊大小。若是未設置,將會自動計算出一個合適的值.

    • 類型: int32 (默認: 0).

相關數據結構

 

parameter_block_size

本地以ParameterSegments爲單位。

 

ParameterSegments和parameter是一一對應的

parameter block切分邏輯代碼位置

詳細的計算過程在下面prepareSendData中。
void ParameterClient2::sendAndReceiveParameter()
void ParameterClient2::prepareSendData()

serverId的計算:

nameHash:由parameterName決定
blockId:由parameter_block_size和當前所取到的block偏移有關係。
int serverId = std::abs((blockId + nameHash) % serviceNum_);

prepare data 詳解

在調用sendAndReceiveParameter以前,首先要調用prepareSendData,preparedata負責切分好parameter數據,並分配到合適的pserver上。下面是dense parameter的過程:

 

最後的parallelInputIovs是作切分的地方,SendJob這個數據結構中,包含了具體的數據parallelInputIovs,上面的for循環中,經過beginDim和endDim來控制buf的地址,實現切分。

 

preparedata生成的sendJob,會被放入sendJobQueue_

 

最終會調用ProtoClient的send發送出去

 

結論:

parameter切分是把parameter當成一個buf,按blocksize切分。

相關文章
相關標籤/搜索