При обучении нейросети получаются огромные числа, который python воспринимает как null, inf и не может продолжать вычисления
обучаю нейросеть определять цифры на изображениях 24*24 px.
Принципиальное условие: не использовать библиотеки tensorflow, keras...
По мере того, как выполняется код, в промежуточных слоях нейросети получаются огромные числа, которые python воспринимает как nan и inf. После чего у него не получается выполнять дальнейшие действия.
Вот пара мест, где происходит эта проблема:
1. Функция нормировки(применяется только к последнему слою нейросети):
def SoftMax(self, t2):
out = np.exp(t2)
return out/np.sum(out)
Насколько я поимаю тут появляются inf, т.е. бесконечно большие числа.
2. Для вычисления ошибки используется категориальная кросс-энтропия.
def CrossEntropy(self):
error = np.log(self.res_vector[np.argmax(self.y)])
return error
Насколько я понимаю тут порой появляются nan, т.е. бесконечно малые числа.
3. Далее пытаюсь выполнить градиентный шаг, а там inf и nan уже лежат:
# Вручную вычисляем градиенты на каждом слое и корректируем веса.
def back_propogation(self):
dE_dt = self.res_vector - self.y
i = self.N-2
while i >= 0:
if i > 0:
dE_dw = self.H[i][None, ...].T @ dE_dt[None, ...]
dE_db = dE_dt
alpha = 0.001
self.M[i+1] += alpha * dE_dw
self.B[i+1] += alpha * dE_db
dE_dh = dE_dt @ self.M[i+1].T
dE_dt = dE_dh * self.ReluDeriv(self.S[i])
i -= 1
if i == 0:
dE_dw = self.S[0][None, ...].T @ dE_dt[None, ...]
dE_db = dE_dt
self.M[i+1] += alpha * dE_dw
self.B[i+1] += alpha * dE_db
break
Ну и понятно, что в весах M[i] и B[i] уже не числа лежат...
Надо сказать, Tensorflow я тоже изучил. И там всё тоже самое, также можно вызывать функции softmax и crossentropy, просто у них не происходит таких неприятных переполнений. Вот мне хочется узнать, что я должен исправить в этих функциях чтоб такой проблемы не возникало. И ещё вопрос, можно ли вообще эти функции как-либо менять, ведь тогда и градиент надо будет ссчитать по-другому...
Поясню, я вдохновялся следующим матреиалом: https://www.youtube.com/playlist?list=PLOSf9rRg-fvJt5adxPbefB394QBtW9smZ
Автор видео сводит вычисления производных к перемножению матриц! Оно и логично, ведь зависимости везде линейные... Но его программа состояла из 1го промежуточного слоя, а моя - из произвольного количества нейронов. Именно поэтому в промежуточных слоях у меня накапливаются "плохие" числа :(
Я пробывал нормировать все значения на входном слое, пытался всячески зажимать интервалы в пределах от e^(-720) до e^(25), путем различных делений, и вроде всё было классно, но накапливаемая ошибка перестала уменьшаться в процессе обучения.
Мне показалось, что мои методы не работали, потому что python или numpy не ссчитал дробные числа дальше 7го знака после запятой... Во всяком случае в консоль так выводилось. Вообщем зашел в тупик, буду рад если окажете помощь :)
Приведу в пример несколько фото, может они внесут дополнительную ясность в то, что было по приложенной ссылке.
И вот эти формулы можно применять на каждом слое, поэтому они УНИКАЛЬНЫ. Вот я и обхожу в цикле все слои "справа-налево", и выполняю back-propogation. Заранее скажу, что backpropogation работает правильно, т.к. в тех случаях, когда по счастливой случайности переполнения НЕ возникали, нейросеть с точностью в 70% определяла цифры на тестовой выборке. А ещё очень приятно было смотреть на убывающую ошибку в процессе обучения...
Поэтому с уверенностью заверяю что проблема в этих inf и nan, помогите пожалуйста.