[PYTHON] Sattelpunktsuche mit der Gradientenmethode

1. Was ist ein Sattelpunkt?

Ein Sattelpunkt ist ein Punkt, an dem die Steigung 0 ist und das Minimum aus einer bestimmten Richtung und das Maximum aus einer bestimmten Richtung genommen wird. Es ist ein wichtiges Thema in verschiedenen Bereichen, wie es GAN beim maschinellen Lernen und bei Übergangszuständen bei der Suche nach chemischen Reaktionswegen darstellt. GAN besteht aus einem Generator, der Daten generiert, die genau wie die realen Daten aussehen, und einem Diskriminator, der zwischen den realen und den generierten Daten unterscheidet. Lernen Sie, mit dem Generator das Maximum und mit dem Diskriminator das Minimum zu nehmen. Bei der chemischen Reaktion passieren verschiedene stabile Rohstoffe die Sattelpunkte auf der potenziell energiegekrümmten Oberfläche und wandeln sich in stabilere Verbindungen um. In diesem Artikel werden wir mit der Gradientenmethode nach Sattelpunkten suchen. Diese Methode ist für einfache Modelle effektiv, verhält sich jedoch für komplexe Modelle (z. B. Quantenchemie usw.) etwas instabil. Daher werde ich sie hinzufügen, sobald sie verbessert werden kann. Wenn Sie an diesem Artikel interessiert sind, LGTM! Bitte.

2. Definition des Sattelpunktes

Beschreiben Sie den Sattelpunkt wie folgt. Die Zielfunktion ist $ y = f (\ boldsymbol {x}) $, $ \ boldsymbol {x} = (x_1, x_2, \ cdots, x_n) ^ \ rm {T} $, und der dem Minimalwert entsprechende Einheitsvektor ist $ \ boldsymbol {b} = (b_1, b_2, \ cdots, b_n) ^ \ rm {T} $, der dem Maximalwert entsprechende Einheitsvektor ist $ \ boldsymbol {c} = (c_1, c_2, \ cdots, c_n) ^ Definiert als \ rm {T} $. Zu diesem Zeitpunkt wird der Gradient von $ f $ zu $ 0 $, und $ y = f (\ boldsymbol {x} + \ boldsymbol {b} t) $ nimmt den Mindestwert bei $ t = 0 $ in Bezug auf $ t $ und $ y an Der Sattelpunkt ist, dass = f (\ boldsymbol {x} + \ boldsymbol {c} t) $ den Maximalwert bei $ t = 0 $ in Bezug auf $ t $ annimmt. Die Formel lautet wie folgt.

Am Sattelpunkt $ \ boldsymbol {x} = \ boldsymbol {x} _0 $

\left.\frac{\partial f(\boldsymbol{x})}{\partial \boldsymbol{x}}\right |_{\boldsymbol{x}=\boldsymbol{x}_0}= 0\\

\left.\frac{\partial^2 f(\boldsymbol{x}+\boldsymbol{b}t)}{\partial t^2}\right |_{\boldsymbol{x}=\boldsymbol{x}_0, t=0} > 0\\

\left.\frac{\partial^2 f(\boldsymbol{x}+\boldsymbol{c}t)}{\partial t^2}\right |_{\boldsymbol{x}=\boldsymbol{x}_0, t=0} < 0

Ist festgelegt.

Betrachten Sie als Beispiel $ y = x_1 ^ 2-x_2 ^ 2 $. Bei $ x_1 = 0 $, $ x_2 = 0 $ wird der Gradient zu $ 0 $ und bei $ \ boldsymbol {b} = (1, 0) ^ \ rm {T} $ ist $ y = (0 + 1 t) ^ 2- (0 + 0 t) ^ 2 = t ^ 2 $ nimmt einen Mindestwert bei $ t = 0 $ und $ y = bei $ \ boldsymbol {c} = (0, 1) ^ \ rm {T} $ an (0 + 0 t) ^ 2- (0 + 1t) ^ 2 = -t ^ 2 $ nimmt den Maximalwert bei $ t = 0 $ an. Daher kann dieser Punkt als Sattelpunkt geschätzt werden.

