ニューラルネットワーク-スタート


機械学習や認知科学の分野では、人工神経ネットワーク(artificial neural network、略称ANN)、略称神経ネットワーク(neural network、略称NN)や類神経ネットワークといった、生物神経ネットワーク(動物の中枢神経系、特に脳)の構造や機能を模した数学モデルや計算モデルである.関数の実行に使用する .ニューラルネットワークは大量の人工ニューロン結合によって計算される.
総括する
多くの場合、人工ニューラルネットワークは外部情報に基づいて内部構造を変えることができ、適応システムである.現代ニューラルネットワークは非線形統計データモデリングツールである.典型的なニューラルネットワークは以下の3つの部分を有する:1. (Architecture)構造は、ネットワーク内の変数とそれらのトポロジー関係を指定する.例えば、ニューラルネットワークにおける変数は、ニューロン接続の重み(weights)およびニューロンの活性化値(activities of the neurons)であってもよい.2. (Activity Rule)ほとんどのニューラルネットワークモデルは、ニューロンが他のニューロンの活動に基づいて自分の励起値をどのように変化させるかを定義する短い時間スケールの動力学規則を有する.一般的な励起関数は、ネットワーク内の重み(すなわち、ネットワークのパラメータ)に依存する.3. (Learning Rule)学習ルールは、ネットワーク内の重みが時間とともにどのように調整されるかを指定します.これは一般に長時間スケールの動力学規則と見なされる.一般に,学習規則はニューロンの励起値に依存する.また、監督者が提供する目標値と現在の重みの値にも依存する可能性があります.
しょしきニューラルネットワーク
前述したように,ニューラルネットワークは主に3つの部分を含む: 、 、 .下図は3層のニューラルネットワークで、入力層はdノード、隠層はqノード、出力層はlノードである.入力レイヤを除いて、各レイヤのノードには非線形変換が含まれます.
では、なぜ非線形変換を行うのでしょうか.
(1)線形変換のみを行うと,多層のニューラルネットワークであっても,依然として1層の効果しかない.0.6∗(0.2)に類似×1+0.3×2)=0.12×1+0.18×2 . (2)非線形変化を行い,ニューラルネットワークを任意の関数にフィットさせることができ,以下は4層ネットワークの図である.
各ニューロンの動作方法を数学式を用いて説明する
(1)入力x(2)計算z=w*x(3)出力new_x = f(z)、ここでのfは1つの関数であり、sigmoidtanhrelu・などであり、fは前述のアクティブ化関数である.
逆伝搬(bp)アルゴリズム
上の その後、このネットワークはどうなっている ( )のでしょうか?まず本稿で使用する sigmoidアクティブ化関数
f(x)=11+e−x
def sigmoid(z):
    return 1.0/(1.0+np.exp(-z))
sigmoid 非常に重要な性質がある:
f(x)′=f(x)(1−f(x))
すなわち,導関数の計算が非常に便利である.
def sigmoid_prime(z):
    return sigmoid(z)*(1-sigmoid(z))

もくてきかんすう
Ek=12∑j=1l(yj1k−yj2k)2
数式の
12は導関数の計算が便利であるためである.
そして、このネットワークはどのように動作していますか.
(1)データは入力層から出力層まで様々な非線形変換の過程である .
def feedforward(self, a):
    for b, w in zip(self.biases, self.weights):
        a = sigmoid(np.dot(w, a)+b)
    return a

ここで、初期の重み(w)とバイアス(b)はランダムに付与される
biases = [np.random.randn(y, 1) for y in sizes[1:]]
weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]

