[PYTHON] Richtlinien für das Design der Ausgangsschicht neuronaler Netze

Überblick

In den letzten Jahren war die Entwicklung von Technologien für neuronale Netze, die durch Deep Learning repräsentiert werden, bemerkenswert. Bisher können neuronale Netze, die aufgrund von Überlernen keine ausreichende Genauigkeit hatten, mithilfe von Methoden wie Drop Learning und Auto Encoder von Hinton et al. Eine hohe institutionelle Lernfähigkeit erwerben, ohne die Generalisierungsfähigkeit zu beeinträchtigen. .. Darüber hinaus haben die jüngsten Entwicklungen bei GPGPU und die Entwicklung von Bibliotheken wie Tensorflow das Erlernen großer neuronaler Netze relativ einfach gemacht. Während andererseits den Lernmethoden neuronaler Netze großes Interesse geschenkt wird, wird nicht viel über die hierarchische Struktur dieser neuronalen Netze selbst und die Anzahl der Perzeptrone diskutiert. In den letzten Jahren wurde die Existenz angewandter neuronaler Netze wie LSTM und CNN festgestellt, aber die Konstruktionsrichtlinien zur tatsächlichen Verbesserung ihrer Genauigkeit haben sich in der Vergangenheit nicht geändert, um handwerkliches Können zu erfordern. In diesem Kapitel diskutieren wir das Design der Ausgabeschicht des modellierten neuronalen Netzwerks mit dem Z3 Solver. Anschließend zeigen wir mit Z3 Prover die Methode und das Programm, mit denen Sie ein neuronales Netzwerk mit der angegebenen Genauigkeit aufbauen können.

Einführung eines modellierten neuronalen Netzwerks

Fehlerfreies Regressionsmodell

Führen Sie ein sehr einfaches neuronales Netzwerk ein. Hier werden wir ** Regressionsprobleme durch neuronale Netze ** diskutieren.

image

Wie in der Figur gezeigt, hat die Ausgabeschicht drei Perzeptrone, jede Ausgabe wird mit einem Gewichtungskoeffizienten multipliziert, und die Summe dieser und der Konstanten wird addiert, um die Ausgabe auszugeben. Es ist wie folgt, wenn es in einer mathematischen Formel geschrieben ist.

\begin{split}
u_i \in \{ 0 , 1 \}  \\
output = \sum_{i=1}^{3} u_i w_i + c
\end{split}

Diskussion über Perceptron Number

Hier wird angenommen, dass $ u_i $ ein sogenanntes Schritttyp-Perzeptron ist, das nur einen Wert von 0 oder 1 annimmt. Mit einem solchen neuronalen Netzwerk

( \vec{x_1} , y_1 ), ( \vec{x_2} , y_2 ), ( \vec{x_3} , y_3 ), ( \vec{x_4} , y_4 )

Lassen Sie uns darüber nachdenken, die vier Daten zurückzuziehen. Angenommen, Sie möchten $ \ vec {x_i} $ als Eingabe für das Perceptron verwenden und $ y_i $ ausgeben. Achten Sie zu diesem Zeitpunkt auf ** $ y_1, y_2, y_3, y_4 $ und ignorieren Sie $ \ vec {x_1}, \ vec {x_2}, \ vec {x_3}, \ vec {x_4} $. ** ** ** Erwägen Sie, unter den oben genannten Bedingungen eine Regression mit Perceptron durchzuführen. Die Ausgangsschicht des neuronalen Zielnetzwerks besteht aus drei Einheiten. Zu diesem Zeitpunkt gibt es höchstens acht mögliche Zustände für $ u_1, u_2, u_3 $. Wenn $ y_i \ neq y_j (i \ neq j) $ gilt, beträgt die maximale Anzahl, die ohne Fehler zurückgegeben werden kann, nur 8. darüber. Offensichtlich können wir Folgendes sehen.

Wenn die Ausgabeebene $ n $ Perzeptrone enthält, beträgt die maximale Anzahl von Datensätzen, die ohne Fehler zurückverfolgt werden können, nur $ 2 ^ n $.

darüber. Daraus können wir ersehen, dass der ** bemerkenswerte Parameter die Anzahl der Datensätze ** ist. Und von dort kann die Anzahl der Perceptrons in der Anzahl der Ausgänge abgeleitet werden. Unter der Annahme, dass die Anzahl der Datensätze $ m $ beträgt und die Anzahl der Perzeptrone mit der Anzahl der Ausgaben, die fehlerfrei zurückgegeben werden können, $ n $ ist.

n \geq \lceil \log_{2} m \rceil