3. Sattelpunktsuche

Diese Methode besteht aus zwei Schritten: Initialisierung und Exploration. Bei der Initialisierung werden die entsprechenden Anfangswerte für $ \ boldsymbol {b} $ und $ \ boldsymbol {c} $ gefunden. Bei der Suche werden die Sattelpunkte nach dem Gradienten durchsucht.

3.1 Initialisierung

Wie oben erwähnt, entspricht $ \ boldsymbol {b} $ dem Maximalwert und $ \ boldsymbol {c} $ dem Minimalwert. Bestimmen Sie zunächst $ \ boldsymbol {b} $, das die Differenzierung zweiter Ordnung von $ y = f (\ boldsymbol {x} + \ boldsymbol {b} t) $ in Bezug auf $ t $ maximiert. Der Einfachheit halber werden wir die Wiederholungsmethode unter Verwendung der Re-Deep-Methode verwenden. Die Formel lautet wie folgt.

\mathrm{grad}\ \boldsymbol{b}_1 \leftarrow \frac{1}{\delta} \left( \nabla f \left(\boldsymbol{x}+\delta \boldsymbol{b} \right) - \nabla f \left(\boldsymbol{x}-\delta \boldsymbol{b} \right) \right)\\

\mathrm{grad}\ \boldsymbol{b}_2 \leftarrow \mathrm{grad}\ \boldsymbol{b}_1 - \left( \boldsymbol{b} \cdot \mathrm{grad}\ \boldsymbol{b}_1 \right)\boldsymbol{b}\\

\boldsymbol{b} \leftarrow \boldsymbol{b} + \epsilon_1 \ \mathrm{grad}\ \boldsymbol{b}_2\\

\boldsymbol{b} \leftarrow \frac{\boldsymbol{b}}{\mathrm{norm} \left(\boldsymbol{b}\right)}\\

Der Minutenbetrag ist $ \ delta $ und die Lernrate ist $ \ epsilon_1 $. Die erste Gleichung ist die Differenzierung des euklidischen Raums der $ n $ -Dimension in Bezug auf die Basis. Als Gerät wurde die Formel so transformiert, dass der Gradient verwendet werden konnte. Wenn dies so wie es ist als Aktualisierungsbetrag verwendet wird, ist es für den Einheitsvektor $ \ boldsymbol {b} $ nicht geeignet, daher ist es notwendig, ihn in den Aktualisierungsbetrag von $ \ boldsymbol {b} $ entlang der Einheitskugel in der zweiten Gleichung umzuwandeln. es gibt. Die dritte Formel wird auf den Maximalwert aktualisiert, und die vierte Formel wird standardisiert, um sie zu einem Einheitsvektor zu machen. In ähnlicher Weise bestimmen Sie $ \ boldsymbol {c} $ so, dass das Differential zweiter Ordnung von $ y = f (\ boldsymbol {x} + \ boldsymbol {c} t) $ in Bezug auf $ t $ maximiert wird. Die Formel lautet wie folgt.

\mathrm{grad}\ \boldsymbol{c}_1 \leftarrow \frac{1}{\delta} \left( \nabla f \left(\boldsymbol{x}+\delta \boldsymbol{c} \right) - \nabla f \left(\boldsymbol{x}-\delta \boldsymbol{c} \right) \right)\\

\mathrm{grad}\ \boldsymbol{c}_2 \leftarrow \mathrm{grad}\ \boldsymbol{c}_1 - \left( \boldsymbol{c} \cdot \mathrm{grad}\ \boldsymbol{c}_1 \right)\boldsymbol{c}\\

\boldsymbol{c} \leftarrow \boldsymbol{c} - \epsilon_1 \ \mathrm{grad}\ \boldsymbol{c}_2\\

\boldsymbol{c} \leftarrow \frac{\boldsymbol{c}}{\mathrm{norm} \left(\boldsymbol{c}\right)}

