ユーザ用ツール

サイト用ツール


目次

機械学習とは

プログラミング無しで機械学習

機械学習プログラミング入門

初めてのKeras2.0

初めてのTensorflow(YouTube)

初めてのChainer2.0

初めてのビットコイン

ビットコイン用語集

初めてのSolidityプログラミング

初めての医療統計

初めてのエクセルで医療統計

初めてのEZRで医療統計

初めてのRStudioでレポート作成

スマホアプリ作成ソフトIonic3

スマホアプリ作成ソフトIonic4

Ionicのためのjavascript tips

その他

NiftyCloudMobileBackend

税金など

Dokuwiki

chainer2プログラミングの全体図

以前のリビジョンの文書です


Chainerプログラミングの全体図

Chainer2プログラミングの全体図

必ずしもこの書き方ではなくてもよいらしい。。。

WEB上のMNISTのサンプルコードを読んでいると、Kerasだと皆ほぼ同じコードになるのに、Chainerだと人によってコードが結構異なる感じで、初心者には本当にとっつきにくいイメージ。

Chainer 1.11.0から、Trainerというものが導入されたらしく、このサイトでは、Trainerを用いた記載方法のみ解説します。(筆者がTrainerを使用しないやり方を実行できなかったため。)

Trainerを利用する場合のChainer全体図

いきなりTrainerと言われてもさっぱりだと思いますが、コードをコピペして1個ずつ理解するのみです!

