Als Folge dessen, dass mein neuronales Netzwerk nicht einmal die euklidische Distanz lernen kann, vereinfachte ich noch mehr und versuchte, eine einzelne ReLU (mit zufälliger Gewichtung) zu einer einzelnen ReLU zu trainieren. Dies ist das einfachste Netzwerk, das es gibt, und dennoch scheitert die Konvergenz in der Hälfte der Zeit.
Wenn die anfängliche Vermutung mit der Ausrichtung des Ziels übereinstimmt, lernt es schnell und nähert sich dem korrekten Gewicht von 1 an:
Wenn die anfängliche Vermutung "rückwärts" ist, bleibt sie bei einer Gewichtung von Null stecken und gelangt niemals in den Bereich mit geringerem Verlust:
Ich verstehe nicht warum. Sollte der Gefälleverlauf nicht einfach der Verlustkurve bis zu den globalen Minima folgen?
Beispielcode:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, ReLU
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
batch = 1000
def tests():
while True:
test = np.random.randn(batch)
# Generate ReLU test case
X = test
Y = test.copy()
Y[Y < 0] = 0
yield X, Y
model = Sequential([Dense(1, input_dim=1, activation=None, use_bias=False)])
model.add(ReLU())
model.set_weights([[[-10]]])
model.compile(loss='mean_squared_error', optimizer='sgd')
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.losses = []
self.weights = []
self.n = 0
self.n += 1
def on_epoch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))
w = model.get_weights()
self.weights.append([x.flatten()[0] for x in w])
self.n += 1
history = LossHistory()
model.fit_generator(tests(), steps_per_epoch=100, epochs=20,
callbacks=[history])
fig, (ax1, ax2) = plt.subplots(2, 1, True, num='Learning')
ax1.set_title('ReLU learning ReLU')
ax1.semilogy(history.losses)
ax1.set_ylabel('Loss')
ax1.grid(True, which="both")
ax1.margins(0, 0.05)
ax2.plot(history.weights)
ax2.set_ylabel('Weight')
ax2.set_xlabel('Epoch')
ax2.grid(True, which="both")
ax2.margins(0, 0.05)
plt.tight_layout()
plt.show()
Ähnliche Dinge passieren, wenn ich die Verzerrung hinzufüge: Die 2D-Verlustfunktion ist glatt und einfach, aber wenn das Relu verkehrt herum startet, dreht es sich und bleibt hängen (rote Startpunkte) und folgt dem Gefälle nicht bis zum Minimum (wie es ist) gilt für blaue Startpunkte):
Ähnliches passiert, wenn ich Output Weight und Bias hinzufüge. (Es wird von links nach rechts oder von unten nach oben gewendet, aber nicht von beiden.)