読者です 読者をやめる 読者になる 読者になる

chainerでbatchの部分を今までミスっていた ~~入門~~

chainer 機械学習

 たまたま僕が参考にしたサイトがバッチの取り扱いを間違えていたのですが、特に気にせずそのまま使いまわしていて、ふと読み直してみたらなんじゃこりゃとなった話です。
 今までchainerの記事をいくつかあげましたが、その中でのバッチ学習は大体以下のようなコードでした。

for i in range(n_batch):
    x = Variable(train_x[sffindx[i:(i+n_batch) if (i+n_batch) < train_size else train_size]])
    y = Variable(train_y[sffindx[i:(i+n_batch) if (i+n_batch) < train_size else train_size]])
    model.zerograds()
    loss = model(x, y)
    loss.backward()
    optimizer.update()

 ここだけ抽出してみればなんじゃこりゃという感じなのですが、恐ろしいことに全く気付いていませんでした。バッチ学習をしているので、train_sizeをbatch_sizeごとに切り分けて学習するべきなのですが、このコードではiが0,1,...,n_batch-1とインクリメントされていて、それぞれについてニューラルネットに突っ込まれるのが[i,i+n_batch)という意味不明なことになっています*1。iは当然batch_size分ずつ増えるべきなので、

for i in range(0,train_size,n_batch):
    x = Variable(train_x[sffindx[i:(i+n_batch) if (i+n_batch) < train_size else train_size]])
    y = Variable(train_y[sffindx[i:(i+n_batch) if (i+n_batch) < train_size else train_size]])
    model.zerograds()
    loss = model(x, y)
    loss.backward()
    optimizer.update()

のようにするべきです。
 過去の記事で既に上のコードを掲載してしまっていて、あーあという気持ちです。

*1:シャッフルされるので少し違いますが意味的には同じことです