Sie können den relationalen Ausdruck von sehen. Dadurch konnten wir die Untergrenze für $ n $ finden. Andererseits entspricht die Obergrenze der Zuweisung von 0 bzw. 1 zu $ m $ Daten.

m \geq n \geq \lceil \log_{2} m \rceil \tag{1}

Ich habe das gefunden.

Diskussion von Optimierungsproblemen im Zusammenhang mit Regression

Die Perceptron-Regression besteht aus zwei Problemen.

  1. Codezuweisung
  2. Optimierung des Regressionskoeffizienten

Ich werde es anhand des oben angegebenen Beispiels erklären. Hier führen wir die Variable $ s_ {i, k} $ ein.

\begin{split}
s_{i,j} \in {0,1} \\
y_k = \sum_{i=1}^{n} s_{i,k}w_i + c
\end{split}

Beim Abrufen der Daten $ y_k $ definieren wir die Ausgabe von $ u_i $ als $ s_ {i, k} $. Hier wird diese Formel der Einfachheit halber "Startbeschränkungsformel S" genannt. Wenn Sie alle vorherigen Beispiele aufschreiben,

\begin{split}
y_1 = s_{1,1}w_1 + s_{2,1}w_2 + s_{3,1}w_3 + c \\
y_2 = s_{1,2}w_1 + s_{2,2}w_2 + s_{3,2}w_3 + c \\
y_3 = s_{1,3}w_1 + s_{2,3}w_2 + s_{3,3}w_3 + c \\
y_4 = s_{1,4}w_1 + s_{2,4}w_2 + s_{3,4}w_3 + c 
\end{split}

Es wird. Wie bestimmen Sie nun den Inhalt von $ s_ {i, j} $, wenn Sie $ y_i $ zurückgeben? Ein Problem tritt auf. Dies ist das Problem der "Zeichenzuweisung", das ich zuvor angesprochen habe. Angenommen, $ s_ {1,1} = 0 $, $ s_ {2,1} = 1 $, $ s_ {3,1} = 1 $ werden $ y_1 $, $ w_1 zugewiesen Was sind die Werte von $, $ w_2 $, $ w_3 $, $ c $? Das Problem entsteht. Dies entspricht der zuvor erwähnten "Optimierung des Regressionskoeffizienten". Es ist sehr schwierig, sich einen Algorithmus vorzustellen, der diese gleichzeitig löst. Daher wird der SMT-Löser verwendet.

  1. Definieren Sie den Startbeschränkungsausdruck S. Es ist jedoch definiert als $ n = m $.
  2. Setzen Sie $ E_ {min} = \ lceil \ log_ {2} m \ rceil $.
  3. Setzen Sie $ E_ {max} = m $.
  4. Setzen Sie $ E_ {try} = {E_ {min} + E_ {max} \ über 2} $.
  5. Setzen Sie $ w_i = 0 (i> E_ {try}) $, um die ausreichende Einschränkung zu bestimmen.
  6. Wenn der logische Ausdruck erfüllt ist, $ E_ {max} = E_ {try} $. Wenn nicht, schließen Sie den Einschränkungsausdruck in 5. aus und setzen Sie $ E_ {min} = E_ {try} $.
  7. Wenn $ E_ {max} - E_ {min} = 1 $, fahren Sie mit 8 fort. Wenn nicht, fahren Sie mit 4 fort.
  8. Es stellt sich heraus, dass die Mindestanzahl von Einheiten, die $ y_i $ zurückgeben können, $ E_ {max} $ ist.

Eine sogenannte Dichotomie wird durchgeführt, um die minimale Anzahl von Einheiten $ n $ zu finden, die erforderlich sind, um die Daten $ y_i $ darzustellen. Zu diesem Zeitpunkt werden die Untergrenze und die Obergrenze unter Verwendung der zuvor verwendeten Gleichung (1) angegeben.

Regressionsmodell mit Fehler

In diesem Kapitel diskutieren wir ein Regressionsmodell mit Fehlern. Es ist äußerst selten, dass das oben erwähnte Regressionsmodell fehlerfrei dargestellt wird, und im Allgemeinen wird häufig ein fehlerhaltiges Modell verwendet. Hier ist der zulässige Entwurfsfehler als $ \ epsilon $ definiert. Zu diesem Zeitpunkt lautet der Einschränkungsausdruck

\begin{split}
y_k - \epsilon \leq \sum_{i=1}^{n} s_{i,k}w_i + c \leq y_k + \epsilon
\end{split}