Der Unterschied zu $ \ boldsymbol {b} $ besteht darin, dass es in Richtung des Minimalwerts in der dritten Gleichung aktualisiert wird. Sie können $ \ mathrm {grad} \ \ boldsymbol {b} \ _2 $ und $ \ mathrm {grad} \ \ boldsymbol {c} \ _2 $ als Konvergenzurteile verwenden.

3.2 Sattelpunktsuche

Die Suche verwendet $ \ mathrm {grad} \ \ boldsymbol {b} \ _2 $ und $ \ mathrm {grad} \ \ boldsymbol {c} \ _2 $. Dies liegt daran, dass es einen Minimalwert in Richtung $ - \ mathrm {grad} \ \ boldsymbol {b} \ _2 $ und einen Maximalwert in Richtung $ \ mathrm {grad} \ \ boldsymbol {c} \ _2 $ gibt. Sie können den Sattelpunkt erreichen, indem Sie entsprechend aktualisieren. Die Formel lautet wie folgt.

\boldsymbol{x} \leftarrow \boldsymbol{x} + \epsilon_2 \ \left( -\mathrm{grad}\ \boldsymbol{b}_2 +\mathrm{grad}\ \boldsymbol{c}_2 \right)

Außerdem haben sich $ \ mathrm {grad} \ \ boldsymbol {b} _2 $ und $ \ mathrm {grad} \ \ boldsymbol {c} _2 $ gemäß der Aktualisierung von $ \ boldsymbol {x} $ geändert, also Initialisierung Sie müssen auch $ \ boldsymbol {b} $ und $ \ boldsymbol {c} $ gleichzeitig ausführen.

4. Implementierung

Die Sattelpunkte verschiedener Funktionen wurden gemäß dem obigen Algorithmus abgeleitet. Die Update-Methode verwendete die Re-Dive-Methode und wurde in Python ausgeführt. Die rote Linie ist der Minimalwertvektor und die grüne Linie ist der Maximalwertvektor.

・ Funktion $ y = x_1 ^ 2-x_2 ^ 2 $ Anfangswert $ x_1 = -2 $, $ x_2 = -1 $ Kleiner Betrag $ \ delta = 0,001 $ Lernrate $ \ epsilon_1 = 0,1 $, $ \ epsilon_1 = 0,1 $ Ergebnis Sattelpunkt $ x_1 = -0.0003 $, $ x_2 = -0.001 $  \boldsymbol{b}=(1,0)^\rm{T}\boldsymbol{c}=(0,1)^\rm{T}

Initialisieren

Sattelpunktsuche

・ Funktion $ y = x_1 ^ 2 + x_2 ^ 3-x_2 $ Anfangswert $ x_1 = -2 $, $ x_2 = -0,5 $ Kleiner Betrag $ \ delta = 0,05 $ Lernrate $ \ epsilon_1 = 0,1 $, $ \ epsilon_1 = 0,1 $ Ergebnis Sattelpunkt $ x_1 = -0.0011 $, $ x_2 = -0.5774 $  \boldsymbol{b}=(1,0)^\rm{T}\boldsymbol{c}=(0,1)^\rm{T}

Initialisieren

Sattelpunktsuche

5. Herausforderungen

Als Verbesserung können, da es sich um eine Gradientenmethode handelt, verschiedene Optimierer (z. B. Momentum, RMSProp, Adam, RAdam) und Wegstain-Methoden in der konjugierten Gradientenmethode und beim maschinellen Lernen verwendet werden. Das Problem ist, dass es nicht stabil ist. Ich fragte mich, ob es für die Sattelpunktsuche verwendet werden könnte, die für die Vorhersage chemischer Reaktionen verwendet werden kann, aber es konvergierte mit einer seltsamen Struktur. Abhängig vom Anfangswert kann es auch sein, dass es nicht zum Sattelpunkt konvergiert. Ein Beispiel ist unten gezeigt. Dies unterscheidet sich vom Anfangswert im vorherigen Beispiel.