Trainerの構造は、以下のようになっているらしいです。
(出典:Chainerビギナー向けチュートリアル Vol.1

最初にこの図を見たときは何がなんだかさっぱりでしたが、この図をみながら、なんとなく、以下のコードを写経して勉強していきたいと思います。

(1)#1 Chainerを使用するためのimport文

(2)#2 データの準備・設定
from chainer import iterators
# trainerを利用するために、Iteratorを定義してdatasetにアクセスできるようにする

(3)#3 モデルの記述
class MyModel(Chain):
    def __init__(self):
        super(MyModel,self).__init__(
            # パラメータを含む関数の宣言
        )
    
    def __call__(self, ...):
    # モデルを記載

(4)#4 モデルと最適化アルゴリズムの設定
model = MyModel()
optimizer = optimizers.Adam()
optimizer.setup(model)

# UpdaterにIteratorとOptimizerを渡す
from chainer import training

updater = training.StandardUpdater(train_iter, optimizer, device=gpu_id)


(5)#5 学習


(6)#6 結果の出力とパラメータの保存

(7)

もう一度、Trainerの構造を、今度はテキストで記載。

Trainer
  |-Updater
      |-Iterator
          |-Dataset
      |-Optimizer
          |-Model
  |-Extensions 

Chainerプログラミングの全体図(2)Trainerを利用する場合

Trainerについては、以下のスライドが非常に参考になります。(といっても、私にはスライド内容の5%くらいしか理解できていない気がします、、、)

Chainer の Trainer 解説と NStepLSTM について Published on Apr 11, 2017
https://www.slideshare.net/Retrieva_jp/chainer-trainer-nsteplstm

Trainerを利用する場合のChainer全体図

「Trainerを利用する場合の全体図」 (参考:Chainer v2による実践深層学習 新納浩幸 p54)

# train.py
(1)#1 Chainerを使用するためのimport文

(2)#2 tuple_datasetによるデータの準備・設定

(3)#3 モデルの記述
class MyModel(Chain):
    def __init__(self):
        super(MyModel, self).__init__(
        # パラメータを含む関数の宣言
    )

    def __call__(self, x,t):
       # モデルを記述

(4)#4 モデルと最適化アルゴリズムの設定(ほぼお約束の3行)
model = MyModel()
optimizer = optimizers.Adam()
optimizer.setup(model)

(5)#5 学習(Trainerを利用する場合)
iterator = iterators.SerialIterator(tdata, bsize)
updater = training.StandardUpdater(iterator, optimizer)
trainer = training.Trainer(updater, (ep, ‘epoch’))
trainer.extend(extensions.ProgressBar())

trainer.run()

(6)#6 結果の出力

Chainer2でMNISTのコード

以下にコードそのものを記載します。非常に長く取っつきにくいコードですが、次回以降、順に解説させていただきます。

train_mnist_mlp.py

# original code from https://github.com/mitmul/chainer-handson/blob/master/2-Try-Trainer-class_ja.ipynb
# 解説ページ http://twosquirrel.mints.ne.jp/?p=20823
# 解説ページ内では、C:/py/chainer2/MNIST_MLP/junbi/train_jupyter.py という名前。
#1 datasetの準備
# 本当は画像からdatasetを準備するべきだが、簡便のため、今回は
# chainer.datasetsが提供するNumpy配列のmnistデータをimportする。
# chainer.datasetsを使用しないで自分で画像からchainer用のデータセットを
# 作成する方法については、以下を参照
# http://twosquirrel.mints.ne.jp/?p=20366
from chainer.datasets import mnist
train, test = mnist.get_mnist()
# --------------------------------------------- #
#2 Iteratorの準備
# ChainerにはTrainerというモジュールがあり、基本的にこれを用いて学習を行う。
# Trainerの構造は、以下の図の通りだが、Trainerが使用できるように、順番に、
# Updater, Iterator, Dataset, Optimizer, Model, Extensions
# を記載していく必要がある。
# 上記を記載した後に、trainer.run() で学習を実行する。
# Trainerの構造の図のリンク(絶対に閲覧お勧めの図)
# https://camo.qiitausercontent.com/d3af5d369c038fed989ea7839b1566ef49a6c331/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f31373933342f61373531646633312d623939392d663639322d643833392d3438386332366231633438612e706e67
from chainer import iterators
batchsize = 128
train_iter = iterators.SerialIterator(train, batchsize)
test_iter = iterators.SerialIterator(test, batchsize, False, False)
# --------------------------------------------- #
#3 Modelの準備
# ChainerのTrainerを使用するために、Modelを準備する
'''
# LinkとFunction
Chainerでは、ニューラルネットワークの各層を、LinkとFunctionに区別します。
Linkは、パラメータを持つ関数です。
Functionは、パラメータを持たない関数です。
これらを組み合わせてモデルを記述します。
'''
import chainer
import chainer.links as L
import chainer.functions as F
'''
今回は、手書き数字MNIST画像を、multiple layer perceptron(多層パーセプトロン)という
ニューラルネットワークモデルを用いて機械学習で分類します。
層構造のイメージは、以下のリンクが参考になります。
https://qiita.com/kenmatsu4/items/7b8d24d4c5144a686412
ネットワークは3層で、入力層、隠れ層、出力層の3層とします。
28x28のグレースケール画像を、0から255までの値をとる各ピクセルの値を、
784個、横に並んだ数字の配列に変換して(、さらに255で割って)、
入力層に入れます。入力層のunit数は784個となります。
中間層のunit数(n_mid_units)は、今回は、100個に設定しています。
手書き数字の0から9まで10種類の画像を分類するため、
出力層のunit数(n_out)は、10個となります。
'''
class MLP(chainer.Chain):
def __init__(self, n_mid_units=100, n_out=10):
super(MLP, self).__init__(
l1=L.Linear(None, n_mid_units),
l2=L.Linear(n_mid_units, n_mid_units),
l3=L.Linear(n_mid_units, n_out),
)
def __call__(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
return self.l3(h2)
# --------------------------------------------- #
#4 モデルと最適化アルゴリズムの設定(Updaterの準備)
'''
trainer.run()で学習をしているとき、Updaterが内部で、以下を行っている。
1.データセットからデータを取り出し(Iterator)
2.モデルに渡してロスを計算し(Model = Optimizer.target)
3.Optimizerを使ってモデルのパラメータを更新する(Optimizer)
'''
from chainer import optimizers
gpu_id = -1 # Set to -1 if you don't have a GPU
model = MLP()
if gpu_id >= 0:
model.to_gpu(gpu_id)
max_epoch = 3
# モデルをClassifierで包んで、ロスの計算などをモデルに含める
model = L.Classifier(model)
if gpu_id >= 0:
model.to_gpu(gpu_id)
# 最適化手法の選択
optimizer = optimizers.SGD()
optimizer.setup(model)
# --------------------------------------------- #
#5 学習と結果の出力
# UpdaterにIteratorとOptimizerを渡す
from chainer import training
updater = training.StandardUpdater(train_iter, optimizer, device=gpu_id)
# TrainerにUpdaterを渡す
trainer = training.Trainer(updater, (max_epoch, 'epoch'), out='mnist_result')
# TrainerにExtensionを追加
from chainer.training import extensions
# trainer.extend()で、学習の進行状況を表すプログレスバーや、lossのグラフ化と画像の保存などを行う
# 以下は、意味不明なコードが並んでいるが、分からなくてもとりあえずコピペしておく。
trainer.extend(extensions.LogReport())
trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'main/accuracy', 'validation/main/loss', 'validation/main/accuracy', 'elapsed_time']))
trainer.extend(extensions.PlotReport(['main/loss', 'validation/main/loss'], x_key='epoch', file_name='loss.png'))
trainer.extend(extensions.PlotReport(['main/accuracy', 'validation/main/accuracy'], x_key='epoch', file_name='accuracy.png'))
trainer.extend(extensions.snapshot(filename='snapshot_epoch-{.updater.epoch}'))
trainer.extend(extensions.snapshot_object(model.predictor, filename='model_epoch-{.updater.epoch}'))
trainer.extend(extensions.Evaluator(test_iter, model, device=gpu_id))
trainer.extend(extensions.dump_graph('main/loss'))
# 学習の実行(Extensionsによって、結果も出力される)
trainer.run()
# --------------------------------------------- #
#6 学習結果のパラメータの保存
# Save paramaters
chainer.serializers.save_npz('my_mnist.model', model)
# --------------------------------------------- #

