教程:
https://bennix.github.io/
https://bennix.github.io/blog/2017/12/14/chain_basic/
https://bennix.github.io/blog/2017/12/18/Chain_Tutorial1/
模塊 | 功能 |
---|---|
datasets | 輸入數據可以被格式化為這個類的模型輸入。它涵蓋了大部分輸入數據結構的用例。 |
variable | 它是一個函數/連接/Chain的輸出。 |
functions | 支持深度學習中廣泛使用的功能的框架,例如 sigmoid, tanh, ReLU等 |
links | 支持深度學習中廣泛使用的層的框架,例如全連接層,卷積層等 |
Chain | 連接和函數(層)連接起來形成一個“模型”。 |
optimizers | 指定用於調整模型參數的什么樣的梯度下降方法,例如 SGD, AdaGrad, Adam. |
serializers | 保存/加載訓練狀態。例如 model, optimizer 等 |
iterators | 定義訓練器使用的每個小批量數據。 |
training.updater | 定義Trainer中使用的每個前向、反向傳播的參數更新過程。 |
training.Trainer | 管理訓練器 |
下面是chainer模塊的導入語句。
# Initial setup following import numpy as np import chainer from chainer import cuda, Function, gradient_check, report, training, utils, Variable from chainer import datasets, iterators, optimizers, serializers from chainer import Link, Chain, ChainList import chainer.functions as F import chainer.links as L from chainer.training import extensions
示例 minst:
MNIST數據集由70,000個尺寸為28×28(即784個像素)的灰度圖像和相應的數字標簽組成。數據集默認分為6萬個訓練圖像和10,000個測試圖像。我們可以通過datasets.get_mnist()
獲得矢量化版本(即一組784維向量)。
train, test = datasets.get_mnist()
此代碼自動下載MNIST數據集並將NumPy數組保存到 $(HOME)/.chainer
目錄中。返回的訓練集和測試集可以看作圖像標簽配對的列表(嚴格地說,它們是TupleDataset的實例)。
我們還必須定義如何迭代這些數據集。我們想要在數據集的每次掃描開始時對每個epoch的訓練數據集進行重新洗牌。在這種情況下,我們可以使用iterators.SerialIterator
。
train_iter = iterators.SerialIterator(train, batch_size=100, shuffle=True)
另一方面,我們不必洗牌測試數據集。在這種情況下,我們可以通過shuffle = False來禁止混洗。當底層數據集支持快速切片時,它使迭代速度更快。
test_iter = iterators.SerialIterator(test, batch_size=100, repeat=False, shuffle=False)
當所有的例子被訪問時,我們停止迭代通過設定 repeat=False 。測試/驗證數據集通常需要此選項;沒有這個選項,迭代進入一個無限循環。
接下來,我們定義架構。我們使用一個簡單的三層網絡,每層100個單元。
class MLP(Chain): def __init__(self, n_units, n_out): super(MLP, self).__init__() with self.init_scope(): # the size of the inputs to each layer will be inferred self.l1 = L.Linear(None, n_units) # n_in -> n_units # 第一個參數為輸入維數,第二個參數為輸出維數。這里注意,第一個參數填none時,則輸入維數將在第一次前向傳播時確定 self.l2 = L.Linear(None, n_units) # n_units -> n_units self.l3 = L.Linear(None, n_out) # n_units -> n_out def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) y = self.l3(h2) return y
該鏈接使用relu()作為激活函數。請注意,“l3”鏈接是最終的全連接層,其輸出對應於十個數字的分數。
為了計算損失值或評估預測的准確性,我們在上面的MLP連接的基礎上定義一個分類器連接:
class Classifier(Chain): def __init__(self, predictor): super(Classifier, self).__init__() with self.init_scope(): self.predictor = predictor def __call__(self, x, t): y = self.predictor(x) loss = F.softmax_cross_entropy(y, t) accuracy = F.accuracy(y, t) report({'loss': loss, 'accuracy': accuracy}, self) return loss
這個分類器類計算准確性和損失,並返回損失值。參數對x和t對應於數據集中的每個示例(圖像和標簽的元組)。 softmax_cross_entropy()
計算給定預測和基准真實標簽的損失值。 accuracy()
計算預測准確度。我們可以為分類器的一個實例設置任意的預測器連接。
report()
函數向訓練器報告損失和准確度。收集訓練統計信息的具體機制參見 Reporter
. 您也可以采用類似的方式收集其他類型的觀測值,如激活統計。
請注意,類似上面的分類器的類被定義為chainer.links.Classifier
。因此,我們將使用此預定義的Classifier
連接而不是使用上面的示例。
model = L.Classifier(MLP(100, 10)) # the input size, 784, is inferred optimizer = optimizers.SGD() optimizer.setup(model)
現在我們可以建立一個訓練器對象。
updater = training.StandardUpdater(train_iter, optimizer) trainer = training.Trainer(updater, (20, 'epoch'), out='result')
第二個參數(20,’epoch’)表示訓練的持續時間。我們可以使用epoch或迭代作為單位。在這種情況下,我們通過遍歷訓練集20次來訓練多層感知器。
為了調用訓練循環,我們只需調用run()方法。
這個方法執行整個訓練序列。
上面的代碼只是優化了參數。在大多數情況下,我們想看看培訓的進展情況,我們可以在調用run方法之前使用擴展插入。
trainer.extend(extensions.Evaluator(test_iter, model)) trainer.extend(extensions.LogReport()) trainer.extend(extensions.PrintReport(['epoch', 'main/accuracy', 'validation/main/accuracy'])) trainer.extend(extensions.ProgressBar()) trainer.run()
epoch main/accuracy validation/main/accuracy
[J total [..................................................] 0.83%
this epoch [########..........................................] 16.67%
100 iter, 0 epoch / 20 epochs
inf iters/sec. Estimated time to finish: 0:00:00.
[4A[J total [..................................................] 1.67%
this epoch [################..................................] 33.33%
200 iter, 0 epoch / 20 epochs
270.19 iters/sec. Estimated time to finish: 0:00:43.672168.
[4A[J total [#.................................................] 2.50%
this epoch [#########################.........................] 50.00%
300 iter, 0 epoch / 20 epochs
271.99 iters/sec. Estimated time to finish: 0:00:43.017048.
[4A[J total [#.................................................] 3.33%
this epoch [#################################.................] 66.67%
400 iter, 0 epoch / 20 epochs