・ Funktion $ y = x_1 ^ 2 + x_2 ^ 3-x_2 $ Anfangswert $ x_1 = -2 $, $ x_2 = -0,5 $ Kleiner Betrag $ \ delta = 0,05 $ Lernrate $ \ epsilon_1 = 0,1 $, $ \ epsilon_1 = 0,1 $

Initialisieren

Sattelpunktsuche

In diesem Beispiel wurden $ \ boldsymbol {b} $ und $ \ boldsymbol {c} $ aktualisiert, sodass die Richtung von $ x_2 $ den Minimalwert und die Richtung von $ x_1 $ den Maximalwert hat. Während wir auf den Minimalwert der kubischen Funktion aktualisieren, steigen wir daher stetig die Steigung der quadratischen Funktion an.

6. Fazit

In diesem Artikel haben wir mit der Gradientenmethode nach Sattelpunkten gesucht. Zur Veranschaulichung wird ein Beispiel für eine Funktion mit zwei Variablen gezeigt. Sie können jedoch auch eine beliebige Variablenfunktion verwenden. Wenn Sie Fragen haben, werden wir in den Kommentaren antworten. Fühlen Sie sich frei zu kommentieren, wenn Sie irgendwelche Anfragen nach Formeltransformationen oder Quellcode haben.

7. Quellcode (quadratische Funktion)

In "Berechnung 1 Initialisierung" gibt es Einstellungen wie Funktionen, Anfangswerte und Lernrate. Sie können den Inhalt der Klasse SDG in verschiedene Optimierer ändern.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from datetime import datetime
np.set_printoptions(precision=4, floatmode='maxprec')

class SDG:
    def __init__(self, learning_rate):
        self.learning_rate = learning_rate
        
    def solve(self, coord, gradient):
        return coord - self.learning_rate*gradient

