淺談chainer框架

一 chainer基礎node

Chainer是一個專門爲高效研究和開發深度學習算法而設計的開源框架。 這篇博文會經過一些例子簡要地介紹一下Chainer,同時把它與其餘一些框架作比較,好比Caffe、Theano、Torch和Tensorflow。算法

大多數現有的深度學習框架是在模型訓練以前構建計算圖。 這種方法是至關簡單明瞭的,特別是對於結構固定且分層的神經網絡(好比卷積神經網絡)的實現。

然而,如今的複雜神經網絡(好比循環神經網絡或隨機神經網絡)帶來了新的性能改進和新的應用。雖然現有的框架能夠用於實現這些複雜神經網絡,可是它們有時須要一些(不優雅的)編程技巧,這可能會下降代碼的開發效率和可維護性。

而Chainer的方法是獨一無二的:即在訓練時「實時」構建計算圖。

這種方法可讓用戶在每次迭代時或者對每一個樣本根據條件更改計算圖。同時也很容易使用標準調試器和分析器來調試和重構基於Chainer的代碼,由於Chainer使用純Python和NumPy提供了一個命令式的API。 這爲複雜神經網絡的實現提供了更大的靈活性,同時又加快了迭代速度,提升了快速實現最新深度學習算法的能力。

如下我會介紹Chainer是如何工做的,以及用戶能夠從中得到什麼樣的好處。
Chainer 是一個基於Python的獨立的深度學習框架。

不一樣於其它基於Python接口的框架(好比Theano和TensorFlow),Chainer經過支持兼容Numpy的數組間運算的方式,提供了聲明神經網絡的命令式方法。Chainer 還包括一個名爲CuPy的基於GPU的數值計算庫。

>>> from chainer import Variable

>>> import numpy as np

Variable 類是把numpy.ndarray數組包裝在內的計算模塊(numpy.ndarray存放在.data中)。

>>> x = Variable(np.asarray([[0, 2],[1, -3]]).astype(np.float32))

>>> print(x.data)

[[ 0.      2.]

[ 1.     -3.]]

用戶能夠直接在Variables上定義各類運算和函數(Function的實例)。

>>> y = x ** 2 – x + 1

>>> print(y.data)

[[  1.   3.]

[  1.  13.]]

由於這些新定義的Varriable類知道他們是由什麼類生成的,因此Variable y跟它的父類有同樣的加法運算(.creator)。

>>> print(y.creator)

<chainer.functions.math.basic_math.AddConstant at 0x7f939XXXXX>

利用這種機制,能夠經過反向追蹤從最終損失函數到輸入的完整路徑來實現反向計算。完整路徑在執行正向計算的過程當中存儲,而不預先定義計算圖。

在chainer.functions類中給出了許多數值運算和激活函數。 標準神經網絡的運算在Chainer類中是經過Link類實現的,好比線性全鏈接層和卷積層。Link能夠看作是與其相應層的學習參數的一個函數(例如權重和誤差參數)。你也能夠建立一個包含許多其餘Link的Link。這樣的一個link容器被命名爲Chain。這容許Chainer能夠將神經網絡建模成一個包含多個link和多個chain的層次結構。Chainer還支持最新的優化方法、序列化方法以及使用CuPy的由CUDA驅動的更快速計算。

>>> import chainer.functions as F

>>> import chainer.links as L

>>> from chainer import Chain, optimizers, serializers, cuda

>>> import cupy as cp
二 chainer的設計
編程

訓練一個神經網絡通常須要三個步驟:(1)基於神經網絡的定義來構建計算圖;(2)輸入訓練數據並計算損失函數;(3)使用優化器迭代更新參數直到收斂。數組

一般,深度學習框架在步驟2以前先要完成步驟1。 咱們稱這種方法是「先定義再運行」。網絡

對於複雜神經網絡,這種「先定義再運行」的方法簡單直接,但並非最佳的,由於計算圖必須在訓練前肯定。 例如,在實現循環神經網絡時,用戶不得不利用特殊技巧(好比Theano中的scan()函數),這就會使代碼變的難以調試和維護。

與之不一樣的是,Chainer使用一種「邊運行邊定義」的獨特方法,它將第一步和第二步合併到一個步驟中去。
框架

計算圖不是在訓練以前定義的,而是在訓練過程當中得到的。 由於正向計算直接對應於計算圖而且也經過計算圖進行反向傳播,因此能夠在每次迭代甚至對於每一個樣本的正向計算中對計算圖作各類修改。函數

舉一個簡單的例子,讓咱們看看使用兩層感知器進行MNIST數字分類會發生什麼。性能

下面是Chainer中兩層感知器的實現代碼:

# 2-layer Multi-Layer Perceptron (MLP)

# 兩層的多層感知器(MLP)

class MLP(Chain):

def __init__(self):

super(MLP, self).__init__()

l1=L.Linear(784, 100),  # From 784-dimensional input to hidden unit with 100 nodes

# 從784維輸入向量到100個節點的隱藏單元

l2=L.Linear(100, 10),  # From hidden unit with 100 nodes to output unit with 10 nodes  (10 classes)

# 從100個節點的隱藏單元到10個節點的輸出單元(10個類)

# Forward computation

# 正向計算

def __call__(self, x):

h1 = F.tanh(self.l1(x))     # Forward from x to h1 through activation with tanh function

# 用tanh激活函數,從輸入x正向算出h1

y = self.l2(h1)                 # Forward from h1to y

# 從h1正向計算出y

return y

在構造函數(__init__)中,咱們分別定義了從輸入單元到隱藏單元,和從隱藏單元到輸出單元的兩個線性變換。要注意的是,這時並無定義這些變換之間的鏈接,這意味着計算圖沒有生成,更不用說固定它了。

跟「先定義後運行」方法不一樣的是,它們之間的鏈接關係會在後面的正向計算中經過定義層之間的激活函數(F.tanh)來定義。一旦對MNIST上的小批量訓練數據集(784維)完成了正向計算,就能夠經過從最終節點(損失函數的輸出)回溯到輸入來實時得到下面的計算圖(注意這裏使用SoftmaxCrossEntropy作爲損失函數):
這裏的關鍵點是神經網絡是直接用Python來定義的而不是領域特定語言,所以用戶能夠在每次迭代(正向計算)中對神經網絡進行更改。

這種神經網絡的命令性聲明容許用戶使用標準的Python語法進行網絡分支計算,而不用研究任何領域特定語言(DSL)。這跟TensorFlow、 Theano使用的符號方法以及Caffe和CNTK依賴的文本DSL相比是一個優點。

此外,可使用標準調試器和分析器來查找錯誤、重構代碼以及調整超參數。 另外一方面,儘管Torch和MXNet也容許用戶使用神經網絡的命令性建模,可是他們仍然使用「先定義後運行」的方法來構建計算圖對象,所以調試時須要特別當心。
學習

三  chainer安裝優化

在Anaconda Prompt下運行下邊的代碼便可:

pip install chainer

參考:https://blog.csdn.net/zkh880loLh3h21AJTH/article/details/78100460

相關文章
相關標籤/搜索