本当に、JAVAの速さに驚いた動揺は未だに冷めない。784X300X150X10のネットワークをサクサクと学習する。ウェイトが、784X300+300X150+150*10=281700個ある。この順方向の計算と誤差逆伝搬によるウェイトの修正を一つのデータに関して行うのにかかる時間は1.67ミリ秒なのである。つまり、60000個のデータを約100秒で修正し終えるので、1サイクル28万個のウェイトを使った一個のデータの計算と修正には、0.00167秒、つまり、1.67ミリ秒しかかからないのである。
本来、JAVAに乗り換えたのは、スレッドの並列計算を導入しやすくする目的だったが、今の所、必要ないので1スレッドで動かしている。いずれ、使用スレッドを指定できるようにするつもりだ。
それはそうと、書いておきたかったのは、JAVAにして改めて、C++の違いに「えっ!」と気づいたことがあったからだ。C++とJAVAは、とてもよく似ていて、書き換えはスムーズにできる。今回、やってみて、クラスを配列に入れた時の振る舞いが違う。
例えば、仮にNeuronというクラスを作成して、この複数のインスタンス(オブジェクトというべきか)を配列neuronsに入れるとしよう。
C++の場合は、vectorを使って、インスタンス neuronを
vector<Neuron> neurons;
neuron.push_back(neuron);
としてvector配列に入れる。
この配列から、
Neuron neuron = neurons.at(1);
という感じで取り出して、このneuronの何かのメンバー変数の値を変更したら、
neuron.at(1) = neuron;
として戻してやらなければ、配列の中に保持されているインスタンスのメンバー変数の値は変わらない。
しかし、JAVAはクラス配列のインスタンスを取り出して、その値を変更すると、元の配列の中のインスタンスそのものの値も変更されているのだ。
だから、埋め戻しが不要だ。
C++愛好家とJAVA愛好家との間では、参照渡しなのか値渡しなのかがよく議論になるが、それと同じようなことだ。もちろん、JAVAのような仕様の方が助かる。なんだから、時間ロスも少ないような気がする。