Es wird. Diese Formel ist definiert als "Startbeschränkungsformel $ S '$". Wenn dies auf die gleiche Weise wie der vorherige Algorithmus berechnet wird, kann die minimale Anzahl $ n $ erhalten werden, die für ein Perzeptron mit einer Genauigkeit innerhalb von $ \ epsilon $ entworfen werden kann. Hier ist zu sehen, dass der zuvor diskutierte "Startbeschränkungsausdruck $ S $" ein spezielles Muster ist, wenn $ \ epsilon = 0 $ des "Startbeschränkungsausdrucks $ S '$" ist.

Tatsächlicher Code

Diesmal als Daten

http://hojin.ctot.jp/markets/data_download.html

Wir verwenden die täglichen Daten von USDJPY für 16 Tage. Unter diesen wird der Fehler innerhalb von 0,1 Yen für den Schlusskurs des Tages angewendet.

#coding:utf-8
from z3 import *
from math import log,ceil

def cluster(max_epsilon,data,solver):
    n = len(data)
    epsilon = Real("epsilon")
    constant = Real("constant")

    max_n = n
    min_n = int(ceil(log(n,2)))
    weights = [
        Real("weight_%04d" % i)
        for i
        in range(n)
    ]

    solver.add(epsilon >= 0)
    solver.add(max_epsilon >= epsilon)

    all_vals = []

    for idx,d in enumerate(data):
        print idx,len(data)
        vals = [
            Real("val_%04d%04d" % (idx,i))
            for i
            in range(n)
        ]

        all_vals.append(vals)

        for val in vals:
           solver.add(Or(val == 1.0,val == 0.0))
            
        solver.check()

        out = sum(v*w for v,w in zip(vals,weights)) + constant

        solver.add(
            d - epsilon <= out , out <= d + epsilon
        )

        solver.check()


    while max_n != min_n:
        try_n = (max_n + min_n) / 2
        solver.push()
        expressions = [
            weights[i] == 0
            for i
            in range(try_n,n)
        ]

        print expressions

        solver.add(
            expressions
        )

        print min_n,max_n,try_n

        if s.check() == sat:
            print "ok:",min_n,max_n,try_n
            max_n = try_n
            s.push()
        else:
            print "ng:",min_n,max_n,try_n
            min_n = try_n
            s.pop()

    print "max_n:",max_n
    print "constant:",float(solver.model()[constant].as_decimal(15)[:-1])
    model = solver.model()
    print "weights:"
    for w in weights:
        print w,model[w].as_decimal(15)[:-1]
    print

    print "patterns:"
    for line in all_vals:
        print "".join(str(int(model[v].as_decimal(15))) for v in line)

       

if __name__=="__main__":
    s = Solver()

    data = []
    with open("tmp.csv") as f:
        f.next()
        for l in f:
            data.append(float(l.split(",")[5]))
        
    data = data[:16]
    data.sort()
    
    cluster(0.1,data,s)

Die tatsächliche Ausgabe ist

kotauchisunsun@kotauchisunsun-VirtualBox:~/z3nn$ python nn_cluster2.py 
0 16
1 16
2 16
3 16
4 16
5 16
6 16
7 16
8 16
9 16
10 16
11 16
12 16
13 16
14 16
15 16
[weight_0010 == 0, weight_0011 == 0, weight_0012 == 0, weight_0013 == 0, weight_0014 == 0, weight_0015 == 0]
4 16 10
ok: 4 16 10
[weight_0007 == 0, weight_0008 == 0, weight_0009 == 0, weight_0010 == 0, weight_0011 == 0, weight_0012 == 0, weight_0013 == 0, weight_0014 == 0, weight_0015 == 0]
4 10 7
ok: 4 10 7
[weight_0005 == 0, weight_0006 == 0, weight_0007 == 0, weight_0008 == 0, weight_0009 == 0, weight_0010 == 0, weight_0011 == 0, weight_0012 == 0, weight_0013 == 0, weight_0014 == 0, weight_0015 == 0]
4 7 5
ok: 4 7 5
[weight_0004 == 0, weight_0005 == 0, weight_0006 == 0, weight_0007 == 0, weight_0008 == 0, weight_0009 == 0, weight_0010 == 0, weight_0011 == 0, weight_0012 == 0, weight_0013 == 0, weight_0014 == 0, weight_0015 == 0]
4 5 4
ok: 4 5 4
max_n: 4
constant: 89.5
weights:
weight_0000 1.4
weight_0001 -0.6
weight_0002 -0.1
weight_0003 -0.8
weight_0004 
weight_0005 
weight_0006 
weight_0007 
weight_0008 
weight_0009 
weight_0010 
weight_0011 
weight_0012 
weight_0013 
weight_0014 
weight_0015 

