Я пытаюсь реализовать функцию softmax для нейронной сети, написанной на Numpy. Пусть h - значение softmax заданного сигнала i.Производное Softmax в подходах NumPy 0 (реализация)
Я изо всех сил, чтобы осуществить частную производную в SoftMax функции активации в.
В настоящее время я застрял на вопрос, где все частные производные к 0, как обучение прогрессирует. Я сопоставил свою математику с this excellent answer, но моя математика, похоже, не работает.
import numpy as np
def softmax_function(signal, derivative=False):
# Calculate activation signal
e_x = np.exp(signal)
signal = e_x/np.sum(e_x, axis = 1, keepdims = True)
if derivative:
# Return the partial derivation of the activation function
return np.multiply(signal, 1 - signal) + sum(
# handle the off-diagonal values
- signal * np.roll(signal, i, axis = 1)
for i in xrange(1, signal.shape[1])
)
else:
# Return the activation signal
return signal
#end activation function
Параметр signal
содержит входной сигнал, посылаемый в функцию активации и имеет форму (n_samples, n_features).
# sample signal (3 samples, 3 features)
signal = [[0.3394572666491664, 0.3089068053925853, 0.3516359279582483], [0.33932706934615525, 0.3094755563319447, 0.3511973743219001], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256]]
Следующий код отрезала является полностью рабочей функцией активации и включаются только в качестве справки и доказательства (в основном для себя), что концептуальная идея на самом деле работает.
from scipy.special import expit
import numpy as np
def sigmoid_function(signal, derivative=False):
# Prevent overflow.
signal = np.clip(signal, -500, 500)
# Calculate activation signal
signal = expit(signal)
if derivative:
# Return the partial derivation of the activation function
return np.multiply(signal, 1 - signal)
else:
# Return the activation signal
return signal
#end activation function
Редактировать
- Проблемы интуитивно сохраняется с простыми сетями однослойными. Softmax (и его производная) применяется на конечном слое.
Во-первых, для суперинтуитивного ответа! При синхронизации кода: ваш, кажется, наиболее эффективен при высоком размере выборки, тогда как предоставленный фрагмент более эффективен, если набор данных имеет большое количество функций. Независимо от того, что вычисленные производные «всегда» находятся в диапазоне 10^-17 - другими словами, около 0. – jorgenkg
@jorgenkg кажется, однако, что мы не получаем одни и те же производные. Обратите внимание, что ваши результаты для последнего образца (последние 2, они одинаковы) исчезают в отношении второй функции, а мины - нет (см. Редактирование). Попробуйте эту версию, чтобы увидеть, имеет ли она лучшую численную стабильность и не полностью исчезает ваши производные. –
Вы окончательно верны, NumPy показывает намного лучшую точность с вашей реализацией - проблема точности в моем коде может возникнуть из встроенного вызова sum(). Я бы поддержал вас дважды – jorgenkg