#c# #machine-learning #neural-network
#c# #машинное обучение #нейронная сеть
Вопрос:
Я только начал пытаться создать свою собственную нейронную сеть на c #, скопировав простую, которую я нашел написанной на python, и результат всегда заканчивается на 0.5. Я просмотрел все другие вопросы, опубликованные об этой же проблеме в Google, и ни одно из решений не было применимо. Я понятия не имею, почему это происходит. Вот как сейчас выглядит мой код:
public class NeuralNetwork
{
private double[,] w;
public NeuralNetwork()
{
w = random(2, 1);
}
public double[,] getWeights()
{
return w;
}
public void train(double[,] x, double[,] y, int iterations)
{
for (int i = 0; i < iterations; i )
{
double[,] output = think(x);
double[,] error = Mat.subtract(Mat.transpose(y), output);
double[,] adjust = dot(Mat.transpose(x), Mat.multiply(error, doSigDeriv(output)));
w = Mat.add(w, adjust);
}
}
public double[,] think(double[,] inputs)
{
return doSig(dot(inputs, w));
}
private double[,] dot(double[,] a, double[,] b)
{
double[,] dot = new double[a.GetLength(0), b.GetLength(1)];
for (int i = 0; i < a.GetLength(0); i )
{
for (int j = 0; j < b.GetLength(1); j )
{
for (int k = 0; k < b.GetLength(0); k )
dot[i, j] = a[i, k] * b[k, j];
}
}
return dot;
}
private double[,] random(int w, int h)
{
double[,] a = new double[w, h];
for (int i = 0; i < w; i )
{
for (int j = 0; j < h; j )
{
a[i, j] = 2 * (double)rand.NextDouble() - 1;
}
}
return a;
}
private double[,] doSig(double[,] a)
{
double[,] b = new double[a.GetLength(0), a.GetLength(1)];
for (int i = 0; i < a.GetLength(0); i )
{
for (int j = 0; j < a.GetLength(1); j )
{
b[i, j] = sig(a[i, j]);
}
}
return b;
}
private double[,] doSigDeriv(double[,] a)
{
double[,] b = new double[a.GetLength(0), a.GetLength(1)];
for (int i = 0; i < a.GetLength(0); i )
{
for (int j = 0; j < a.GetLength(1); j )
{
b[i, j] = a[i, j] * (1 - a[i, j]);
}
}
return b;
//return Mat.multiply(a, Mat.subtract(one(a), a));
}
private double sig(double x)
{
return 1 / (double)(1 Math.Exp(-x));
}
}
x — это массив, который я использовал для входных данных, и y для выходных данных, а Mat — это просто класс, который я создал для обработки матричных операций. Когда я тестировал это, я изменил итерации на 10000 и 50000 и получил тот же результат. Любая информация с благодарностью, спасибо.
РЕДАКТИРОВАТЬ: я только что понял, что когда оно должно быть 0, оно равно -0,5, а 1 равно 0,5.
Комментарии:
1. Я думаю, что большинство людей в NN больше не кодируют их с нуля, я привык, но я этого больше не делаю, вам лучше потратить время на pytorch / tensorflow. Там вы работаете с конвейером. скрытые слои входного слоя, выходные слои узнают о RELU и т. Д. (Я думаю, что это время намного лучше потратить, если вы хотите погрузиться в него)
2. ах, хорошо, я понимаю, так вы думаете, что с этим стоит работать и учиться даже новичку?
3. Особенно для новичка более полезно, чтобы нейронная сеть делала какие-то забавные вещи, распознавала кошек, переходила к kaggle.com и попробуйте решить проблему Титаника, узнайте о ней, запустите код от других пользователей в облаке, это бесплатно.
Ответ №1:
Конечно, комментарий пользователя 219279 верен: в настоящее время NN лучше работать в GPU / Tensor, что намного быстрее, когда вы собираетесь расширять свою сеть. Однако для обратного распространения и изучения XOR вам не понадобится производительность.
Выходное значение 0,5 является очень распространенным и называется «локальным минимумом». Это происходит, когда по какой-то причине ваше сетевое обучение не может сходиться. Веса достигают гигантских значений / — вместо баланса с небольшими значениями и выходами 0/1.
Ошибка, которую я вижу выше: весов недостаточно. Вы распределяете свои веса в виде массива 2×1, подключая ввод-вывод. Вы не можете обучить сеть результатов XOR только с 2 весами. Вам нужно не менее 5 весов. См. Для получения дополнительной информации о подходящей архитектуре XOR http://mnemstudio.org/neural-networks-multilayer-perceptrons.htm
Комментарии:
1. Я обязательно это сделаю! просто прочитайте ссылку, это очень полезно. могу ли я добавить новые веса к уже существующей матрице или мне понадобится вторая матрица для дополнительных? Спасибо!
2. неважно, на этот раз я переписал середину и использовал 6 весов, и через некоторое время он теперь работает правильно. еще раз спасибо!
3. Чем больше нейронов вы вводите, тем более гибким будет ваше обучение, потому что веса остаются низкими по значению. Сеть все еще может учиться. На входе каждого нейрона существует S-функция, которая имеет крутое значение около 0: вес запоминается в этом диапазоне, а не за пределами ca -3 или 3. Если у вас слишком много таких весов, сеть насыщена. Попробуйте это: настройте сеть в некоторой конфигурации, обучите ее .. затем измените передачу. Посмотрите, сколько циклов требуется для замены вашей сети. Повторное обучение никогда не должно давать результатов 0,5 или занимать слишком много времени .. тогда вы использовали недостаточно нейронов или непоследовательное обучение.