patterns:
0111101001011111
0011010111111111
0110000111011001
0001110111011110
0100001011101010
0110111001110011
1111001010111011
0000010010100000
0000010110111111
1011100000110011
1001101000010111
1100110001100100
1010011010110111
1010110101000010
1000010110001011
1000110010010001

Nur die Ergebnisse extrahieren und zusammenfassen

output = 1.4 u_1 -0.6 u_2 -0.1 u_3 -0.8 u_4 + 89.5
Schlusskurs u_1 u_2 u_3 u_4
87.87 0 1 1 1
88.37 0 0 1 1
88.61 0 1 1 0
88.7 0 0 0 1
88.77 0 1 0 0
88.79 0 1 1 0
89.17 1 1 1 1
89.47 0 0 0 0
89.64 0 0 0 0
89.86 1 0 1 1
90.09 1 0 0 1
90.32 1 1 0 0
90.71 1 0 1 0
90.84 1 0 1 0
90.9 1 0 0 0
91.08 1 0 0 0

Es wird in Form von sein. Hier können wir sehen, dass 16 Daten durch 4 Perzeptrone mit einem Fehler von 0,1 oder weniger dargestellt werden können.

Methodengrenzen und -beschränkungen

Durch dieses Verfahren können die Anzahl der minimierten Perzeptrone, der Gewichtungskoeffizient zu diesem Zeitpunkt und das Zündmuster der Perzeptrone erhalten werden. Es gibt jedoch zwei Einschränkungen.

  1. Gilt nur für kleine Probleme
  2. Nur die Ausdruckskraft von Perceptron diskutieren

In Bezug auf 1. ist dies die Grenze des von mir verwendeten Z3 Provers. Wenn im obigen Beispielprogramm der Fehlerbereich auf 0,01 eingegrenzt wird, dauert die Ausgabe der Antwort mehr als 30 Minuten (es ist nicht bestätigt, ob die Lösung möglich war, weil sie zu lange gedauert hat). Es kann schneller sein, wenn Sie sich ein wenig mehr an die Implementierungsmethode und die Konstruktion des logischen Ausdrucks halten. In Bezug auf 2., ** Der Text hat bisher nicht die Möglichkeit der Rückkehr besprochen. Um eine Regression durchzuführen, ist es jedoch eine Voraussetzung, dass die Ausgabeschicht mindestens "Ausdrucksfähigkeit der zurückzugebenden Daten" ** aufweist. In diesem Artikel wird nur die Frage "Haben Sie die Möglichkeit, die Daten auszudrücken, die Sie an die Ausgabeebene zurückgeben möchten?" Beschrieben.

Verwendung des neuronalen Netzwerks als Entspannungsproblem

Die diesmal diskutierte Perceptron-Diskussion ist ein Grundmodell. Die heute am häufigsten verwendete Perceptron-Diskriminanzfunktion ist Sigmoid oder Tanh. Schauen Sie sich nun die folgende Abbildung an.

image

Dieses Mal beträgt die Anzahl der durch diese Methode gefundenen Perzeptrone $ n_ {b0} $, da dies "die Anzahl der Perzeptrone ist, die erforderlich sind, um die Ausdruckskraft der Ausgabeschicht auszudrücken". Im Allgemeinen sind die Daten, die Sie suchen möchten, die Zahl, die $ n_ {b1} $ entspricht. Dann gilt "wahrscheinlich" die folgende allgemeine Formel. (Linker grüner Pfeil)

n_{b0} \leq n_{b1}

Der Vorbehalt "wahrscheinlich" ist, weil es nicht bewiesen wurde. Als Diskussion über Regression diskutieren wir nicht die Generalisierungsleistung auf einer anderen Achse. Beim Abrufen der Daten gilt wahrscheinlich die obige Gleichung, um die Fälle feiner Ecken darzustellen. Es ist eine Vorhersage. Hier ist ein anderes Argument möglich: Wenn die Unterscheidungsfunktion von Perceptron auf $ 0 \ leq u \ leq 1 $ erweitert wird, beträgt die Anzahl der Perceptrons, die zur Darstellung der zurückzugebenden Daten erforderlich sind, $ n_ {a0} $. Definiere es. das ist,

n_{b0} \geq n_{a0}