class SaddlePoint:
    
    def __init__(self, function, gradient, coordinate, delta=1.0e-3,
                 learning_rate=0.5, max_iteration=1000,
                 judgment1=1.0e-8, judgment2=1.0e-8, log_span=100):
        """
Initialisierungskonstruktor
        function --Zielfunktion
        differential --Funktionsdifferenzierung erster Ordnung
        coordinates --Anfangskoordinaten
        delta --Kleiner Wert
        learning_rate --Lernrate
        judgment --Konvergenzurteil 1
        judgment --Konvergenzurteil 2
        log_span --Protokollanzeigeintervall
        """
        self.function = function
        self.gradient = gradient
        self.coordinate = coordinate.copy()
        self.dim = len(coordinate)
        self.delta = delta
        self.learning_rate = learning_rate
        self.max_iteration = max_iteration
        self.judgment1 = judgment1
        self.judgment2 = judgment2
        self.log_span = log_span
        
        #Basisvektor
        self.b = np.random.rand(self.dim)
        self.b /= np.linalg.norm(self.b)
        self.c = np.random.rand(self.dim)
        self.c /= np.linalg.norm(self.c)
        
        # SDG
        self.sdg_b_init = SDG(learning_rate)
        self.sdg_c_init = SDG(learning_rate)
        self.sdg_b_solv = SDG(learning_rate)
        self.sdg_c_solv = SDG(learning_rate)
        self.sdg_a_solv = SDG(learning_rate)
        
    def initialize(self):
        """
Funktion zum Initialisieren. Geeignet b,Bestimmen Sie c
Rückgabewert--Minimalwert Richtungsvektor b,Maximalwert Richtungsvektor c
        """
        #Steigung
        gradient = self.gradient
        #Koordinate b
        coordinate = self.coordinate
        #Basisvektor
        b = self.b.copy()
        c = self.c.copy()
        #Betrag aktualisieren
        diff_b = np.zeros_like(b)
        diff_c = np.zeros_like(c)
        #Lernrate
        learning_rate = self.learning_rate
        #Kleiner Wert
        delta = self.delta
        #Standardisierung
        norm = np.linalg.norm
        #Beurteilung
        judgement1 = self.judgment1
        #Protokollintervall
        log_span = self.log_span
        # SDG
        sdg_b = self.sdg_b_init
        sdg_c = self.sdg_c_init
        
        z, _ = gradient(coordinate)
        
        print("-----Initialization of b has started.-----")
        for i in range(self.max_iteration):
            #Differential erster Ordnung
            z_b1, grad_b1 = gradient(coordinate + delta*b)
            z_b2, grad_b2 = gradient(coordinate - delta*b)
            #Betragsberechnung ändern
            nabla_b = (grad_b1 - grad_b2)/delta
            grad_b = nabla_b - (np.dot(b, nabla_b))*b
            #aktualisieren
            b = sdg_b.solve(b, -grad_b)
            #Standardisierung
            b /= norm(b)
            #Konvergenzurteil
            error = np.linalg.norm(grad_b)
            if i%log_span == 0:
                print("Iteration = {}, Error = {}".format(i, error))
            if error < judgement1:
                print("Converged! Iteration = {}, Error = {}".format(i, error))
                break
        self.b = b.copy()
        
        print()
        print("-----Initialization of c has started.-----")
        for i in range(self.max_iteration):
            #Gradientenberechnung
            z_c1, grad_c1 = gradient(coordinate + delta*c)
            z_c2, grad_c2 = gradient(coordinate - delta*c)
            #Betragsberechnung ändern
            nabla_c = (grad_c1 - grad_c2)/delta
            grad_c = nabla_c - (np.dot(c, nabla_c))*c
            #aktualisieren
            c = sdg_c.solve(c, grad_c)
            #Standardisierung
            c /= norm(c)
            #Konvergenzurteil
            error = np.linalg.norm(grad_c)
            if i%log_span == 0:
                print("Iteration = {}, Error = {}".format(i, error))
            if error < judgement1:
                print("Converged! Iteration = {}, Error = {}".format(i, error))
                break
        self.c = c.copy()
        
        print()
        print("Result")
        print("b = {}".format(self.b))
        print("c = {}".format(self.c))
        print()
        return self.b, self.c
    
    def solve(self):
        """
Suche nach Sattelpunkten
Rückgabewert--Sattelpunktkoordinaten koordinieren,Minimalwert Richtungsvektor b,Maximalwert Richtungsvektor c
        """
        #Steigung
        gradient = self.gradient
        #Koordinaten, eine Sammlung von Koordinaten
        coordinate = self.coordinate.copy()
        coordinate_Array = coordinate.copy()
        #Basisvektor
        b = self.b.copy()
        c = self.c.copy()
        #Betrag aktualisieren
        diff_b = np.zeros_like(b)
        diff_c = np.zeros_like(c)
        #Lernrate
        learning_rate = self.learning_rate
        #Kleiner Wert
        delta = self.delta
        #Standardisierung
        norm = np.linalg.norm
        #Beurteilung
        judgement1 = self.judgment1
        judgement2 = self.judgment2
        #Protokollintervall
        log_span = self.log_span
        # SDG
        sdg_a = self.sdg_a_solv
        sdg_b = self.sdg_b_solv
        sdg_c = self.sdg_c_solv
        
        print("-----Saddle-point solver has started.-----")
        for i in range(self.max_iteration):
            #Differential erster Ordnung
            z_b1, grad_b1 = gradient(coordinate + delta*b)
            z_b2, grad_b2 = gradient(coordinate - delta*b)
            z_c1, grad_c1 = gradient(coordinate + delta*c)
            z_c2, grad_c2 = gradient(coordinate - delta*c)
            grad_through_b = (z_b1-z_b2) / (2.0*delta)
            grad_through_c = (z_c1-z_c2) / (2.0*delta)
            #Differential zweiter Ordnung
            z, _ = gradient(coordinate)
            grad2_through_b = (z_b1-2.0*z+z_b2) / delta**2.0
            grad2_through_c = (z_c1-2.0*z+z_c2) / delta**2.0
            
            #aktualisieren
