Python でニューラルネットワークを実装してみましょう。何回かに分けて作っていきます。
第一弾の今回は、行列データを受け取って、0から9までの10種類のラベルを出力する、3層のモデルを作ります。行列パラメーターの更新機能は無く、手動で成分を設定してラベルを出力します。
Python の環境が無い人は、google colab を使えるようにしましょう。Pythonファイルに色々まとめて置くのが便利ですが、最悪一つのnotebook にまとめても良いです。
Google Colabolatory とニューラルネットワークの話はこちらの記事でどうぞ。


ニューラルネットワークのモデルの実装は、以下の本を参考にしています。管理人はこの本でpythonがなんとなく書けるようになりました。
記事で使っているソースコードはgithub に置いてあります。
https://github.com/msamunetogetoge
使用するデータ
使うデータは Fashion MNIST という画像データです。10種類の衣類が\( 28 \times 28 \)の行列で表現されています。以下のような感じのデータです。

実際のデータでは画像に対して、0~9の数字が割り振られています。単純に考えると、\(28 \times 28\)の数字から、0~9どのクラスに属しているのか当てる問題です。データを読み込むコードを以下に記します。
ただし、ちょっとした細工をしておきます。精度が上がるように画像は白黒に加工します。 また、画像データは\( 28 \times 28 \)の行列ですが、1つのデータが行列として与えられるのは、普段考える問題と違っています。いつも通りが一番なので、行列を1列のベクトルだと思いましょう。numpyのflatten 関数を使えばよいです。
1 2 3 4 5 6 7 8 9 10 11 |
import tensorflow as tf from tensorflow import keras fashion_mnist = keras.datasets.fashion_mnist (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data() train_images = train_images / 255.0 test_images = test_images / 255.0 train_images.flatten().reshape(-1,784) #28*28=784 test_images.flatten().reshape(-1,784) |
今回実装するニューラルネットワークモデルの部分
作ろうとしているモデルは、入力層1層、隠れ層1層、出力層1層のモデルです。隠れ層では、relu関数で活性化し、出力層ではsoftmax関数で10個の値を得て最も大きい値を出すクラスを予測値とします。
パラメーターの更新は単純な勾配法で行い、誤差関数は交差エントロピーを使用します。
今回は、データを受け取って予測ラベルを出力し、正解率を計算する関数を作ります。具体的には、以下の機能が必要です。
- 活性化関数(relu)の計算
- 出力関数(softmax)の計算
- 行列同士の積
- 正解率の計算
ニューラルネットワークモデルの予測部分の実装
以下のグラフが示すモデルで予測値を得られるように、コードを書きます。

最終的には一つのクラスにまとめたいので、初めにクラスを作っておいて機能を増やしていきましょう。ニューラルネットワークのクラスとは別に、活性化関数や出力関数を作っておく必要があります。今のところは、reluとsoftmaxがあれば良いので、以下のように定義しておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
def relu(x): return np.maximum(0, x) def softmax(x): if x.ndim == 2: x = x.T x = x - np.max(x, axis=0) y = np.exp(x) / np.sum(np.exp(x), axis=0) return y.T x = x - np.max(x) # オーバーフロー対策 return np.exp(x) / np.sum(np.exp(x)) |
今回の目玉である、行列の計算と活性化関数の計算、そして出力関数の定義をしましょう。行列の行や列に気を付ければ簡単です。クラスにまとめたいので、TwoLayerNet というクラスの中に、行列の生成や ニューラルネットワークでの予測、正答率の表示を組み込みました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.1): self.params = {} self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size) self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size) self.params['b2'] = np.zeros(output_size) def predict(self, x): W1, W2 = self.params['W1'], self.params['W2'] b1, b2 = self.params['b1'], self.params['b2'] a1 = np.dot(x, W1) + b1 z1 = relu(a1) a2 = np.dot(z1, W2) + b2 y = softmax(a2) return y def accuracy(self, x, t): y = self.predict(x) y = np.argmax(y, axis=1) accuracy = np.sum(y == t) / float(x.shape[0]) return accuracy |
この状態で、トレーニング画像からラベルを予測させてみましょう。全く訓練していないパラメーターなので、正答率は10%前後が妥当です。
1 2 3 4 5 6 7 |
network=TwoLayerNet(input_size=len(train_images[0]),hidden_size=64, output_size=10) np.argmax(network.predict(train_images[0])) #1番目の画像の予測 #管理人の環境での出力 1 network.accuracy(train_images , train_labels ) #トレーニング用画像全体の正答率の算出 #管理人の環境での出力 0.05976666666666667 |
正答率 5 %でした。パラメーターは適当なので正答率は何%でも良いのですが、無事にデータから予測値を得る関数を作ることが出来ました。次回からはpython上で作ったクラスに色々な関数を追加して、パラメーターの更新を自動で行ってくれるようにしていきます。
まとめ
・ Fashion MNIST という\(28 \times 28 \)の画像データがあり、10種類の分類問題に使える。
・計3層のニューラルネットワークモデルを作るために、クラスTwolayernet を作った。
・データに予測値を与える関数を作成した。
・pythonによるニューラルネットワークの実装➁はこちら
https://masamunetogetoge.com/make-neuralnetwork2