記事"パーセプトロンニューラルネットワーク"についてのディスカッション - ページ 3

 
Maxim Dmitrievsky:


"5つの理由 "とは何か、4つのレイヤーはそれと何の関係があるのか?調べてみると、単純な決定木がこの質問に答えてくれる。ユニバーサル近似器は2層のNSであり、いくつの "なぜ "にも答えることができる。)他の層は、主に複雑な設計におけるデータの前処理に使われます。例えば、多数のピクセルから画像を圧縮し、それを認識する。


「5つの理由」は、ウィキペディアの 因果関係を決定するためのテクニックである。この記事では、基本的にニューラルネットワークが、過去の値動きと将来の値動きの方向性との因果関係を見つけるためにどのように設計されているかを例示している。

 
Andrey Azatskiy:
入力信号だけがこの区間になければならない。入力信号とは、議論中の関数ではなく、ニューロンへの入力信号のことである。

理論的には、ニューロンへの入力信号はどのようなものでもよい。その影響は重み付け係数によって補正される。入力信号が小さすぎるが、全体の解に大きな影響を与える場合、その重み係数は学習過程で増加する。その信号の重要度は高いが、結果への影響が無視できるほど小さい場合、その重み係数は "0 "まで下げられる(ニューロン間の通信が途絶える)。

 
Dmitriy Gizlyk:

"5つの理由 "とは、ウィキペディアの 因果関係を判断するためのテクニックである。過去の値動きと将来の値動きの方向性の間に因果関係を見つけるために設計されたニューラルネットワークの本質的なものとして、記事の例が示されている。

ただ、質問数と層の相関関係がよくわからなかった。入力はいくつかの属性で、それぞれ(大雑把に言えば)答えなければならない。出力は要約された結果である。隠れ層は1層で十分で、4層である必要はない。隠れ層が2層のNSであれば、どんな関数でも近似できると考えられている。これは参考までに。

 

そして話題を発展させるために、NSのアーキテクチャーについて質問したい。それは何に依存しているのか?

 
Maxim Dmitrievsky:

ただ、質問数とレイヤーの相関関係が理解できませんでした。入力はいくつかの属性で、それぞれが(大まかに言えば)答えなければならない。出力は要約結果です。隠れ層は1層で十分で、4層である必要はない。隠れ層が2層のNSであれば、どんな関数でも近似できると考えられている。これは参考までに。

5 Whyテクニックは、連続した質問に基づいており、各質問は前の質問の理由に答える。例えば、チャートと上昇価格チャートを見て、質問を組み立てます(質問はテクニックを説明するために抽象的に答えています):
1.どこで取引するか - 買う
2.なぜ買うのか?- 上昇トレンドだから
3.なぜ上昇トレンドなのか?- MA50が上昇しているから
4.なぜMA50は上昇しているのか?- 50本のローソク足の終値の 平均が、直近50本のローソク足の終値の平均より低いから。

など
質問は連続的で因果関係があるため、この関係を観察するためにレイヤーを作成します。レイヤーを2つしか使用しないと、因果関係は失われ、ニューラルネットは独立した多くのオプションを分析し、最良のものを選択します。

 
Denis Kirichenko:

そして話題を発展させるために、NSのアーキテクチャーについて質問したい。それは何に依存しているのか?

アーキテクトのプロセスに対する理解による。この記事では、ニューラルネットワークの 最も単純なバージョンを示し、畳み込みや他のアーキテクチャについては考慮していない。

 
Dmitriy Gizlyk:

5 Whyテクニックは、各質問が前の質問の理由に答えるという連続した質問で構成されています。例えば、チャートと上昇価格チャートを見て、質問を組み立てていきます(質問はテクニックを説明するために抽象的に答えています):
1.どこで取引するか - 買う
2.なぜ買うのか?- 上昇トレンドだから
3.なぜ上昇トレンドなのか?- MA50が上昇しているから
4.なぜMA50は上昇しているのか?- 1のシフトを持つ50本のローソク足の平均終値は、最後の50本のローソク足の平均終値よりも低い。

など
質問は連続的で因果関係があるため、この関係に従うようにレイヤーを作成します。レイヤーを2つしか使用しないと、因果関係が失われ、ニューラルネットは独立した多くのオプションを分析し、最良のものを選択します。

どの順番で質問しても、結果は同じである。層で分ける必要はない。

 
Dmitriy Gizlyk:


中のニューロンは2つの機能で構成されている。
1.まず、加重係数を考慮して、すべての入力信号の合計を計算する。つまり、ニューロンの各入力における値を取り、それに対応する重み付け係数を掛ける。そして得られた積の値を合計する。


こうして、活性化関数の入力に供給されるある値が得られる。

2.活性化関数は、受け取った和を正規化された出力信号に変換する。これは単純な論理関数でも、さまざまなシグモイド関数でもよい。後者の方が、状態遷移が滑らかであるため、一般的である。

