Я смотрел это потрясающее видео Дэйва Миллера о создании нейронной сети с нуля в C ++ здесь: https://vimeo.com/19569529
Вот полный исходный код, указанный в видео: http://inkdrop.net/dave/docs/neural-net-tutorial.cpp
Он использует среднеквадратичную ошибку в качестве функции стоимости. Я заинтересован в использовании нейронной сети для бинарной классификации, хотя и хотел бы использовать кросс-энтропию в качестве функции стоимости. Я надеялся добавить это к этому коду, если это возможно, так как я уже играл с ним.
Как это будет применяться конкретно здесь?
Будет ли единственное различие в том, как рассчитывается ошибка для выходного слоя … или уравнения меняются на протяжении всего обратного распространения?
Что-нибудь меняется вообще? Используется ли MSE в сравнении с кросс-энтропией исключительно для того, чтобы получить представление об общей ошибке и не имеет отношения к обратному распространению?
Изменить для ясности:
Вот соответствующие функции.
//output layer - seems like error is just target value minus calculated value
void Neuron::calcOutputGradients(double targetVal)
{
double delta = targetVal - m_outputVal;
m_gradient = delta * Neuron::transferFunctionDerivative(m_outputVal);
}
double Neuron::sumDOW(const Layer &nextLayer) const
{
double sum = 0.0;
// Sum our contributions of the errors at the nodes we feed.
for (unsigned n = 0; n < nextLayer.size() - 1; ++n) {
sum += m_outputWeights[n].weight * nextLayer[n].m_gradient;
}
return sum;
}
void Neuron::calcHiddenGradients(const Layer &nextLayer)
{
double dow = sumDOW(nextLayer);
m_gradient = dow * Neuron::transferFunctionDerivative(m_outputVal);
}void Neuron::updateInputWeights(Layer &prevLayer)
{
// The weights to be updated are in the Connection container in the neurons in the preceding layer
for (unsigned n = 0; n < prevLayer.size(); ++n) {
Neuron &neuron = prevLayer[n];
double oldDeltaWeight = neuron.m_outputWeights[m_myIndex].deltaWeight;
//calculate new weight for neuron with momentum
double newDeltaWeight = eta * neuron.getOutputVal() * m_gradient + alpha * oldDeltaWeight;
neuron.m_outputWeights[m_myIndex].deltaWeight = newDeltaWeight;
neuron.m_outputWeights[m_myIndex].weight += newDeltaWeight;
}
}
Наконец-то нашел ответ здесь: https://visualstudiomagazine.com/articles/2014/04/01/neural-network-cross-entropy-error.aspx
Вам нужно только изменить способ вычисления ошибки в выходном слое.
Соответствующая функция, подлежащая изменению:
void Neuron::calcOutputGradients(double targetVal)
Для среднеквадратичных ошибок используйте:
double delta = targetVal - m_outputVal;
m_gradient = delta * Neuron::transferFunctionDerivative(m_outputVal);
Для перекрестной энтропии просто использовать:
m_gradient = targetVal - m_outputVal;
Других решений пока нет …