Anpassungsübung

Home PDF

Als nächstes versuchen wir, die Funktion y(x) = ax + b anzupassen.

import numpy as np
import math

x = np.linspace(-math.pi, math.pi, 20)

print(x)
[-3.14159265 -2.81089869 -2.48020473 -2.14951076 -1.8188168  -1.48812284
 -1.15742887 -0.82673491 -0.49604095 -0.16534698  0.16534698  0.49604095
  0.82673491  1.15742887  1.48812284  1.8188168   2.14951076  2.48020473
  2.81089869  3.14159265]

Beachte, dass es linspace heißt, nicht linespace. Dies ist ein Teil des Codes aus einem Beispiel in den PyTorch-Tutorials. Diese Dezimalzahlen sind möglicherweise nicht sehr intuitiv.

x = np.linspace(0, 100, 20)
import numpy as np
import math
x = np.linspace(0, 100, 20)
y = np.linspace(0, 100, 20)
print(x)
print(y)

So erhalten wir zwei Datensätze. Wie können wir diese grafisch darstellen?

Linie

Allerdings sind x und y tatsächlich gleich.

x = np.random.rand(2)
print(x)
[0.06094295 0.89674607]

Weiter geht’s mit den Änderungen.

x = np.random.rand(2)*100
print(x)
[39.6136151  66.15534011]

Weiter bearbeiten.

import numpy as np
import math
import matplotlib.pyplot as plt
x = np.random.rand(10)*100
y = np.random.rand(10)*100
plt.plot(x,y)
plt.show()

xy1

[20.1240488  59.69327146 58.05432614  3.14092909 82.86411091 43.23010476
 88.09796699 94.42222486 58.45253048 51.98479507]
[58.7129098   1.6457994  49.34115933 71.13738592 53.09736099 15.4485691
 45.12200319 20.46080549 67.48555147 91.10864978]

Es ist sichtbar, dass der Pfad von (20.1,58.7) nach (59.7,1.6) und dann nach (58,49.3) verläuft. Obwohl das Diagramm chaotisch aussieht, gibt es dennoch eine Regelmäßigkeit. Es handelt sich um einen durchgehenden Strich.

import numpy as np
import math
import matplotlib.pyplot as plt
x = np.random.rand(2)*100
y = np.random.rand(2)*100
print(x)
print(y)
plt.plot(x,y)
plt.show()

x1

y11

Beachte, dass die Skalen von x und y sich ständig ändern. Daher sind zwei scheinbar identische Geraden tatsächlich unterschiedlich. Wie können wir also a und b in der Gleichung y(x) = ax + b bestimmen? Angenommen, wir kennen zwei Punkte auf dieser Geraden. Beachte, dass wir dies einfach auf einem Schmierblatt lösen können. Subtrahiere die beiden Gleichungen, eliminiere b und bestimme a. Setze dann a in eine der Gleichungen ein, um b zu berechnen.

Kann man jedoch eine Vermutungsmethode verwenden? Mit der binären Suche. Lass es uns ausprobieren.

import numpy as np
import math
import matplotlib.pyplot as plt
x = np.random.rand(2)*100
y = np.random.rand(2)*100
a_max = 1000
a_min = -1000
b_max = 1000
b_min = -1000
def cal_d(da, b):
    y0 = x[0] * da + b
    y1 = x[1] * da + b
    d = abs(y0 - y[0]) + abs(y1 - y[1])
    return d
def cal_db(a, db):
    y0 = x[0] * a + db
    y1 = x[1] * a + db
    d = abs(y0 - y[0]) + abs(y1 - y[1])
    return d

Hinweis: Der Code scheint eine Funktion zu definieren, die den absoluten Unterschied zwischen den berechneten Werten y0 und y1 und den gegebenen Werten y[0] und y[1] berechnet. Es ist jedoch unklar, woher die Variablen x und y stammen, da sie nicht als Parameter übergeben werden.

def avg_a():
    return (a_max + a_min) / 2
def avg_b():
    return (b_max + b_min) / 2
for i in range(100):
    a = avg_a()
    b = avg_b()
    max_d = cal_d(a_max, b)
    min_d = cal_d(a_min, b)
    if max_d < min_d:
        a_min = a
    else:
        a_max = a
    
    a = avg_a()
    max_db = cal_db(a, b_max)
    min_db = cal_db(a, b_min)
    if max_db < min_db:
        b_min = b        
    else:
        b_max = b
print(x)
print(y)
print('a = ', avg_a())
print('b = ', avg_b())
print(avg_a() * x[0] + avg_b())
print(avg_a() * x[1] + avg_b())

Führe es aus.

[42.78912791 98.69284173]
[68.95535212 80.89946202]
a =  11.71875
b =  -953.125
-451.68990725289063
203.4317390671779

Die Ergebnisse wichen jedoch stark voneinander ab.

Lassen Sie uns das Problem vereinfachen. Angenommen, y(x) = ax. Gegeben sei eine Menge von x, y. Wir sollen a bestimmen. Obwohl wir es direkt berechnen könnten, lassen Sie uns raten.

import numpy as np
import math
import matplotlib.pyplot as plt
from numpy.random import rand, randint
x = randint(100)
y = randint(100)
a_max = 1000
a_min = -1000
def cal_d(da):
    y0 = x * da
    return abs(y0 - y)
def avg_a():
    return (a_max + a_min) / 2
for i in range(1000):
    a = avg_a()
    max_d = cal_d(a_max)
    min_d = cal_d(a_min)
    if max_d < min_d:
        a_min = a
    else:
        a_max = a
print(x)
print(y)
print(avg_a())
print(avg_a()*x)

结果是令人欣喜的。猜测非常准确。

96
61
0.6354166666666667
61.00000000000001

Allerdings schreibt man normalerweise for i in range(15):, was bedeutet, dass 15 Iterationen ziemlich genau sind. Warum? Beachten Sie, dass unsere x und y beide im Bereich von 0 bis 100 liegen. Daher liegt auch der Wert von a im Bereich von 0 bis 100. Zum Beispiel x=1, y=99 und x=99, y=1. Daher können die Anfangswerte von a_min und a_max optimiert werden. Beachten Sie, dass 1/99 gleich 0.01 ist. Daher reicht eine Genauigkeit von bis zu 0.01 aus, was ungefähr 2^n entspricht, das etwa 10000 ist. log2(10000)=13.28. Das bedeutet, dass eine Einstellung von etwa 14 ausreichend ist.


Back 2025.01.18 Donate