Я пытаюсь научить нейронную сеть 2 входам, 4 скрытым узлам (все на одном уровне) и 1 выходному узлу. Бинарное представление работает отлично, но у меня проблемы с Bipolar. Я не могу понять, почему, но общая ошибка иногда сходится к тому же числу около 2.xx. Мой сигмоид равен 2/(1+ exp (-x)) - 1. Возможно, я сигмоид в неправильном месте. Например, чтобы вычислить выходную ошибку, следует ли сравнивать сигмоидный результат с ожидаемым значением или с ожидаемым значением sigmoided?Преподавание нейронной сети: биполярный XOR
Я следил за этим сайтом здесь: http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html, но они используют разные функции, после чего мне было поручено использовать. Даже когда я пытался реализовать свои функции, я все еще сталкивался с той же проблемой. В любом случае я получаю около половины времени на одном и том же номере (другое число для разных реализаций). Скажите, пожалуйста, если я допустил ошибку в моем коде где-нибудь или если это нормально (я не понимаю, как это может быть). Momentum установлен в 0. Является ли это общей проблемой с импульсом 0? Функции ошибок мы должны использовать, являются:
, если пользовательский интерфейс выходной блок
Error(i) = (Ci - ui) * f'(Si)
если щ скрытый блок
Error(i) = Error(Output) * weight(i to output) * f'(Si)
public double sigmoid(double x) {
double fBipolar, fBinary, temp;
temp = (1 + Math.exp(-x));
fBipolar = (2/temp) - 1;
fBinary = 1/temp;
if(bipolar){
return fBipolar;
}else{
return fBinary;
}
}
// Initialize the weights to random values.
private void initializeWeights(double neg, double pos) {
for(int i = 0; i < numInputs + 1; i++){
for(int j = 0; j < numHiddenNeurons; j++){
inputWeights[i][j] = Math.random() - pos;
if(inputWeights[i][j] < neg || inputWeights[i][j] > pos){
print("ERROR ");
print(inputWeights[i][j]);
}
}
}
for(int i = 0; i < numHiddenNeurons + 1; i++){
hiddenWeights[i] = Math.random() - pos;
if(hiddenWeights[i] < neg || hiddenWeights[i] > pos){
print("ERROR ");
print(hiddenWeights[i]);
}
}
}
// Computes output of the NN without training. I.e. a forward pass
public double outputFor (double[] argInputVector) {
for(int i = 0; i < numInputs; i++){
inputs[i] = argInputVector[i];
}
double weightedSum = 0;
for(int i = 0; i < numHiddenNeurons; i++){
weightedSum = 0;
for(int j = 0; j < numInputs + 1; j++){
weightedSum += inputWeights[j][i] * inputs[j];
}
hiddenActivation[i] = sigmoid(weightedSum);
}
weightedSum = 0;
for(int j = 0; j < numHiddenNeurons + 1; j++){
weightedSum += (hiddenActivation[j] * hiddenWeights[j]);
}
return sigmoid(weightedSum);
}
//Computes the derivative of f
public static double fPrime(double u){
double fBipolar, fBinary;
fBipolar = 0.5 * (1 - Math.pow(u,2));
fBinary = u * (1 - u);
if(bipolar){
return fBipolar;
}else{
return fBinary;
}
}
// This method is used to update the weights of the neural net.
public double train (double [] argInputVector, double argTargetOutput){
double output = outputFor(argInputVector);
double lastDelta;
double outputError = (argTargetOutput - output) * fPrime(output);
if(outputError != 0){
for(int i = 0; i < numHiddenNeurons + 1; i++){
hiddenError[i] = hiddenWeights[i] * outputError * fPrime(hiddenActivation[i]);
deltaHiddenWeights[i] = learningRate * outputError * hiddenActivation[i] + (momentum * lastDelta);
hiddenWeights[i] += deltaHiddenWeights[i];
}
for(int in = 0; in < numInputs + 1; in++){
for(int hid = 0; hid < numHiddenNeurons; hid++){
lastDelta = deltaInputWeights[in][hid];
deltaInputWeights[in][hid] = learningRate * hiddenError[hid] * inputs[in] + (momentum * lastDelta);
inputWeights[in][hid] += deltaInputWeights[in][hid];
}
}
}
return 0.5 * (argTargetOutput - output) * (argTargetOutput - output);
}