내 신경망에 대한 후속 조치로 유클리드 거리를 알 수조차 없으므로 나는 더 단순화하고 단일 ReLU (임의의 무게로)를 단일 ReLU로 훈련하려고했습니다. 이것은 가장 간단한 네트워크이지만 수렴하지 못하는 시간의 절반입니다.
초기 추측이 목표와 같은 방향에 있다면, 빠르게 학습하고 올바른 가중치 1로 수렴합니다.
초기 추측이 "뒤로"이면, 가중치 0에 갇히고 더 낮은 손실 영역으로 넘어 가지 않습니다.
왜 그런지 모르겠습니다. 그라디언트 하강이 손실 곡선을 쉽게 따라 가면 안될까요?
예제 코드 :
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()
바이어스를 추가하면 비슷한 일이 발생합니다 .2D 손실 기능은 부드럽고 간단하지만 relu가 거꾸로 시작하면 주위를 맴돌고 붙어 (빨간색 시작점) 기울기를 따라 가지 않습니다. 파란색 시작점에 해당) :
출력 무게와 바이어스를 추가하면 비슷한 일이 발생합니다. (왼쪽에서 오른쪽으로 또는 아래에서 위로 뒤집지 만 둘다는 아닙니다.)