#            coordinate = sdg_a.solve(coordinate,
#                                     grad_through_b*b/(np.linalg.norm(grad_through_b)+np.linalg.norm(grad2_through_b))
#                                     -grad_through_c*c/(np.linalg.norm(grad_through_c)+np.linalg.norm(grad2_through_c)))
            coordinate = sdg_a.solve(coordinate, grad_through_b*b - grad_through_c*c)
            coordinate_Array = np.vstack([coordinate_Array, coordinate])
            #Konvergenzurteil
            error_coordinate = np.linalg.norm(grad_through_b**2 + grad_through_c**2)
            
            # b,Aktualisierung von c
            nabla_b = -(grad_b1 - grad_b2)/delta
            grad_b = nabla_b - (np.dot(b, nabla_b))*b
            #aktualisieren
            b = sdg_b.solve(b, grad_b)
            #Standardisierung
            b /= norm(b)
            #Konvergenzurteil
            error_b = np.linalg.norm(grad_b)
            
            nabla_c = (grad_c1 - grad_c2)/delta
            grad_c = nabla_c - (np.dot(c, nabla_c))*c
            #aktualisieren
            c = sdg_c.solve(c, grad_c)
            #Standardisierung
            c /= norm(c)
            #Konvergenzurteil
            error_c = np.linalg.norm(grad_c)
            
            if i%log_span == 0:
                print("B converged! Iteration = {}, Error = {}".format(i, error_b))
                print("C converged! Iteration = {}, Error = {}".format(i, error_c))
                print("Iteration = {}, Error = {}".format(i, error_coordinate))
                print()
            if error_coordinate < judgement2:
                print("Converged! Iteration = {}, Error = {}".format(i, error_coordinate))
                break
        
        self.coordinate = coordinate.copy()
        self.b = b.copy()
        self.c = c.copy()
        
        print()
        print("Result")
        print("coordinate = {}".format(self.coordinate))
        print("b = {}".format(self.b))
        print("c = {}".format(self.c))
        print()
        return self.coordinate, coordinate_Array, self.b, self.c
# =============================================================================
#Berechnung 1 Initialisierung
# =============================================================================
def f(x):
    #Funktion
    return x[0]**2 - x[1]**2

def gradient_f(x):
    #Funktionsdifferenzierung erster Ordnung
    return f(x), np.array([2*x[0], -2*x[1]])

x_init = np.array([-2.0, -1.0], dtype="float")

saddlePoint = SaddlePoint(f, gradient_f, x_init, delta=1e-3,
                          learning_rate=0.1, max_iteration=100,
                          judgment1=1.0e-5, judgment2=1.0e-5, log_span=1)

b, c = saddlePoint.initialize() #Initialisieren

# =============================================================================
#Diagrammzeichnung(2D)
# =============================================================================
t = np.linspace(-1.0, 1.0, 100)
tb = np.linspace(x_init-1.0*b, x_init+1.0*b, 100)
tc = np.linspace(x_init-1.0*c, x_init+1.0*c, 100)
fb = f(tb.T)
fc = f(tc.T)
plt.xlabel("t")
plt.ylabel("z")
plt.plot(t, fb, c="red")
plt.plot(t, fc, c="green")
plt.savefig("file/" + str(datetime.now().strftime("%Y_%m_%d_%H_%M_%S")) + "_2d1.png ", dpi=300)
plt.show()

# =============================================================================
#Diagrammzeichnung(3D)
# =============================================================================
#Drahtrahmen
fig = plt.figure(figsize=(6, 6))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
X = np.linspace(-2.5, 2.5, 50)
Y = np.linspace(-2.5, 2.5, 50)
X, Y = np.meshgrid(X, Y)
Z = f([X,Y])

#Basisvektor
width = 1.0
bt = np.linspace(x_init-width*b,x_init+width*b,10)
bz = f(bt.T)
ct = np.linspace(x_init-width*c,x_init+width*c,10)
cz = f(ct.T)