Predict_mnist_mlp.py

# original code from https://github.com/mitmul/chainer-handson/blob/master/2-Try-Trainer-class_ja.ipynb
# 解説ページ http://twosquirrel.mints.ne.jp/?p=20823
# 解説ページ内では、C:/py/chainer2/MNIST_MLP/junbi/predict_jupyter.py という名前。
# predict.py
#7 推測
import numpy as np
from PIL import Image
import chainer
import chainer.functions as F
import chainer.links as L
from chainer import datasets, serializers
# Network definition
class MLP(chainer.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
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))
return self.l3(h2)
# filepath は適当に変更。今回は、chainer_MNIST_MLP_predict.pyと同じ階層に、0.jpgを保存しておき、推測する。
filepath = "0.jpg"
# モデルを使って判定する
model = L.Classifier(MLP(100, 10))
# 前回の学習結果のパラメータをインポート
serializers.load_npz('my_mnist.model', model)
# PIL(pillow)を用いてjpg画像を開き、グレースケール画像として読み込む
image = Image.open(filepath).convert('L').resize((28, 28))
# グレースケール画像をfloat32型のNumpy配列に変換し、255で割って正規化
image = np.asarray(image).astype(np.float32) / 255
# 上記Numpy配列を1次元ベクトル化(28x28を1x784にreshape)
image = image.reshape((1, -1))
# ニューラルネットワークにおけるノードに対応するオブジェクトに変換する
x = chainer.Variable(image)
# chainer.links.Classifierのpredictorで推測
y = model.predictor(x)
# y.dataという配列の中で一番大きい値をとる要素のインデックスを返す
# 今回は、インデックスの値がそのまま、数字の分類項目となっている
predict = np.argmax(y.data)
print("filepath:" , filepath , " , " , "predict:" , predict)

(1)Chainer2を使用するためのimport文

参考文献

https://qiita.com/abechi_17/items/b271b7042fae126616d7
Chainer 2.0 のMNISTサンプルで推論を動かす abechi_17 2017年07月01日に投稿

Chainer 2.0 のMNISTサンプル(公式Document) https://github.com/chainer/chainer/tree/v2.0.0/examples/mnist

Chainerの基本的な使い方
https://github.com/dsanno/deep-learning-study/blob/master/doc/chainer_basic.md

次節以降

MNISTを例に、一つずつ解説させていただきたいと思います。

いつもあまり面白くないMNISTですが、Chainer2プログラミングを理解する上で避けて通れないので、頑張ってやってみたいと思います。

リンク

chainer2プログラミングの全体図.1509626779.txt.gz · 最終更新: 2018/10/07 (外部編集)