(2)パラメータ更新,すなわち 反射伝播プロセス:
逆伝播アルゴリズム(Backpropagation)は、現在、人工ニューラルネットワーク(Artificial Neural Network,ANN)を訓練するために用いられている最も一般的で最も有効なアルゴリズムである.主な考えは次のとおりです.
(1)訓練セットデータをANNの入力層に入力し、隠蔽層を経て、最後に出力層に達し、結果を出力する.これはANNの順方向伝播過程である.
(2)ANNの出力結果と実際の結果とに誤差があるため、推定値と実際の値との誤差を算出し、この誤差を出力層から非表示層に逆伝搬して入力層に伝播する.
(3)逆伝播の過程において、誤差に応じて各種パラメータの値を調整する.収束するまで、上記の手順を繰り返します.
具体的な導出過程は、パラメータ参照2
  • 入力訓練セット
  • トレーニングセットの各サンプルxについて、入力層(Input layer)に対応する活性化値alを設定する:順方向伝播:
    zl=wlal−1+bl,al=σ(zl)
    内σ
  • 算出出力層で発生したエラー:
  • δL=∇αC⊙σ′(zl)
    ここでLはニューラルネットワークの最大層数、Cは対価関数、⊙はHadamard積を表し、行列またはベクトル間の点対点の乗算に用いられる. 計算に用いられるANN出力値と実値との誤差.よく使われる対価関数は二次対価関数(Quadratic cost function):
    C=12∑x||y(x)−αL(x)||2
    ここで、
    xは入力されたサンプルを表し、
    yは実際の分類を表し、
    αLは予測の出力を表し、
    Lはニューラルネットワークの最大層数を表す
  • 逆伝播エラー:
  • δl=((wl+1)Tδl+1)⊙σ′(zl)
  • 使用勾配降下(gradient descent)、訓練パラメータ:
  • wl=wl−ηm∑xδx,l(αx,l−1)T
    bl=bl−ηm∑xδx,l
    pythonの例
    # -*- coding: utf-8 -*-
    
    import random
    import numpy as np
    
    class Network(object):
    
        def __init__(self, sizes):
        """  sizes           , [2,3,1],      2    ,    3    ,    1    ."""
            self.num_layers = len(sizes)
            self.sizes = sizes
            self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
            self.weights = [np.random.randn(y, x)
                            for x, y in zip(sizes[:-1], sizes[1:])]
    
        def feedforward(self, a):
            """    """
            for b, w in zip(self.biases, self.weights):
                a = sigmoid(np.dot(w, a)+b)
            return a
    
        def SGD(self, training_data, epochs, mini_batch_size, eta,
                test_data=None):
            """      """
            if test_data: 
                n_test = len(test_data)
            n = len(training_data)
            for j in xrange(epochs):
                random.shuffle(training_data)
                mini_batches = [
                    training_data[k:k+mini_batch_size]
                    for k in xrange(0, n, mini_batch_size)]
                for mini_batch in mini_batches:
                    self.update_mini_batch(mini_batch, eta)
                if test_data:
                    print "Epoch {0}: {1} / {2}".format(j, self.evaluate(test_data), n_test)
                else:
                    print "Epoch {0} complete".format(j)
    
        def update_mini_batch(self, mini_batch, eta):
            """              .mini_batch     (x, y)   、eta     """
            nabla_b = [np.zeros(b.shape) for b in self.biases]
            nabla_w = [np.zeros(w.shape) for w in self.weights]
            for x, y in mini_batch:
                delta_nabla_b, delta_nabla_w = self.backprop(x, y)
                nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
                nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
            self.weights = [w-(eta/len(mini_batch))*nw
                            for w, nw in zip(self.weights, nabla_w)]
            self.biases = [b-(eta/len(mini_batch))*nb
                           for b, nb in zip(self.biases, nabla_b)]
    
        def backprop(self, x, y):
            """      (nabla_b, nabla_w)         ."""
            nabla_b = [np.zeros(b.shape) for b in self.biases]
            nabla_w = [np.zeros(w.shape) for w in self.weights]
            #     
            activation = x
            activations = [x] # list to store all the activations, layer by layer
            zs = [] # list to store all the z vectors, layer by layer
            for b, w in zip(self.biases, self.weights):
                z = np.dot(w, activation)+b
                zs.append(z)
                activation = sigmoid(z)
                activations.append(activation)
            # backward pass
            delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
            nabla_b[-1] = delta
            nabla_w[-1] = np.dot(delta, activations[-2].transpose())
            """l = 1          ,l = 2          ,     ."""
            for l in xrange(2, self.num_layers):
                z = zs[-l]
                sp = sigmoid_prime(z)
                delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
                nabla_b[-l] = delta
                nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
            return (nabla_b, nabla_w)
    
        def evaluate(self, test_data):
            """         """
            test_results = [(np.argmax(self.feedforward(x)), y) for (x, y) in test_data]
            return sum(int(x == y) for (x, y) in test_results)
    
        def cost_derivative(self, output_activations, y):
            return (output_activations-y)
    
    def sigmoid(z):
        return 1.0/(1.0+np.exp(-z))
    
    def sigmoid_prime(z):
        """sigmoid     """
        return sigmoid(z)*(1-sigmoid(z))

    単純な応用
    # -*- coding: utf-8 -*-
    
    from network import *
    
    def vectorized_result(j,nclass):
        """      one-hot"""
        e = np.zeros((nclass, 1))
        e[j] = 1.0
        return e
    
    def get_format_data(X,y,isTest):
        ndim = X.shape[1]
        nclass = len(np.unique(y))
        inputs = [np.reshape(x, (ndim, 1)) for x in X]
        if not isTest:
            results = [vectorized_result(y,nclass) for y in y]
        else:
            results = y
        data = zip(inputs, results)
        return data
    
    #      
    from sklearn.datasets import *
    np.random.seed(0)
    X, y = make_moons(200, noise=0.20)
    ndim = X.shape[1]
    nclass = len(np.unique(y))
    
    #    、   
    from sklearn.model_selection import train_test_split
    train_x,test_x,train_y,test_y = train_test_split(X,y,test_size=0.2,random_state=0)
    
    training_data = get_format_data(train_x,train_y,False)
    test_data = get_format_data(test_x,test_y,True)
    
    net = Network(sizes=[ndim,10,nclass])
    net.SGD(training_data=training_data,epochs=5,mini_batch_size=10,eta=0.1,test_data=test_data)

    参照
  • http://blog.csdn.net/a819825294/article/details/53393837
  • 逆伝播導出