#Flugbahn
zArray = f(x_init)
#Anzeige
ax.plot_wireframe(X,Y,Z,color="gray",linewidth=0.2) #Drahtrahmen
ax.plot(bt[:,0],bt[:,1],bz,color="red") #Minimal
ax.plot(ct[:,0],ct[:,1],cz,color="green") #maximal
ax.scatter(x_init[0],x_init[1],f(x_init),color="blue") #Flugbahn
plt.savefig("file/" + str(datetime.now().strftime("%Y_%m_%d_%H_%M_%S")) + "_3d1.png ", dpi=300)
plt.show()

# =============================================================================
#Berechnung 2 Sattelpunktsuche
# =============================================================================
x, xArray, b, c = saddlePoint.solve() #Sattelpunktberechnung

# =============================================================================
#Diagrammzeichnung(2D)
# =============================================================================
t = np.linspace(-1.0, 1.0, 100)
tb = np.linspace(x-1.0*b, x+1.0*b, 100)
tc = np.linspace(x-1.0*c, x+1.0*c, 100)
fb = f(tb.T)
fc = f(tc.T)
plt.xlabel("t")
plt.ylabel("z")
plt.plot(t, fb, c="red")
plt.plot(t, fc, c="green")
plt.savefig("file/" + str(datetime.now().strftime("%Y_%m_%d_%H_%M_%S")) + "_2d2.png ", dpi=300)
plt.show()

# =============================================================================
#Diagrammzeichnung(2D)
# =============================================================================
#Drahtrahmen
fig = plt.figure(figsize=(6, 6))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
X = np.linspace(-2.5, 2.5, 50)
Y = np.linspace(-2.5, 2.5, 50)
X, Y = np.meshgrid(X, Y)
Z = f([X,Y])

#Basisvektor
width = 1.0
bt = np.linspace(x-width*b,x+width*b,10)
bz = f(bt.T)
ct = np.linspace(x-width*c,x+width*c,10)
cz = f(ct.T)

#Flugbahn
zArray = f(xArray.T)

#Anzeige
ax.plot_wireframe(X,Y,Z,color="gray",linewidth=0.2) #Drahtrahmen
ax.plot(bt[:,0],bt[:,1],bz,color="red") #Minimal
ax.plot(ct[:,0],ct[:,1],cz,color="green") #maximal
ax.scatter(xArray[:,0],xArray[:,1],zArray,color="blue") #Flugbahn
ax.text(xArray[0,0],xArray[0,1],zArray[0], "start")
ax.text(xArray[-1,0],xArray[-1,1],zArray[-1], "goal")
plt.savefig("file/" + str(datetime.now().strftime("%Y_%m_%d_%H_%M_%S")) + "_3d2.png ", dpi=300)
plt.show()

Recommended Posts

Sattelpunktsuche mit der Gradientenmethode
Denken Sie grob über die Gradientenabstiegsmethode nach
Versuchen Sie die Clusteranalyse mit K-Mitteln
Sekundärplanungsmethode nach interner Punktmethode
Suche nach Adsorptionsstruktur mit der Minima-Hopping-Methode
Implementierung der Gradientenmethode 1
Generieren Sie Hash-Werte mit der HMAC-Methode.
Approximieren Sie eine Bezier-Kurve durch einen bestimmten Punkt mit der Methode der kleinsten Quadrate in Python
Berechnung der kürzesten Route nach der Monte-Carlo-Methode
Bestimmen Sie den Schwellenwert mithilfe der P-Tile-Methode in Python
Ich habe versucht, EKG-Daten mit der K-Shape-Methode zu gruppieren
Verwenden Sie die Such-API der National Parliament Library in Python
Liste der Gradientenabstiegsmethoden (2020)
Suchen Sie Twitter mit Python
Methodenaufruf mit __getattr__
Probieren Sie die ähnliche Suche von Image Search mit Python SDK [Search] aus.
[Python] LASSO-Regression mit Gleichungsbeschränkung unter Verwendung der Multiplikatormethode
Geben Sie das Ergebnis der Gradientenabstiegsmethode als Matplotlib-Animation aus