Scheme で MNIST 続き
Scheme で MNIST からの学び - higepon blog の続き。
f64array
前回のプロトタイプをもとに Mosh のシステムライブラリとして f64array というものを導入した。double 型の2次元の行列を表現したもの。追加した手続きは最低限のもの。
- make-f64array
- f64array-ref
- f64array-set!
- f64array-shape
- f64array-dot-product)
f64array の構築、setter/getter、dot product 。プロファイラで見てみると行列の shape を返す手続きも無視できない回数呼ばれている。おそらく行列同士の計算での broadcast で呼ばれているのだろう。
Portable なコードを書く
R7RS では処理系ごとの違いをうまく扱える仕組みが用意されているので Gauche と Mosh 両方で動くように整えてみよう。 行列の初期化で make-normal-generator を使うのだが Gauche には SRFI-194 がないようなので data.random ライブラリから似たような手続きを持ってきて rename している。ところで SRFI-194 の author は Shiro さんなのであった。
(cond-expand [gauche (import (rename (data random) (reals-normal$ make-normal-generator)))] [(library (srfi 194)) (import (only (srfi 194) make-normal-generator))])
また Mosh では .mosh.sld という拡張子のライブラリを優先して読み込むという機能があるので以下のように Mosh が読み込むライブラリ、Mosh 以外が読み込むライブラリを分けることができる。ここで行列の実装を分岐している。
そしてどちらの行列ライブラリにも共通なコードは (include "matrix-common.scm")
のように直接ファイルを include する。
というわけでめでたく Mosh と Gauche の両方で動く MNIST デモができました。他のR7RS 処理系でも少しの手直しで動くのではないかと期待している。PR 待ってます。コードは mosh/tests/mnist at master · higepon/mosh · GitHub。