前回までで、「機械学習と深層学習」をやり切ったのだが、これを使っていろんなことをやってみたい。
- 作者: 小高知宏
- 出版社/メーカー: オーム社
- 発売日: 2016/05/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (4件) を見る
せっかくニューラルネットワークのC/C++での記述について勉強したので、これでいろんなアプリケーションを作ってみたい。まずは、Cの実装を使ってMNISTを作ってみるための検討をしてみよう。
ベースにするニューラルネット
ニューラルネットのベースにするのは、比較対象として明確な「ゼロから作るディープラーニング」のMNISTネットワークとしたい。
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
- 作者: 斎藤康毅
- 出版社/メーカー: オライリージャパン
- 発売日: 2016/09/24
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (16件) を見る
ここの第5章:「誤差逆伝搬法」の章では、MNISTのための2層ニューラルネットワークを作っている。まずForward方向には、以下のようなネットワークを構成していた。
Affineレイヤ1、ReLUレイヤ1、Affineレイヤ2、そして出力層としてSoftmaxを使っている。
# レイヤの生成 self.layers = OrderedDict() self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1']) self.layers['Relu1'] = Relu() self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2']) self.lastLayer = SoftmaxWithLoss()
それぞれをC言語で実装することを考えてみよう。
Affineレイヤでは、行列WとベクトルXの積、さらにその結果に対してバイアスを掛けることになる。
double affine (double *o, double *e, double **wh, double *b, int output_size, int input_size) { for (int i = 0; i < output_size; i++) { o[i] = 0; for (int j = 0; j < input_size; j++) { o[i] += e[j] * wh[i][j]; } o[i] += b[i]; } }
次に、ReLU活性化関数は0以下ならば0、そうでなければ入力値となるので、
double relu (double *o, double *e, int input_size) { for (int i = 0; i < input_size; i++) { o[i] = e[i] > 0.0 ? e[i] : 0.0; } }
Softmaxはさらに複雑だ。まだテストしていないので合っているのかいるのか分からないが…
double softmax (double *o, double *e, int input_size) { double max = e[0]; for (int i = 1; i < input_size; i++) { max = max < e[i] ? e[i] : max; } double exp_sum = 0.0; double *exp_a = (double *)malloc(sizeof(double) * input_size); for (int i = 0; i < input_size; i++) { exp_a[i] = exp (e[i] - max); exp_sum += exp_a[i]; } for (int i = 0; i < input_size; i++) { o[i] = exp_a[i] / exp_sum; } } ````