Hält. (Oberer schwarzer Pfeil) Dies liegt daran, dass $ n_ {b0} $ nur zwei Werte von 0,1 für die Diskriminanzfunktion annehmen kann, während die Diskriminatorfunktion von $ n_ {a0} $ den Bereich von 0 bis 1 annehmen kann. .. Zumindest der Wertebereich des ersteren Unterscheidungsbereichs ist nur ein Teil des Bereichs der letzteren Unterscheidungsfunktion, so dass $ n_ {a0} $ der letzteren aussagekräftiger ist und mit einer geringeren Anzahl von Perzeptronen ausgedrückt werden kann. Es wird angenommen, dass die obige Formel gilt. Auch $ n_ {a0} $ kann auf die gleiche Weise wie $ n_ {b0} $ diskutiert werden.

n_{a0} \leq n_{a1}

(Rechter grüner Pfeil). Aus derselben Diskussion wie $ n_ {b0} $ und $ n_ {a0} $,

n_{b1} \geq n_{a1}

Sie können den relationalen Ausdruck sehen. (Schwarzer Pfeil nach unten) Um diese Formeln zusammenzufassen

\begin{split}
n_{a0} \leq n_{b0} \leq n_{b1} \\
n_{a0} \leq n_{a1} \leq n_{b1}
\end{split}

Sie können sehen, dass. Derzeit ist aus der Bedingung von Gleichung (1), wenn die Anzahl der Daten $ m $ ist, die Anzahl der Perzeptrone $ n $

m \geq n \geq \lceil \log_{2} m \rceil

Das wusste ich nur. Es ist jedoch ersichtlich, dass der Bereich von $ n_ {a0} $ weiter begrenzt werden kann, indem der Wert von $ n_ {b0} $ durch das obige Verfahren berechnet wird.

n_{b0} \geq n_{a0} \geq \lceil \log_{2} m \rceil \tag{2}

Die diesmal verwendete Diskriminanzfunktion ist ein sehr begrenztes Modell, und ihr Vorteil ist, dass sie billiger ist als die Diskussion der Anzahl von Perzeptronen unter Verwendung eines allgemeinen Modells. Der Vorteil ist auch, dass der obere Grenzwert wie in Gleichung (2) reduziert werden kann und wenn $ m $ sehr groß ist, $ m >> log_ {2} m $, was allgemein ist Wenn Sie mit einem solchen Modell streiten, kann dies lange dauern, da der Bereich von $ n $ zu groß ist. Daher wird angenommen, dass ein effektives Design erreicht werden kann, indem das diesmal verwendete Grundmodell durchlaufen und eine Obergrenze angegeben wird.

Zusammenfassung

Was diesmal in diesem Artikel besprochen wurde

  1. Diskutierte die Ausdruckskraft von Perceptron, das eine grundlegende Diskriminanzfunktion hat.
  2. Für das Modell in 1. haben wir gezeigt, wie die minimale Anzahl von Perzeptronen ermittelt werden kann, die die angegebenen Daten mindestens darstellen.
  3. Es wurde gezeigt, dass die Anzahl der Perzeptrone mit einer allgemeinen Diskriminanzfunktion unter Verwendung des Ergebnisses von 2 effizient eingegrenzt werden kann.

Wenn $ n_ {b0} $ erhalten werden kann, scheint es wahrscheinlich kein Problem mit $ n_ {a1} = n_ {b0} $ als ursprünglichem Entwurf zu geben. Der Grund dafür ist, dass die Anzahl der Perzeptrone ohne großen Grund empirisch ausgewählt wurde. Daher lohnt es sich, $ n_ {b0} $ als Richtlinie zu verwenden.

die nächste Bereitstellung

Dieses Mal diskutierten wir "die Ausdruckskraft von Perceptron". Wir konnten jedoch nicht über "Rückgabefähigkeit" sprechen. Wenn diesbezüglich eine einfache Methode gefunden werden kann, wird angenommen, dass das minimal notwendige neuronale Netzwerk aufgebaut und die Lernkosten reduziert werden können. Obwohl dies häufig von Z3 Prover abhängt, wird davon ausgegangen, dass es zur fortgeschrittenen Unterscheidungsfähigkeit des maschinellen Lernens beiträgt, wenn diese Entwürfe auf einfachere Weise beschrieben werden und die Logik durch die Erfüllung von Einschränkungen garantiert werden kann.

Recommended Posts

Richtlinien für das Design der Ausgangsschicht neuronaler Netze
Implementierung eines 3-Schicht-Neuronalen Netzwerks (kein Lernen)
Bildgebung eines neuronalen Netzwerks, das MNIST erkennt
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 13 Grundlagen des neuronalen Netzwerks
[Für Anfänger] Warum brauchen Sie das "Gewicht" und die "Tendenz" des neuronalen Netzwerks?
Träumt das neuronale Netz von einer elektrischen Maus?
Visualisieren Sie die innere Schicht des neuronalen Netzwerks