自分用の備忘録としてchainerの書き方とIris分類を書き起こしておく
これから機械学習を始めたい方も是非参照して欲しい
# 環境
以下は自分の環境である。
- MacBook Pro(15-inch 2018)
- macOS Mojave (ver 10.14.4)
- python3 (ver 3.7.2)
- chainer (ver 5.3.0)
- numpy (ver 1.17.0)
- pandas (ver 0.24.2)
import
上記を使える状態にするためにインポートをする。
これで機械学習に必要なライブラリを使えるようになる。
import chainer
import chainer.links as L
import chainer.functions as F
ここにある... as ~
というのは...をこれ以降~という呼び方をしても呼び出せるようにしている。
便利なので覚えておくべき。
モデル構築
これから実際に機械学習を行うコードを作成する。
chainerでモデルを構築する方法はいくつかあるが、今回は最もポピュラーな方法で記述していく。
class MyChain(chainer.Chain):
def __init__(self,):
super(MyChain, self).__init__(
l1 = L.Linear(4, 64),
l2 = L.Linear(64, 32),
l3 = L.Linear(32,16),
l4 = L.Linear(16, 8),
l5 = L.Linear(8, 2),
)
def __call__(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
h3 = F.relu(self.l3(h2))
h4 = F.relu(self.l4(h3))
h5 = F.sigmoid(self.l5(h4))
return h3
それぞれl1~l5
が実際の機械学習の重みを格納する変数であり、h1〜h5
が学習の際に使用する活性化関数に当たる。
データセットの用意
データはIris.csvを使用する。ここからダウンロード
一度開いて
"setosa" -> 0
"versicolor" -> 1
"virsinica" -> 2
のように書き換える。トレーニングを行う際には数字にしてあげないと学習されない
このCSVをコードと同じディレクトリに配置する。コードには以下を記述
import pandas as pd
df = pd.read_csv("./iris.csv")
x = df[["sepal.length", "sepal.width", "petal.length", "petal.width"]].values
x = np.array(x, "float32")
t = df["variety"].values
変数x
には学習対象となるあやめの額弁の幅、長さといったデータが入っている。この時データを全てfloat32
に変換しておくこと、
これをやらないとあとでエラーになるので注意。
#オプティマイザーの準備
何も考えずにAdamを使う
my_nn = MyChain()
optimizer = chainer.optimizers.Adam()
optimizer.setup(my_nn)
学習
早速回していく、バッチサイズだとか細かいことは気にしない
epochはとりあえず1000に設定する
for _ in range(1000):
my_nn.zerograds()
y = my_nn(x)
loss = F.softmax_cross_entropy(y, t)
acc = F.accuracy(y, t)
loss.backward()
optimizer.update()
print("epoch:{} ==> acc:{} loss:{}".format(_, acc.data, loss.data))
多分ここまでやれば実行はできるので、いざ実行
> python3 iris_train.py
epoch:0 ==> acc:0.0 loss:3.036327362060547
epoch:1 ==> acc:0.1133333370089531 loss:2.8747689723968506
epoch:2 ==> acc:0.3266666531562805 loss:2.7357027530670166
epoch:3 ==> acc:0.3333333432674408 loss:2.6169583797454834
epoch:4 ==> acc:0.3333333432674408 loss:2.5149309635162354
epoch:5 ==> acc:0.3333333432674408 loss:2.4245212078094482
...
epoch:996 ==> acc:0.9800000190734863 loss:0.04298550263047218
epoch:997 ==> acc:0.9800000190734863 loss:0.04296574369072914
epoch:998 ==> acc:0.9800000190734863 loss:0.04291696473956108
epoch:999 ==> acc:0.9800000190734863 loss:0.04287692531943321
ガバガバ精度なのは気にしない
学習に満足したら保存する
コードに以下を追加
chainer.serializers.save_npz("model_Iris.npz", my_nn)
保存したファイルを使いたいときは以下のようにしてロードしてデータを入れるだけ
import chainer
import numpy as np
from Iris_train import MyChain
test_nn = MyChain()
chainer.serializers.load_npz("model_Iris.npz", test_nn)
import pandas as pd
df = pd.read_csv("./iris.csv")
x = df[["sepal.length", "sepal.width", "petal.length", "petal.width"]].values
x = np.array(x, "float32")
t = df["variety"].values
test = test_nn(x)
label = ["setosa", "versicolor", "verginica"]
i = 0
for _ in test:
pred_index = np.argmax(_.data)
real_index = t[i]
print("予測:%s 実ラベル:%s" % (label[pred_index], label[real_index]))
i += 1