LoginSignup
2
3

More than 5 years have passed since last update.

ChainerでIris分類

Posted at

自分用の備忘録として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

上記を使える状態にするためにインポートをする。
これで機械学習に必要なライブラリを使えるようになる。

Iris_train.py
import chainer
import chainer.links as L
import chainer.functions as F

ここにある... as ~というのは...をこれ以降~という呼び方をしても呼び出せるようにしている。
便利なので覚えておくべき。

モデル構築

これから実際に機械学習を行うコードを作成する。
chainerでモデルを構築する方法はいくつかあるが、今回は最もポピュラーな方法で記述していく。

Iris_train.py
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をコードと同じディレクトリに配置する。コードには以下を記述

Iris_train.py
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を使う

Iris_train.py
my_nn = MyChain()
optimizer = chainer.optimizers.Adam()
optimizer.setup(my_nn)

学習

早速回していく、バッチサイズだとか細かいことは気にしない
epochはとりあえず1000に設定する

Iris_train.py
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)

保存したファイルを使いたいときは以下のようにしてロードしてデータを入れるだけ

Iris_test.py
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
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3