[PYTHON] Liste der Aktivierungsfunktionen (2020)

Zielperson

Ich habe zusammengefasst, welche Art von Aktivierungsfunktion es gibt. ** Das neueste Swish and Mish sowie tanhExp! ** ** ** Ich ziele auf die Ebene, auf der ich keine gute finden kann, selbst wenn ich die Liste durchsuche. Neue werden hinzugefügt, sobald sie gefunden werden. Wenn Sie Informationen zu neuen Funktionen oder Funktionen in der TODO-Liste unten haben, lassen Sie es uns bitte wissen!

Aufgabenliste

--Überprüfen Sie die Zusatzinformationen der hardShrink-Funktion --Überprüfen Sie die Zusatzinformationen der SoftShrink-Funktion --Überprüfen Sie die Zusatzinformationen der Schwellenwertfunktion --Überprüfen Sie die Zusatzinformationen der logSigmoid-Funktion --Überprüfen Sie die Zusatzinformationen der Funktion tanhShrink --Überprüfen Sie die Zusatzinformationen der Hardtanh-Funktion --Überprüfen Sie die Zusatzinformationen der ReLU6-Funktion --Überprüfen Sie die Zusatzinformationen der CELU-Funktion --Überprüfen Sie die Zusatzinformationen der Softmin-Funktion --Überprüfen Sie die Zusatzinformationen der logSoftmax-Funktion

Inhaltsverzeichnis

Schrittfunktion (Schritt)

Zuerst von der Schrittfunktion. Wahrscheinlich die älteste Aktivierungsfunktion. step.png Zu dieser Zeit wurde es verwendet, um Perceptron zu implementieren, aber es wird heutzutage selten im Deep Learning gesehen. Der Grund dafür ist, dass das Differential für alle reellen Zahlen $ 0 $ beträgt ($ x \ ne 0 $), sodass Parameter nicht durch Backpropagation optimiert werden können.

Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    1 & (x \gt 0) \\
    0 & (x \le 0)
  \end{array}
\right.

So ist die Backpropagation-Formel natürlich

\cfrac{\partial y}{\partial x} = 0

Und multiplizieren Sie dies mit dem fließenden Fehler. Mit anderen Worten, nichts wird vergossen. Aus diesem Grund konnte die Methode der Fehlerrückausbreitung nicht angewendet werden und wurde beim tiefen Lernen in den Schatten gezwungen.

Identitätsfunktion

Die Gleichheitsfunktion gibt die Eingabe so aus, wie sie ist. Es wird für die Aktivierungsfunktion der Ausgabeschicht der Regressionsanalyse verwendet. In der mittleren Schicht gibt es keine Wende. Der Zweck der Verwendung einer solchen Aktivierungsfunktion besteht darin, sie eindeutig zu implementieren. Die eindeutige Implementierung soll hier die Verarbeitung nicht durch bedingte Verzweigung oder dergleichen teilen. identity.png Da der Differenzwert $ 1 $ ist, wird der Fehler unverändert auf die vorherige Ebene übertragen. Da bei der Fehlerberechnung der quadratische Fehler verwendet wird, beträgt die Ausbreitung zur nächsten Schicht $ y - t $ ~

Die Formel für die Vorwärtsausbreitung lautet

y = x

Und die Rückenausbreitung ist

\cfrac{\partial y}{\partial x} = 1

Es wird sein. Sie können sehen, dass der Wert, der gerade geflossen ist, fließen wird!

Bent Identity-Funktion