ニューロン間のコミュニケーションは、あるニューロンの出力値を後続のニューロンの入力に直接転送することで構成される。この場合、ポイント1を参照すると、ニューロンの入力に到着する値は、その重み係数に従って考慮される。

ありがとう。この記事と参考文献のおかげで、ニューラルネットワークの目的である、データセットの変動空間内で不変量を見つけ処理するということの本質と、技術的な実装の最も単純な方法を理解することができましたが、まだ決定的な理解はできていません。しかし、説明は非常に明快である。
 
Maxim Dmitrievsky:

これらの質問をする順番に違いはなく、結果は同じである。ここでは重ねる必要はない。

質問は条件付きで与えられる。この技法は、ある出来事の根本原因を見つけるために使われる。最初の質問と最後の質問の関連性は、必ずしもすぐにはわからない。
しかし、この記事のこの例は、根本原因分析のアプローチとネットワーク・アーキテクチャとの関連を示すために与えられている。
 
Реter Konow:
ありがとう。この記事と参考文献のおかげで、ニューラルネットワークの目的の本質、つまりデータセットに埋め込まれた不変量の定義と処理、そして技術的な実装の最も単純な方法を理解することができました。しかし、説明は非常にわかりやすい。

MLPの構造を理解したければ、このコードを見た方がいい:

#danila_zaytcev mlp 2018


import random

import math



class mlp:


    class activefunc:

        def __init__(self, func, derive):

            self.func = func

            self.derive = derive


    def __init__(self, structure,  af,  learnRate,  moment,  epohs):

        self.leanRate = learnRate

        self.af = af

        self.moment = moment

        self.epohs = epohs


        self.layerCount = len(structure) - 1

        self.weightCount = [None] * self.layerCount

        self.neuronsCount = [None] * self.layerCount

        self.Out = [None] * self.layerCount

        self.Err = [None] * self.layerCount

        self.Drv = [None] * self.layerCount

        self.Inputs = [None] * self.layerCount

        self.Weigthts = [None] * self.layerCount


        for l in range(self.layerCount):

            nLen = structure[l + 1]

            wLen = structure[l] + 1

            self.weightCount[l] = wLen

            self.neuronsCount[l] = nLen


            self.Out[l] = [0.0] * nLen

            self.Err[l] = [0.0] * nLen

            self.Drv[l] = [0.0] * nLen

            self.Weigthts[l] = [None] * nLen


            for n in range(nLen):

                self.Weigthts[l][n] = [None] * wLen

                for w in range(wLen):

                    self.Weigthts[l][n][w] = (random.random() * 2 - 1) / wLen



    def forward(self,  input):

        for l in range(self.layerCount):

            self.Inputs[l] = input

            for n in range(self.neuronsCount[l]):

                wcount = self.weightCount[l] - 1

                out = 0.0

                for w in range(wcount):

                    out += self.Weigthts[l][n][w] * input[w]


                out += self.Weigthts[l][n][wcount]

                out = self.af.func(out)

                self.Out[l][n] = out

                self.Drv[l][n] = self.af.derive(out)


            input = self.Out[l];



    def backward(self, output):

        last = self.layerCount - 1

        for n in range( self.neuronsCount[last]):

            self.Err[last][n] *= self.moment

            self.Err[last][n] += (output[n] - self.Out[last][n])*self.Drv[last][n] * (1.0 - self.moment)


        for l in range(last - 1, -1,-1):

            for n in range( self.neuronsCount[l]):

                backProp = 0

                for w in range(self.neuronsCount[l + 1]):

                    backProp += self.Weigthts[l + 1][w][n] * self.Err[l + 1][w]


                self.Err[l][n] = backProp * self.Drv[l][n]



    def update(self):

        for l in range(self.layerCount):

            for n in  range(self.neuronsCount[l]):

                G = self.Err[l][n] * self.leanRate

                for w in  range(self.weightCount[l] - 1):

                    self.Weigthts[l][n][w] += self.Inputs[l][w] * G

                self.Weigthts[l][n][self.weightCount[l] - 1] += G



    def learn(self, inputs, outputs):

        for e in  range(self.epohs):

            for i in range(len(inputs)):

                index = random.randint(0, len(inputs) - 1)

                self.forward(inputs[index])

                self.backward(outputs[index])

                self.update()



    def compute(self, vector):

        self.forward(vector)

        return self.Out[self.layerCount - 1]



def test_mlp():


    inputs = [[1.0,1.0],[-1.0,-1.0],[1.0,-1.0],[-1.0,1.0]]

    outputs = [[1.0],[1.0],[-1.0],[-1.0]]


    af = mlp.activefunc(math.tanh, lambda y: 1.0 - y ** 2)

    ml = mlp([2,2,1],af,0.01,0.1,10000)

    ml.learn(inputs,outputs)


    for i in inputs:

        print(str(i) + " = " + str(ml.compute(i)))

5倍小さく、必要なことが保証されており、理解しやすいPythonで書かれている。

しかし、この記事の著者はもちろん良い人ですが、自分でMLPを書くのもかっこいいですよ :)