Experimentell lässt sich am Programmbeispiel leicht zeigen, dass die niedrige Lernrate von alpha = 0.01 von den großen Werten des Features "Durchschnittliche Anzahl der Zehen pro Spieler" toes bedingt wird. Bei alpha = 0.1 divergiert das KNN:

0. loop: weights=[ 0.1     0.2    -0.1]    pred=0.86   delta=-0.14  -> weight_deltas=[-1.19     -0.091   -0.168]
1. loop: weights=[ 0.219   0.2091 -0.0832] pred=1.898 delta= 0.8976 -> weight_deltas=[7.62939 0.58342 1.07709]  
2. loop: weights=[-0.5439  0.1508 -0.1909] pred=-4.755 delta=-5.755 -> weight_deltas=[-48.91391 -3.74048 -6.90549]

Werden diese Daten durch 10 geteilt befinden sich diese Daten im Bereich der beiden anderen Features "Gewinnerwartung" und "Zahl der Fans in Millionen".

 1  
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np

weights = np.array([0.1, 0.2, -0.1])
def neural_network(input, weights):
    pred = input.dot(weights)  # replaces w_sum(a,b)
    return pred
    
toes =  np.array([0.85, 0.95, 0.9, 0.9]) # normalized data
wlrec = np.array([0.65, 0.8, 0.8, 0.9])
nfans = np.array([1.2, 1.3, 0.5, 1.0])

# Input is the first game of the season.
input = np.array([toes[0],wlrec[0],nfans[0]])

# first game: 1 => win
win_or_lose_binary = [1, 1, 0, 1]

alpha = 0.1  # increased learning rate

for i in range(3):
    pred = neural_network(input,weights)
    delta = pred - win_or_lose_binary[0]    # one delta
    weight_deltas = input * delta           # but three weight_deltas (weighted by input)
    print(f'{i}. loop: weights={np.array2string(weights, precision=4)} pred={pred:.4} delta={delta:.4} -> weight_deltas={np.array2string(weight_deltas, precision=5)}')
    weights = weights - alpha * weight_deltas       # 3 new weights


Jetzt lässt sich die Lernrate dementsprechend auf alpha = 0.1 erhöhen und das KNN konvergiert trotzdem wieder:

0. loop: weights=[0.1    0.2   -0.1]    pred=0.095  delta=-0.905  -> weight_deltas=[-0.76925 -0.58825 -1.086  ]
1. loop: weights=[0.1769 0.2588 0.0086] pred=0.3289 delta=-0.6711 -> weight_deltas=[-0.5704  -0.43619 -0.80527]
2. loop: weights=[0.234  0.3024 0.0891] pred=0.5024 delta=-0.4976 -> weight_deltas=[-0.42295 -0.32343 -0.59711]

(Das KNN konvergiert sogar bis zu einer Lernrate von alpha = 0.41.)

Normalisierung

Die Anpassung der Dateneingaben auf ähnliche Wertebereiche wird als Normalisierung bezeichnet. Ein KNN mit normalisierten Daten konvergiert besser und schneller.

(Es gibt hierfür verschiedene mathematische Verfahren, auf die an dieser Stelle nicht eingegangen wird. Weitere Informationen finden sich z.B. hier:
https://towardsdatascience.com/data-normalization-in-machine-learning-395fdec69d02   (3.10.2022))


Fehlerflächen

Tatsächlich sind die Fehlerkurven nur kleine Ausschnitte bzw. 2-dimensionale Schnitte aus Fehlerflächen, deren Komplexität durch die Trainingsdaten und deren Gewichte festgelegt werden. Unter Umständen finden man nicht die absoluten Tiefpunkte mit der Steigung 0 in diesen eventuell sehr zerklüfteten Flächen, sondern nur lokale Tiefpunkte. Interessante Darstellungen finden sich dazu z.B. hier:
https://ml4a.github.io/ml4a/how_neural_networks_are_trained/    (04.10.2022)

Last modified: Wednesday, 30 November 2022, 8:12 AM