機械学習

ニューラルネットワーク内の単一ニューロンを実装してみた

ニューラルネットワークは、人間の脳の神経細胞(ニューロン)の仕組みをプログラム上で模したモデルで、機械学習の1手法であるディープラーニングで利用する。

今回は、ニューラルネットワーク内の単一ニューロンを実装してみたので、そのサンプルプログラムを共有する。

(単一ニューロンを組み合わせた)ニューラルネットワークの全体構成は、以下のようになる。
ニューラルネットワーク

なお、活性化関数については、以下のサイトを参照のこと。
https://cvml-expertguide.net/terms/dl/layers/activation-function/

このうち、単一ニューロンのみを抜粋した結果は以下の通り。
単一ニューロン

上図における\(u\)は、(入力値)×(重み)の総和で計算する場合、\(u=w_{10}^1x_0 + w_{11}^1x_1 + w_{12}^1x_2\)(ただし、\(x_2=1\)とする)で計算される。

また、活性化関数にシグモイド関数を利用する場合、\(y = \displaystyle \frac{1}{1 + e^{-u}} \)で計算される。



「MiniTool Partition Wizard」はパーティション分割・統合・バックアップ・チェックを直感的に行える便利ツールだったハードディスクの記憶領域を論理的に分割し、分割された個々の領域のことを、パーティションといいます。 例えば、以下の図の場合、C/D...

単一ニューロンを実装した内容は以下の通りで、set_input_dataメソッドで入力値を設定し、先ほどの\(u\), \(y\)の計算を、フォワードプロパゲーション(順伝播処理)を行うforwardメソッド内で実行している。

import numpy as np

# 単一ニューロン
class OrigNeuron:
    
    # 変数の初期化
    def __init__(self):
        # 入力データ(変数x)
        self.x = np.array([])
        # 入力データ(重みw)
        self.w = np.array([])
        # 出力データ(シグモイド関数の変換前)
        self.u = 0
        # 出力データ
        self.y = 0
    
    # 入力データ(変数x、重みw:いずれもNumpy配列)の設定
    def set_input_data(self, x, w):
        if self.__input_check(x, 2) and self.__input_check(w, 3):
            self.x = x
            self.w = w           
        else:
            print("OrigNeuron set_input_data : 引数の指定方法が誤っています")
    
    # フォワードプロパゲーションで出力変数を設定
    def forward(self):
        if self.__input_check(self.x, 2) and self.__input_check(self.w, 3):
            self.u = self.x[0] * self.w[0] + self.x[1] * self.w[1] + self.w[2]
            self.y = self.__sigmoid(self.u)
    
    # 出力データyを返却
    def get_y(self):
        return self.y
    
    # 入力データの型・長さをチェック
    def __input_check(self, data, size):
        if isinstance(data, np.ndarray) and len(data) == size: 
            if np.issubdtype(data.dtype, float) or np.issubdtype(data.dtype, int):
                return True
            return False
        return False
    
    # シグモイド関数による変換
    def __sigmoid(self, data):
        return 1.0 / (1.0 + np.exp(-data))

また、先ほどの単一ニューロンを呼び出すニューラルネットワークを実装した内容は、以下の通り。なお、__init__メソッドの重み\(w\)は、何らかの任意値を設定している。

import numpy as np

# ニューラルネットワーク
class OrigNeuralNetwork:
    
    # 変数の初期化(変数x、重みw:いずれもNumpy配列)の設定
    def __init__(self, x):
        if self.__input_check(x, 2):
            self.x = x
            self.w = np.array([6.2, 6.2, -2.7])
        else:
            self.x = np.array([])
            self.w = np.array([])
            print("OrigNeuralNetwork set_input_data : 引数の指定方法が誤っています")

    # フォワードプロパゲーションで出力変数を設定後
    def forward(self):
        if self.__input_check(self.x, 2):
            self.on = OrigNeuron()
            self.on.set_input_data(self.x, self.w)
            self.on.forward()
    
    # 出力データを返却
    def get_y(self):
        return self.on.get_y()
    
    # 入力データの型・長さをチェック
    def __input_check(self, data, size):
        if isinstance(data, np.ndarray) and len(data) == size: 
            if np.issubdtype(data.dtype, float) or np.issubdtype(data.dtype, int):
                return True
            return False
        return False



「Envader」はLinuxコマンドやDatabase SQL等のスキルを、環境構築不要で習得できる学習サイトだった「Envader」は、ITエンジニアとしてよく使うLinuxコマンドやDatabase SQL等のスキルを、解説を読んだ上で、問題を解き...

さらに、先ほどのニューラルネットワークを呼び出した結果は、以下の通り。

import numpy as np

# 作成した入力データのフォワードプロパゲーションを実行
input_data = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
for data in input_data:
    onn = OrigNeuralNetwork(data)
    print("*** 入力データ ***")
    print(data)
    print("*** 出力結果 ***")
    onn.forward()
    print(onn.get_y())
    print()
ニューラルネットワークの呼び出し

実際に計算した結果は以下の通りで、先ほどの結果と一致していることが確認できる。

import numpy as np

# 入力データ
input_data = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
# 重み
w = np.array([6.2, 6.2, -2.7])

for data in input_data:
    print("*** 入力データ ***")
    print(data)    
    print("*** 出力結果 ***")
    u = data[0] * w[0] + data[1] * w[1] + 1 * w[2]
    y = 1.0 / (1.0 + np.exp(-u))
    print(y)
    print()
計算結果の確認

要点まとめ

  • ニューラルネットワークは、人間の脳の神経細胞(ニューロン)の仕組みをプログラム上で模したモデルで、機械学習の1手法であるディープラーニングで利用する。
  • 単一ニューロン内で、(入力値)×(重み)の総和で計算後、活性化関数で変換した出力値を返却する。