7.5 CNNの実装

「ゼロから作るDeep Learning」 7章5節のCNNの実装を、Ivoryライブラリで再現します。

データセットを用意します。これまでと違い、画像を平坦化しません。

from ivory.datasets.mnist import load_dataset

data_train, data_test = load_dataset(flatten=False)
print(data_train)
print(data_train.shape)

[1] 2019-06-12 16:37:56 (1.92s) python3 (1.92s)

mnist_train(batch_size=1, epochs=1, len=60000, column=0, size=(60000,))
((1, 1, 28, 28), (1,))

「ゼロから作るDeep Learning」のSimpleConvNetを作成します。学習のために、Trainerインスタンスを用意します。

from ivory.core.trainer import sequential

net = [
    ("input", 1, 28, 28),
    ("convolution", 30, 5, 5, "relu"),
    ("pooling", 2, 2, "flatten"),
    ("affine", 100, "relu"),
    ("affine", 10, "softmax_cross_entropy"),
]
trainer = sequential(net, optimizer="adam", metrics=["accuracy"])

[2] 2019-06-12 16:37:58 (46.9ms) python3 (1.97s)

学習を行います。

data_train.epochs = 20
data_train.batch_size = 100
data_train.shuffle()
data_test.shuffle()

[3] 2019-06-12 16:37:58 (175ms) python3 (2.14s)

エポックごとの評価にスライス表記で取得したデータを使います。スライス表記にはバッチ数分を含むので、バッチサイズが100の訓練データに対しては、data_train[:10]で1000個分のデータが取得できます。

epoch_data = {"train": data_train[:10], "test": data_test[:1000]}
len(epoch_data["train"][0]), len(epoch_data["test"][0])

[4] 2019-06-12 16:37:58 (15.6ms) python3 (2.16s)

(1000, 1000)
trainer.init(std=0.01)
trainer = trainer.fit(data_train, epoch_data=epoch_data)
df = trainer.to_frame()
df.tail()

[5] 2019-06-12 16:37:58 (39min51s) python3 (39min53s)

epoch data accuracy
37 18 test 0.990
38 19 train 0.999
39 19 test 0.989
40 20 train 0.999
41 20 test 0.990
import altair as alt

def plot(df):
    y = alt.Y("accuracy", scale=alt.Scale(domain=[0, 1]))
    return (
        alt.Chart(df)
        .mark_line()
        .encode(x="epoch", y=y, color="data")
        .properties(width=200, height=160)
    )

plot(df)

[6] 2019-06-12 17:17:49 (46.9ms) python3 (39min53s)