6.6 まとめ

前節でさらなる改善を施したRNNの訓練は、独立したスクリプトで行いました。結果を検証します。

import os

import altair as alt
import pandas as pd

import ivory

directory = os.path.dirname(ivory.__file__)
directory = os.path.join(directory, "../docs/script")
path = os.path.join(directory, "better_rnnlm_ppl.csv")
df = pd.read_csv(path)
df.tail()

[1] 2019-06-20 19:37:47 (31.3ms) python3 (3min56s)

epoch ppl_train ppl_val
35 36 50.199360 79.83910
36 37 51.056183 79.83858
37 38 50.622810 79.83877
38 39 50.439747 79.83861
39 40 49.942932 79.83858

プロットします。

alt.Chart(data=df).mark_line().encode(x="epoch", y="ppl_val").properties(
    width=200, height=160
)

[2] 2019-06-20 19:37:47 (52.5ms) python3 (3min56s)

テストデータでのパープレキシティを求めてみます。高速化のためにGPUを使います。

from ivory.common.context import np
np.context = 'gpu'

[3] 2019-06-20 19:37:47 (5.01ms) python3 (3min56s)

PTBデータセットを読み出します。

from ivory.common.dataset import TimeDataset
from ivory.utils.repository import import_module

ptb = import_module("scratch2/dataset/ptb")
corpus_test, _, _ = ptb.load_data("test")
x, t = corpus_test[:-1], corpus_test[1:]
data = TimeDataset((x, t), time_size=35, batch_size=20)
data

[4] 2019-06-20 19:37:47 (469ms) python3 (3min57s)

TimeDataset(time_size=35, batch_size=20, epochs=1, len=117, column=0, size=(82429,))

モデルを作成します。

from ivory.core.model import sequential

net = [
    ("input", 10000),
    ("embedding", 650),
    ("lstm", 650),
    ("lstm", 650),
    ("affine", 10000, "softmax_cross_entropy"),
]
model = sequential(net)

[5] 2019-06-20 19:37:47 (243ms) python3 (3min57s)

重みの共有をします。

em = model.layers[0]
affine = model.layers[-2]
affine.W.share_variable(em.W, transpose=True)
model.build()

[6] 2019-06-20 19:37:47 (15.5ms) python3 (3min57s)

<ivory.core.model.Model at 0x1383fb65518>

学習済みの重みを読み出します。

import pickle

with open(os.path.join(directory, 'better_rnnlm.pkl'), 'rb') as f:
    weights = pickle.load(f)

for v, weight in zip(model.weight_variables, weights):
    v.data = np.asarray(weight)

[7] 2019-06-20 19:37:47 (119ms) python3 (3min57s)

テストデータでのパープレキシティを求めます。

count = 0
total_loss = 0.0
for x, t in data:
    model.set_data(x, t)
    model.forward()
    total_loss += model.loss
    count += 1
print(np.exp(total_loss / count))

[8] 2019-06-20 19:37:48 (6.70s) python3 (4min4s)

76.25039

「ゼロから作るDeep Learning ❷」と同等の結果が得られました。