Es ist eine ähnliche Funktion wie [Identitätsfunktion](# Konstante Funktionsidentität). Es ist jedoch nicht gerade, sondern leicht gebogen. bent-identity.png

Die Formel für die Vorwärtsausbreitung lautet

y = \cfrac{1}{2}(\sqrt{x^2 + 1} - 1) + x

So, Rückausbreitung

\cfrac{\partial y}{\partial x} = \cfrac{x}{2 \sqrt{x^2 + 1}} + 1

Es wird sein. Irgendwie sieht es aus wie [ReLU-Funktion](# Relu-Funktion) (persönlicher Eindruck). Ich konnte den auf Japanisch vorgestellten Artikel nicht auf einen Blick finden, daher denke ich, dass es sich um eine geringfügige Aktivierungsfunktion handelt.

HardShrink-Funktion

Von Pytorch vorerst nur eine Einführung. ** Überprüfen Sie die TODO-Zusatzinformationen ** hard-shrink.png Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    x & (x \lt -\lambda \quad \textrm{or} \quad \lambda \lt x) \\
    0 & (\textrm{otherwise})
  \end{array}
\right.

Und die Rückenausbreitung ist

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    1 & (x \lt -\lambda \quad \textrm{or} \quad \lambda \lt x) \\
    0 & (\textrm{otherwise})
  \end{array}
\right.

Es wird sein. Der Standardwert für $ \ lambda $ ist $ 0.5 $.

SoftShrink-Funktion

Dies ist auch nur eine Einführung von Pytorch. ** Überprüfen Sie die TODO-Zusatzinformationen *** soft-shrink.png Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    x + \lambda & (x \lt -\lambda) \\
    x - \lambda & (x \gt \lambda) \\
    0 & (\textrm{otherwise})
  \end{array}
\right.

Und die Rückenausbreitung ist

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    1 & (x \lt -\lambda \quad \textrm{or} \quad \lambda \lt x) \\
    0 & (\textrm{otherwise})
  \end{array}
\right.

Es wird sein. Der Anfangswert von $ \ lambda $ beträgt hier ebenfalls $ 0,5 $.

Schwellenwertfunktion

Dies ist nur eine Einführung von Pytorch. ** Überprüfen Sie die TODO-Zusatzinformationen ** threshold.png Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    x & (x \gt threshold) \\
    value & (\textrm{otherwise})
  \end{array}
\right.

Und die Rückenausbreitung ist

y = \left\{
  \begin{array}{cc}
    1 & (x \gt threshold) \\
    0 & (\textrm{otherwise})
  \end{array}
\right.

Es wird sein. Wobei die Variablen Schwelle und Wert Werte sind, die im Voraus angegeben werden sollten. Vorerst passend in der Grafik

threshold = -1 \\
value = -2

Es wird gesagt.

Sigmoidfunktion (Sigmoid)

Die Sigmoidfunktion ist eine Aktivierungsfunktion, die häufig verwendet wurde, als die Backpropagation-Methode eingeführt wurde. Es wird jedoch derzeit selten in der mittleren Schicht verwendet, und es wird häufig in der Ausgabeschicht von binären Klassifizierungsproblemen verwendet. Der Grund ist der später beschriebene Nachteil. sigmoid.png Vorwärtsausbreitung

y = \cfrac{1}{1 + e^{-x}}

Backpropagation

\cfrac{\partial y}{\partial x} = y(1 - y)

Kann geschrieben werden als Das größte Merkmal ist, dass die Differenzierung leicht von der Ausgabe erhalten werden kann, aber die Reaktion auf extrem große und kleine Eingaben schlecht ist und der maximale Wert der Differenzierung 0,25 $ beträgt. Wenn Sie also Ebenen ** Gradienten stapeln Es gibt auch Nachteile wie das Problem des Verschwindens **. Da es exponentielle Berechnungen und Divisionen gibt, ist die Berechnungslast zwangsläufig höher als die von einfachen Funktionen wie [ReLU-Funktion](# Relu-Funktion).

hardSigmoid-Funktion

Die hardSigmoid-Funktion ist eine lineare Annäherung an die Sigmoid-Funktion, beispielsweise eine lineare Funktion. hard-sigmoid.png Mathematisch Vorwärtsausbreitung

y = \left\{
  \begin{array}{cc}
    1 & (x \gt 2.5) \\
    0.2x + 0.5 & (-2.5 \le x \le 2.5) \\
    0 & (x \lt -2.5)
  \end{array}
\right.

Backpropagation

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    0.2 & (-2.5 \le x \le 2.5) \\
    0 & (\textrm{otherwise})
  \end{array}
\right.

Es sieht aus wie. Es gibt einen Artikel im Detail überprüft. Wenn Sie also mehr wissen möchten, gehen Sie bitte dorthin! Es gibt einen so komplizierten theoretischen Grund, dass der Koeffizient der linearen Funktion $ 0,2 $ beträgt ... ~~ Ich habe es gelesen, aber überhaupt nicht verstanden ~~

logSigmoid-Funktion

Dies ist auch nur eine Einführung von Pytorch. Nimmt den Logarithmus von [Sigmoidfunktion](# Sigmoidfunktion Sigmoid). ** Überprüfen Sie die TODO-Zusatzinformationen ** log-sigmoid.png Die Formel für die Vorwärtsausbreitung lautet

y = \log \left( \cfrac{1}{1 + e^{-x}} \right)

Und Backpropagation

\cfrac{\partial y}{\partial x} = \cfrac{1}{1 + e^x}

Es wird sein. Beachten Sie, dass der Nenner der Backpropagation nicht die Potenz $ -x $ ist.

Tanh-Funktion

Die Tanh-Funktion, die eine der Bikurvenfunktionen ist, wurde als eine der Funktionen vorgeschlagen, um die Schwäche zu lösen, dass der Maximalwert der Differenzierung von [Sigmoidfunktion](# Sigmoidfunktion Sigmoid) $ 0,25 $ beträgt. tanh.png Wie Sie in der Abbildung sehen können, beträgt der Maximalwert des Differentials $ 1 $, und die Ursache für das Verschwinden des Gradienten kann beseitigt werden. Es besteht jedoch immer noch das Problem, dass die Unterscheidung mit extrem großen und kleinen Eingaben $ 0 $ beträgt.

y = \tanh x = \cfrac{e^x - e^{-x}}{e^x + e^{-x}}

Backpropagation

\cfrac{\partial y}{\partial x} = \textrm{sech}^2 x = \cfrac{1}{\cosh^2 x} = \cfrac{4}{(e^x + e^{-x})^2}

Es wird sein. In letzter Zeit wurde es teilweise für erwartete neue Sterne wie [Mischfunktion](# Mischfunktion) und [tanhExp-Funktion](# Tanhexp-Funktion) verwendet. Es scheint eine Funktion mit hoher Aufmerksamkeit zu sein.

tanhShrink-Funktion

Dies ist auch von Pytorch. Es ist nur eine Einführung. ** Überprüfen Sie die TODO-Zusatzinformationen ** tanh-shrink.png Die Formel für die Vorwärtsausbreitung lautet

y = x - \tanh x

Und die Rückenausbreitung ist

\cfrac{\partial y}{\partial x} = \tanh^2 x

Es wird sein.

Hardtanh-Funktion

Dies ist auch Pytorch. Nur zur Einführung ... ** Überprüfen Sie die TODO-Zusatzinformationen ** hard-tanh.png Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    1 & (x \gt 1) \\
    -1 & (x \lt -1) \\
    x & (\textrm{otherwise})
  \end{array}
\right.

Und die Rückenausbreitung ist

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    0 & (x \lt -1 \quad \textrm{or} \quad 1 \le x) \\
    1 & (\textrm{otherwise})
  \end{array}
\right.

Es wird sein.

ReLU-Funktion

Die ReLU-Funktion (allgemein als Rampenfunktion bezeichnet) ist eine kürzlich vorgeschlagene Aktivierungsfunktion, die die Vorherrschaft innehat. Das Merkmal ist diese einfache und schnelle Berechnung. ReLU.png Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    x & (x \gt 0) \\
    0 & (x \le 0)
  \end{array}
\right.

Backpropagation

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    1 & (x \gt 0) \\
    0 & (x \le 0)
  \end{array}
\right.

Es wird sein. Wenn die Eingabe ein positiver Wert ist, beträgt der Gradient immer $ 1 $, sodass der Gradient weniger leicht verschwindet und es einfach ist, Ebenen zu stapeln. Es gibt jedoch auch den Nachteil, dass das Lernen für negative Eingaben überhaupt nicht fortgesetzt wird. Außerdem wird die Diskontinuität bei $ x = 0 $ grundsätzlich ignoriert. Bei der Fehler-Rück-Ausbreitungsmethode wird das Lernen basierend auf der Ausbreitung des Gradienten unter Verwendung des Kettengesetzes vorangetrieben, so dass die Aktivierungsfunktion mit allen reellen Zahlen differenzierbar sein sollte, aber in Wirklichkeit ist sie perfekt $ x = 0 $ Es gibt sowieso weniger Fälle, in denen es zu & $ 0 $ wird, also spielt es keine Rolle.

ReLU6-Funktion

Nur eine Einführung von Pytorch. ** Überprüfen Sie die TODO-Zusatzinformationen ** ReLU6.png Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    0 & (x \le 0) \\
    6 & (x \ge 6) \\
    x & (\textrm{otherwise})
  \end{array}
\right.

Und Backpropagation

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    0 & (x \le 0 \quad \textrm{or} \quad 6 \le x) \\
    1 & (\textrm{otherwise})
  \end{array}
\right.

Es wird sein.

Leaky-ReLU-Funktion

Die Leaky-ReLU-Funktion gibt bei einem negativen Eingang eine lineare Funktion mit einem sehr kleinen Gradienten aus, um den Nachteil der [ReLU-Funktion](# Relu-Funktion) zu kompensieren, dass "das Lernen für negative Eingänge nicht fortgesetzt wird". Es ist so etwas. leaky-ReLU.png In der Grafik ist wenig zu sehen, aber in der Formel

y = \left\{
  \begin{array}{cc}
    x & (x \gt 0) \\
    0.01x & (x \le 0)
  \end{array}
\right.

Der Ausgang ist unterschiedlich, wenn der Eingang negativ ist. Daher Backpropagation

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    1 & (x \gt 0) \\
    0.01 & (x \le 0)
  \end{array}
\right.

Es wird sein. Dies ist auch bei $ x = 0 $ diskontinuierlich. Ich habe es auch an verschiedenen Stellen während meiner Recherche gesehen, aber es scheint, dass der Name dieser Funktion lautet: "Es hatte keinen besonderen Sinn, dies zu verwenden." Es ist ein wenig überraschend. Es sieht so aus, als würde es sich ein wenig verbessern ...

ELU-Funktion

Ein Graph, dessen Form der [ReLU-Funktion](# Relu-Funktion) ähnelt, einer der glatteren Funktionen, wenn $ x = 0 $ ist, ist die ELU-Funktion. ELU.png Wie Sie in der Grafik sehen können, führen negative Eingaben nicht zu einem Gradienten von $ 0 $ ($ 0 $ für $ x \ to- \ infty $). In der Formel

y = \left\{
  \begin{array}{cc}
    x & (x \ge 0) \\
    \alpha (e^x - 1) & (x \lt 0)
  \end{array}
\right.

Und Backpropagation

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    1 & (x \ge 0) \\
    \alpha e^x & (x \lt 0)
  \end{array}
\right.

Es wird sein. Es scheint, dass der Wert von ~~ $ \ alpha $ in der nächsten [SELU-Funktion](# selu-Funktion) (wahrscheinlich) häufig einen theoretisch angemessenen Wert annimmt. ~~ ** Überarbeitet am 02.06.2020 ** Der Standardwert für $ \ alpha $ scheint normalerweise $ 1 $ zu sein. Ich werde es durch ein Diagramm von $ \ alpha = 1 $ ersetzen. Es tut mir leid, dass ich die falschen Informationen gesendet habe ...

SELU-Funktion

Die SELU-Funktion ist die Ausgabe der [ELU-Funktion](# elu-Funktion) multipliziert mit $ \ lambda $. SeLU.png In der Formel

y = \left\{
  \begin{array}{cc}
    \lambda x & (x \ge 0) \\
    \lambda \alpha (e^x - 1) & (x \lt 0)
  \end{array}
\right.

Und Backpropagation

\cfrac{\partial y}{\partial x} = \left\{
  \begin{array}{cc}
    \lambda & (x \ge 0) \\
    \lambda \alpha e^x & (x \lt 0)
  \end{array}
\right.

Es wird wie in mit $ \ lambda $ multipliziert. Es scheint, dass der theoretisch optimale Parameterwert erhalten werden kann, und dieser Wert ist

\alpha = 1.67326\ldots, \quad \lambda = 1.0507\ldots

Es scheint so als. Ich könnte die Zeitung bald lesen ... Ich werde sie ergänzen, wenn ich sie lese.

CELU-Funktion

Dies ist auch eine Einführung nur von Pytorch. ** Überprüfen Sie die TODO-Zusatzinformationen ** CeLU.png Die Formel für die Vorwärtsausbreitung lautet

y = \left\{
  \begin{array}{cc}
    x & (x \ge 0) \\
    \alpha \left( e^{\frac{x}{\alpha}} - 1 \right) & (\textrm{otherwise})
  \end{array}
\right.

Und die Formel für die Rückausbreitung lautet

y = \left\{
  \begin{array}{cc}
    1 & (x \ge 0) \\
    e^{\frac{x}{\alpha}} & (\textrm{otherwise})
  \end{array}
\right.

Es wird sein.

Softmax-Funktion (Softmax)

Die Softmax-Funktion wird als Aktivierungsfunktion für die Ausgabeschicht von mehrwertigen Klassifizierungsproblemen verwendet. Aufgrund der Eigenschaften der Berechnung kann die Ausgabe als Wahrscheinlichkeit angesehen werden. softmax.png Sorgen Sie sich nicht zu sehr um die vertikale Achse des Diagramms. Alles, was zählt, ist, dass Sie bei der Integration (der Computer ist diskret, also fassen Sie es zusammen) $ 1 $ erhalten. Mathematisch

y_i = \cfrac{e^{x_i}}{\displaystyle\sum_{k=1}^{n}{e^{x_k}}} \quad (i = 1, 2, \ldots, n)

Es ist wie es ist. Die Rückenausbreitung ist vorläufig

\left( \cfrac{\partial y}{\partial x} \right)_i = e^{x_i} \cfrac{\displaystyle\sum_{k=1}^{n}{e^{x_k}} - e^{x_i}}{\left( \displaystyle\sum_{k=1}^{n}{e^{x_k}} \right)^2}

** Kreuzentropiefehler **

Error = t \log y

Durch Aufnehmen der Rückausbreitung von der Ausgangsschicht zur Zwischenschicht

y - t

Es wird sehr einfach sein. Dies ist übrigens kein Zufall, der Kreuzentropiefehler ist eine Funktion, die so ausgelegt ist, dass sie zur Softmax-Funktion passt, sodass der Gradient $ y-t $ beträgt. Ich kann es eines Tages in ein Berechnungsdiagramm einführen.

Softmin-Funktion

Dies ist auch von Pytorch. Im Gegensatz zu [Softmax-Funktion](# Softmax-Funktion Softmax) steigt die Wahrscheinlichkeit kleiner Werte. ** Überprüfen Sie die TODO-Zusatzinformationen ** softmin.png Die Formel für die Vorwärtsausbreitung lautet

y_i = \cfrac{e^{-x_i}}{\displaystyle\sum_{k=1}^{n}{e^{-x_k}}} \quad (i = 1, 2, \ldots, n)

Und die Formel für die Rückausbreitung lautet

\left( \cfrac{\partial y}{\partial x} \right)_i = e^{-x_i} \cfrac{\displaystyle\sum_{k=1}^{n}{e^{-x_k}} - e^{-x_i}}{\left( \displaystyle\sum_{k=1}^{n}{e^{-x_k}} \right)^2}

Es wird sein. Wenn der Kreuzentropiefehler auch hier verwendet wird, breitet sich der Fehler sauber zurück ... Ich werde ihn das nächste Mal untersuchen.

logSoftmax-Funktion

Von Pytorch ist dies der Logarithmus von [softmax function](#softmax function softmax). ** Überprüfen Sie die TODO-Zusatzinformationen ** log-softmax.png Es sieht fast gerade aus. Ich frage mich, ob es passt ... Ich denke, der Code ist korrekt. Die Formel für die Vorwärtsausbreitung lautet

y_i = \log \left( \cfrac{e^{x_i}}{\displaystyle\sum_{k=1}^{n}{e^{x_k}}} \right)

Und die Rückenausbreitung ist

\left( \cfrac{\partial y}{\partial x} \right)_i = \cfrac{\displaystyle\sum_{k=1}^{n}{e^{x_k}} - e^{x_i}}{\displaystyle\sum_{k=1}^{n}{e^{x_k}}}

Es wird sein.

Softplus-Funktion

Die Softplus-Funktion hat einen ähnlichen Namen wie [Softmax-Funktion](# Softmax-Funktion Softmax), ähnelt jedoch im Wesentlichen der [ReLU-Funktion](# Relu-Funktion). softplus.png

In der Formel

y = \log{(1 + e^x)} = \ln{(1 + e^x)}

Ausgedrückt als Backpropagation

\cfrac{\partial y}{\partial x} = \cfrac{e^x}{1 + e^x} = \cfrac{1}{1 + e^{-x}}

Es sieht aus wie. Es sieht genauso aus wie die [ReLU-Funktion](# relu-Funktion) und die Differenzierung.

Übrigens soll $ \ ln x $ klarstellen, dass die Basis eine logarithmische Funktion von Napier-Zahlen ist. Mit anderen Worten

\ln x = \log_ex

Es ist das.

Softsign-Funktion

Auch hier ähnelt der Name [softmax function](#softmax function softmax), in Wirklichkeit ähnelt er jedoch [tanh function](#tanh function) (Vorwärtsausbreitung). softsign.png

Die Vorwärtsausbreitung sieht genauso aus wie die Tanh-Funktion, aber die Rückwärtsausbreitung ist völlig anders. Es ist sehr scharf. Blick auf die Vorwärtsausbreitung mit einer mathematischen Formel

y = \cfrac{x}{1 + |x|}

Und Backpropagation

\cfrac{\partial y}{\partial x} = \cfrac{1}{(1 + |x|)^2}

Es ist geworden. Bei ~~ $ x = 0 $ ist die Differenzierung zu einer diskontinuierlichen Funktion geworden. ~~ ** Überarbeitet am 02.06.2020 ** Ich habe die Kontinuität der Funktion falsch verstanden. Es ist nicht diskontinuierlich richtig. Es kann nicht unterschieden werden.

\lim_{x \to \pm 0}{\cfrac{1}{(1 + |x|)^2}} = 1
\Leftrightarrow
\lim_{x \to 0}{\cfrac{1}{(1 + |x|)^2}} = 1 

Und

\cfrac{\partial y}{\partial x} = \cfrac{1}{(1 + |0|)^2} = 1 \quad (\because x = 0)

Damit

\lim_{x \to 0}{\cfrac{1}{(1 + |x|)^2}} = \cfrac{1}{(1 + |0|)^2}

Wird als kontinuierlich angezeigt.

Swish-Funktion

Dies ist die Swish-Funktion, die voraussichtlich der Nachfolger der 2017 erschienenen [ReLU-Funktion](# relu-Funktion) sein wird. Swish.png Es sieht genauso aus wie die [ReLU-Funktion](# Relu-Funktion), aber im Gegensatz zu [ELU-Funktion](# Elu-Funktion) und [SELU-Funktion](# Selu-Funktion) wird es auch mit $ x = 0 $ zu einer stetigen Funktion. Ich bin. Ein weiteres Merkmal ist, dass es sich um eine $ C ^ {\ infty} $ -Klassenfunktion handelt. Darüber hinaus können Sie auch sehen, dass für negative Eingaben nur wenige negative Werte erforderlich sind. Der schöne Punkt ist, dass es einen Minimalwert und keinen Maximalwert gibt. Wenn die Vorwärtsausbreitung durch eine mathematische Formel ausgedrückt wird

y = x \sigma_{sigmoid}(\beta x) = \cfrac{x}{1 + e^{-\beta x}}

Es ist wie es ist. In der obigen Grafik ist $ \ beta = 1 $ festgelegt. Übrigens scheint es, dass $ \ beta $ durch die Fehler-Back-Propagation-Methode (nicht implementiert) optimiert werden kann. Backpropagation

\cfrac{\partial y}{\partial x} = \beta y + \sigma_{sigmoid}(\beta x)(1 - \beta y) = \beta y + \cfrac{1 - \beta y}{1 + e^{-\beta x}}

Sie können so schreiben. Es fühlt sich an wie ein Blick auf die [Sigmoid-Funktion](# Sigmoid-Funktion Sigmoid).

Mischfunktion

Die Mish-Funktion ist der Nachfolger der 2019 vorgeschlagenen [ReLU-Funktion](# Relu-Funktion), die noch aktueller ist als die [Swish-Funktion](# Swish-Funktion). Papiere haben gezeigt, dass es oft die Swish-Funktion übertrifft. (Ich habe die Zeitung noch nicht richtig gelesen, aber er hat sie geschrieben) Mish.png Es sieht fast genauso aus wie die Swish-Funktion, ist aber etwas anders. swish_vs_mish.png Die Grafik ganz rechts zeigt den größten Unterschied. Dieses Diagramm ist die Berechnung jeder doppelten Differenzierung. Mit anderen Worten, es repräsentiert den Grad der Änderung des Gradienten. Was Sie aus dem Diagramm ablesen können, ist, dass die Mish-Funktion deutlichere Fehler übermittelt, insbesondere bei der $ \ Rightarrow $ -Gradientenberechnung, die sich dynamisch um $ x = 0 $ ändert. Als Vorwärtsausbreitungsformel

y = x \tanh{(\varsigma(x))} = x \tanh{(\ln{(1 + e^x)})}

Die Rückausbreitung ist etwas kompliziert

\cfrac{\partial y}{\partial x} = \cfrac{e^x \omega}{\delta^2}\\
\omega = 4(x + 1) + 4e^{2x} + e^{3x} + (4x + 6)e^x \\
\delta = 2e^x + e^{2x} + 2

Es wird berechnet als. Daher dauert das Lernen länger als die ReLU-Funktion. In Bezug auf die Genauigkeit ist dies jedoch häufig besser als die Verwendung der ReLU-Funktion. Berücksichtigen Sie daher bei der Auswahl einer Aktivierungsfunktion den Kompromiss zwischen Lernzeit und Genauigkeit.

tanhExp-Funktion

Dies ist die tanhExp-Funktion von @ reppy4620! Laut Paper ist es ab März 2020 ~ Es ist schrecklich neu. tanhExp.png Wie Sie in diesem Artikel sehen können, ist es ein Mitglied der [ReLU-Funktion](# relu-Funktion) (heißt es die ReLU-Familie?). Anscheinend übertrifft es die [Mish-Funktion](# mish-Funktion) in berühmten Datensätzen wie MNIST, CIFER-10 und CIFER-100 (ich habe es noch nicht gelesen). Vergleiche mit [Swish-Funktion](# Swish-Funktion) Swish_vs_tanhExp.png Die Ausgabe der Vorwärtsausbreitung sieht fast gleich aus, aber die tanhExp-Funktion hat eine steilere Steigung und einen kleineren Bereich über dem Differenzwert von $ 1 $ bei der Rückwärtsausbreitung. Der Gradient ist sehr empfindlich, und wenn der absolute Wert des Differentials weniger als $ 1 $ beträgt, verschwindet der Gradient sofort, und umgekehrt, wenn er mehr als $ 1 $ beträgt, tritt eine Gradientenexplosion auf. Die tanhExp-Funktion sieht auch in dieser Hinsicht hervorragend aus. Dann vergleiche mit [Mischfunktion](# Mischfunktion). Mish_vs_tanhExp.png Die Mish-Funktion folgt eher der tanhExp-Funktion als der Swish-Funktion. Bei steilen Hängen um $ 0 $ ist die tanhExp-Funktion jedoch immer noch besser. Betrachten wir die Vorwärtsausbreitung mit einer mathematischen Formel.

y = x \tanh(e^x)

Sie verwenden sowohl die Tanh-Funktion als auch die Mish-Funktion. Bekommt die Tanh-Funktion jetzt nicht mehr Aufmerksamkeit? Backpropagation

\begin{align}
  \cfrac{\partial y}{\partial x} &= \tanh(e^x) + xe^x\textrm{sech}^2(e^x) \\
  &= \tanh(e^x) - xe^x(\tanh^2(e^x) - 1)
\end{align}

Es wird sein. Es ist schön, viel einfacher berechnen zu können als die Mish-Funktion ~

Codebeispiel

Hier ist ein Beispiel für den Code, der beim Zeichnen des Diagramms verwendet wird. Bitte verwenden Sie es als Referenz bei der Implementierung. Ich benutze ein Jupyter-Notebook.

activators.py

activators.py


import numpy as np


class Activator():
    def __init__(self, *args,**kwds):
        pass
    

    def forward(self, *args,**kwds):
        raise Exception("Not Implemented")
    
    
    def backward(self, *args,**kwds):
        raise Exception("Not Implemented")
    
    
    def update(self, *args,**kwds):
        pass


class step(Activator):
    def forward(self, x, *args,**kwds):
        return np.where(x > 0, 1, 0)
    
    
    def backward(self, x, *args,**kwds):
        return np.zeros_like(x)


class identity(Activator):
    def forward(self, x, *args,**kwds):
        return x
    
    
    def backward(self, x, *args,**kwds):
        return np.ones_like(x)


class bentIdentity(Activator):
    def forward(self, x, *args,**kwds):
        return 0.5*(np.sqrt(x**2 + 1) - 1) + x
    
    
    def backward(self, x, *args,**kwds):
        return 0.5*x/np.sqrt(x**2 + 1) + 1


class hardShrink(Activator):
    def __init__(self, lambda_=0.5, *args,**kwds):
        self.lambda_ = lambda_
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return np.where((-self.lambda_ <= x) & (x <= self.lambda_),
                        0, x)
    
    
    def backward(self, x, *args,**kwds):
        return np.where((-self.lambda_ <= x) & (x <= self.lambda_),
                        0, 1)


class softShrink(Activator):
    def __init__(self, lambda_=0.5, *args,**kwds):
        self.lambda_ = lambda_
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return np.where(x < -self.lambda_, x + self.lambda_,
                        np.where(x > self.lambda_, x - self.lambda_, 0))
    
    
    def backward(self, x, *args,**kwds):
        return np.where((-self.lambda_ <= x) & (x <= self.lambda_),
                        0, 1)


class threshold(Activator):
    def __init__(self, threshold, value, *args,**kwds):
        self.threshold = threshold
        self.value = value
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return np.where(x > self.threshold, x, self.value)
    
    
    def backward(self, x, *args,**kwds):
        return np.where(x > self.threshold, 1, 0)


class sigmoid(Activator):
    def forward(self, x, *args,**kwds):
        return 1/(1 + np.exp(-x))
    
    
    def backward(self, x, y, *args,**kwds):
        return y*(1 - y)


class hardSigmoid(Activator):
    def forward(self, x, *args,**kwds):
        return np.clip(0.2*x + 0.5, 0, 1)
    
    
    def backward(self, x, *args,**kwds):
        return np.where((x > 2.5) | (x < -2.5), 0, 0.2)


class logSigmoid(Activator):
    def forward(self, x, *args,**kwds):
        return -np.log(1 + np.exp(-x))
    
    
    def backward(self, x, *args,**kwds):
        return 1/(1 + np.exp(x))


class act_tanh(Activator):
    def forward(self, x, *args,**kwds):
        return np.tanh(x)
    
    
    def backward(self, x, *args,**kwds):
        return 1 - np.tanh(x)**2


class hardtanh(Activator):
    def forward(self, x, *args,**kwds):
        return np.clip(x, -1, 1)
    
    
    def backward(self, x, *args,**kwds):
        return np.where((-1 <= x) & (x <= 1), 1, 0)


class tanhShrink(Activator):
    def forward(self, x, *args,**kwds):
        return x - np.tanh(x)
    
    
    def backward(self, x, *args,**kwds):
        return np.tanh(x)**2


class ReLU(Activator):
    def forward(self, x, *args,**kwds):
        return np.maximum(0, x)
    
    
    def backward(self, x, *args,**kwds):
        return np.where(x > 0, 1, 0)


class ReLU6(Activator):
    def forward(self, x, *args,**kwds):
        return np.clip(x, 0, 6)
    
    
    def backward(self, x, *args,**kwds):
        return np.where((0 < x) & (x < 6), 1, 0)


class leakyReLU(Activator):
    def __init__(self, alpha=1e-2, *args,**kwds):
        self.alpha = alpha
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return np.maximum(self.alpha * x, x)
    
    
    def backward(self, x, *args,**kwds):
        return np.where(x < 0, self.alpha, 1)


class ELU(Activator):
    def __init__(self, alpha=1., *args,**kwds):
        self.alpha = alpha
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return np.where(x >= 0, x, self.alpha*(np.exp(x) - 1))
    
    
    def backward(self, x, *args,**kwds):
        return np.where(x >= 0, 1, self.alpha*np.exp(x))


class SELU(Activator):
    def __init__(self, lambda_=1.0507, alpha=1.67326, *args,**kwds):
        self.lambda_ = lambda_
        self.alpha = alpha
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return np.where(x >= 0,
                        self.lambda_*x,
                        self.lambda_*self.alpha*(np.exp(x) - 1))
    
    
    def backward(self, x, *args,**kwds):
        return np.where(x >= 0, 
                        self.lambda_,
                        self.lambda_*self.alpha*np.exp(x))


class CELU(Activator):
    def __init__(self, alpha=1., *args,**kwds):
        self.alpha = alpha
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return np.where(x >= 0,
                        x,
                        self.alpha*(np.exp(x/self.alpha) - 1))
    
    
    def backward(self, x, *args,**kwds):
        return np.where(x >= 0, 1, np.exp(x/self.alpha))


class softmax(Activator):
    def forward(self, x, *args,**kwds):
        return np.exp(x)/np.sum(np.exp(x))
    
    
    def backward(self, x, *args,**kwds):
        return np.exp(x)*(np.sum(np.exp(x)) 
                          - np.exp(x))/np.sum(np.exp(x))**2


class softmin(Activator):
    def forward(self, x, *args,**kwds):
        return np.exp(-x)/np.sum(np.exp(-x))
    
    
    def backward(self, x, *args,**kwds):
        return -(np.exp(x)*(np.sum(np.exp(-x)) - np.exp(x))
                 /np.sum(np.exp(-x))**2)


class logSoftmax(Activator):
    def forward(self, x, *args,**kwds):
        return np.log(np.exp(x)/np.sum(np.exp(x)))
    
    
    def backward(self, x, *args,**kwds):
        y = np.sum(np.exp(x))
        return (y - np.exp(x))/y


class softplus(Activator):
    def forward(self, x, *args,**kwds):
        return np.logaddexp(x, 0)
    
    
    def backward(self, x, *args,**kwds):
        return 1/(1 + np.exp(-x))


class softsign(Activator):
    def forward(self, x, *args,**kwds):
        return x/(1 + np.abs(x))
    
    
    def backward(self, x, *args,**kwds):
        return 1/(1 + np.abs(x)) ** 2


class Swish(Activator):
    def __init__(self, beta=1, *args,**kwds):
        self.beta = beta
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        return x/(1 + np.exp(-self.beta*x))
    
    
    def backward(self, x, y, *args,**kwds):
        return self.beta*y + (1 - self.beta*y)/(1 + np.exp(-self.beta*x))
    
    
    def d2y(self, x, *args,**kwds):
        return (-0.25*self.beta*(self.beta*x*np.tanh(0.5*self.beta*x) - 2)
                               *(1 - np.tanh(0.5*self.beta*x)**2))


class Mish(Activator):
    def forward(self, x, *args,**kwds):
        return x*np.tanh(np.logaddexp(x, 0))
    
    
    def backward(self, x, *args,**kwds):
        omega = (4*(x + 1) + 4*np.exp(2*x) 
                 + np.exp(3*x) + (4*x + 6)*np.exp(x))
        delta = 2*np.exp(x) + np.exp(2*x) + 2
        return np.exp(x)*omega/delta**2
    
    
    def d2y(self, x, *args,**kwds):
        omega = (2*(x + 2) 
                 + np.exp(x)*(np.exp(x)*(-2*np.exp(x)*(x - 1) - 3*x + 6)
                              + 2*(x + 4)))
        delta = np.exp(x)*(np.exp(x) + 2) + 2
        return 4*np.exp(x)*omega/delta**3


class tanhExp(Activator):
    def forward(self, x, *args,**kwds):
        return x*np.tanh(np.exp(x))
    
    
    def backward(self, x, *args,**kwds):
        tanh_exp = np.tanh(np.exp(x))
        return tanh_exp - x*np.exp(x)*(tanh_exp**2 - 1)
    
    
    def d2y(self, x, *args,**kwds):
        tanh_exp = np.tanh(np.exp(x))
        return (np.exp(x)*(-x + 2*np.exp(x)*x*tanh_exp - 2)
                         *(tanh_exp**2 - 1))


class maxout(Activator):
    def __init__(self, n_prev, n, k, wb_width=5e-2, *args,**kwds):
        self.n_prev = n_prev
        self.n = n
        self.k = k
        self.w = wb_width*np.random.rand((n_prev, n*k))
        self.b = wb_width*np.random.rand(n*k)
        
        super().__init__(*args,**kwds)
    
    
    def forward(self, x, *args,**kwds):
        self.x = x.copy()
        self.z = np.dot(self.w.T, x) + self.b
        self.z = self.z.reshape(self.n, self.k)
        self.y = np.max(self.z, axis=1)
        return self.y
    
    def backward(self, g, *args,**kwds):
        self.dw = np.sum(np.dot(self.w, self.x))
test_activators.py

test_activators.py


import numpy as np
import matplotlib.pyplot as plt


_act_dic = {"step": step,
            "identity": identity,
            "bent-identity": bentIdentity,
            "hard-shrink": hardShrink,
            "soft-shrink": softShrink,
            "threshold": threshold,
            "sigmoid": sigmoid,
            "hard-sigmoid": hardSigmoid,
            "log-sigmoid": logSigmoid,
            "tanh": act_tanh,
            "tanh-shrink": tanhShrink,
            "hard-tanh":hardtanh,
            "ReLU": ReLU,
            "ReLU6": ReLU6,
            "leaky-ReLU": leakyReLU,
            "ELU": ELU,
            "SELU": SELU,
            "CELU": CELU,
            "softmax": softmax,
            "softmin": softmin,
            "log-softmax": logSoftmax,
            "softplus": softplus,
            "softsign": softsign,
            "Swish": Swish,
            "Mish": Mish,
            "tanhExp": tanhExp,
           }


def get_act(name, *args,**kwds):
    for act in _act_dic:
        if name == act:
            activator = _act_dic[name](*args,**kwds)
            break
    else:
        raise ValueError(name, ": Unknown activator")
    
    return activator


def plot_graph(x, name, *args,**kwds):
    activator = get_act(name, *args,**kwds)
    
    y = activator.forward(x, *args,**kwds)
    dx = activator.backward(x, y, *args,**kwds)
    
    plt.plot(x, y, label="forward")
    plt.plot(x, dx, label="backward")
    plt.title(name)
    plt.xlabel("x")
    plt.ylabel("y")
    plt.grid()
    plt.legend(loc="best")
    plt.savefig("{}.png ".format(name))
    plt.show()


def vs_plot(x, A, B):
    A_activator = get_act(A)
    B_activator = get_act(B)
    
    y_A = {}
    y_B = {}
    
    y_A["{} y".format(A)] = A_activator.forward(x)
    y_B["{} y".format(B)] = B_activator.forward(x)
    y_A["{} dy".format(A)] = A_activator.backward(x, 
                                                  y_A["{} y".format(A)])
    y_B["{} dy".format(B)] = B_activator.backward(x,
                                                  y_B["{} y".format(B)])
    y_A["{} d2y".format(A)] = A_activator.d2y(x, y_A["{} y".format(A)])
    y_B["{} d2y".format(B)] = B_activator.d2y(x, y_B["{} y".format(B)])
    
    fig, ax = plt.subplots(1, 3, figsize=(18, 6))
    for i, key in enumerate(y_A):
        ax[i].plot(x, y_A[key], label=key)
        ax[i].set_xlabel("x")
        ax[i].set_ylabel("y")
        ax[i].grid()
    for i, key in enumerate(y_B):
        ax[i].plot(x, y_B[key], label=key)
        ax[i].legend(loc="best")
    ax[0].set_title("forward")
    ax[1].set_title("backward")
    ax[2].set_title("second-order derivative")
    fig.tight_layout()
    fig.savefig("{}_vs_{}.png ".format(A, B))
    plt.show()


x = np.arange(-5, 5, 5e-2)

plot_graph(x, "step")
plot_graph(x, "identity")
plot_graph(x, "bent-identity")
plot_graph(x, "hard-shrink")
plot_graph(x, "soft-shrink")
plot_graph(x, "threshold", -1, -2)
plot_graph(x, "sigmoid")
plot_graph(x, "hard-sigmoid")
plot_graph(x, "log-sigmoid")
plot_graph(x, "tanh")
plot_graph(x, "tanh-shrink")
plot_graph(x, "hard-tanh")
plot_graph(x, "ReLU")
plot_graph(x + 2, "ReLU6")
plot_graph(x, "leaky-ReLU")
plot_graph(x, "ELU")
plot_graph(x, "SELU")
plot_graph(x, "CELU")
plot_graph(x, "softmax")
plot_graph(x, "softmin")
plot_graph(x, "log-softmax")
plot_graph(x, "softplus")
plot_graph(x, "softsign")
plot_graph(x, "Swish")
plot_graph(x, "Mish")
plot_graph(x, "tanhExp")

vs_plot(x, "Swish", "Mish")
vs_plot(x, "Swish", "tanhExp")
vs_plot(x, "Mish", "tanhExp")

Es gibt einige andere, die implementiert werden. Ich denke, ich werde es bald hinzufügen ...

Referenz

Künstliche Intelligenz Unterscheidet sich von der Art der Aktivierungsfunktion. Verdienst und Fehler. ](Https://fresopiya.com/2019/05/14/activefunc/)

Nachtragsliste & danke

--- @ reppy4620 gab uns Informationen über die tanhExp-Funktion! Vielen Dank, dass Sie den Link des Papiers höflich gepostet haben!

Deep Learning-Serie

Recommended Posts

Liste der Aktivierungsfunktionen (2020)
Liste der Python-Module
Deep Learning / Aktivierungsfunktionen
Kopie mehrerer Listen
Liste häufig verwendeter integrierter Funktionen und Methoden
# 4 [Python] Grundlagen der Funktionen
Tiefe der verschachtelten Liste
Anzeige von Brüchen (Liste)
Fügen Sie nach und nach eine Liste der Funktionen der Numpy-Bibliothek hinzu --a
Zusammenfassung der Python3-Listenoperationen
Aktivieren Sie Aktivierungsfunktionen nebeneinander
Vollständiges Verständnis der Funktion numpy.pad
Filterbetrieb (Keine, Liste)
Liste der Knoten in Diagrammen
Liste der selbst erstellten Docker-Bilder
Mehrdimensionale Array-Initialisierung der Liste
[Python] Kopie einer mehrdimensionalen Liste
Liste nützlicher Codierungsstile
Fügen Sie nach und nach eine Liste der Funktionen der Numpy-Bibliothek hinzu --- b
Fügen Sie nach und nach eine Liste der Funktionen der Numpy-Bibliothek hinzu --c
Zusammenfassung der Aktivierungsfunktionen (Schritt, Sigmoid, ReLU, Softmax, konstante Funktion)
[Python] Verwalten Sie Funktionen in einer Liste
Einführung und Implementierung der Aktivierungsfunktion
Beurteilung, ob durch Listeneinschlussnotation
Liste der gebrauchsfertigen Worteinbettungsvektoren
Liste der von conda installierten Pakete
10 Funktionen von "Sprache mit Batterie" Python
Liste der häufig verwendeten Linux-Befehle
Generieren Sie eine Liste aufeinanderfolgender Zeichen
Informationen zur Grundlagenliste der Python-Grundlagen
Wenden Sie die Funktion auf die Zeile oder Spalte von numpy.array an, ohne die Listeneinschlussnotation zu verwenden
[Linux] Liste der in der Praxis verwendeten Linux-Befehle
Zeigen Sie eine Liste der Alphabete in Python 3 an
Algorithmus Gymnastik 24 Mitte der verknüpften Liste
Holen Sie sich die Spaltenliste und Datenliste von CASTable
Zusammenfassung der Numpy-Funktionen, die ich nicht kannte
[Python] Ruft eine Liste der Instanzvariablen ab
String-Konvertierung einer Liste mit Zahlen
Grundlegende Grammatik der Python3-Reihe (Liste, Tapple)
Liste der Atom-Pakete, die ich wirklich benutze
Zusammenfassung der integrierten Methoden usw. der Python-Liste
[Maschinelles Lernen] Liste der häufig verwendeten Pakete
Zusammenfassung der Verwendung der Python-Liste
[Python] Nur eine Liste der Ordner abrufen
[Für Anfänger] Einfaches Beispiel für Listenoperationsfunktionen: Zuordnen, Reduzieren, Filtern