admin管理员组文章数量:1394409
I have been suffering for several days and cannot understand what the problem is, the neural network can SOMETIMES produce the same results for different input data, sometimes it works correctly, perhaps the problem is in the initialization of the weights, I tried different methods, it did not help, perhaps in the training method, I did unit tests, depending on the number of layers and neurons in them it may be that the result is ultimately the same for all predictions with different input data, although a completely different result is expected, as if the neural network simply freezes at some point or is trained incorrectly, in which algorithm could the problem be?
public class Neuron
{
public List<double> Weights { get;}
public List<double> Inputs { get;}
public NeuronType Type { get; }
public double Output { get; set; }
public double Delta { get; set; }
public double Error = 0.0;
Random rnd = new Random();
public Neuron(int inputCount, NeuronType type)
{
Type = type;
Weights = new List<double>();
Inputs = new List<double>();
for (int i = 0; i < inputCount; i++)
{
if (type == NeuronType.Input)
Weights.Add(1);
else
Weights.Add(rnd.NextDouble());
Thread.Sleep(10);
Inputs.Add(0);
}
}
public double FeedForward(List<double> signals)
{
for (int i = 0; i < Inputs.Count; i++)
{
Inputs[i] = signals[i];
}
double sum = 0.0;
for (int i = 0; i < signals.Count; i++)
{
sum += signals[i] * Weights[i];
}
if (Type != NeuronType.Input)
{
Output = Sigmoid(sum);
}
else
{
Output = sum;
}
return Output;
}
public double Sigmoid(double x)
{
double function = 1.0 / (1.0 + Math.Pow(Math.E, -x));
return function;
}
public double SigmoidDx(double x)
{
double functiondef = Sigmoid(x);
double function = functiondef * (1.0 - functiondef);
return function;
}
public void CorrectWeight(double learningRate)
{
if (Type == NeuronType.Input)
{
return;
}
for (int i = 0; i < Weights.Count; i++)
{
double newWeight = Weights[i] - Inputs[i] * Delta * learningRate;
Weights[i] = newWeight;
}
}
public void CheckDelta(double error, double learningRate)
{
if (Type == NeuronType.Input)
{
Error = error;
return;
}
double delta = error * SigmoidDx(Output);
Error = error;
Delta = delta;
}
}
public class NeuralNetwork
{
public List<Layer> Layers { get; }
public Topology Topology { get; }
public NeuralNetwork(Topology topology)
{
Topology = topology;
Layers = new List<Layer>();
CreateInputLayer();
CreateHiddenLayers();
CreateOutputLayer();
}
public Neuron Predict(params double[] signals)
{
SendSignalsInputLayer(signals);
FeedForwardAll();
return Layers.Last().Neurons.OrderByDescending(n => n.Output).First();
}
private void FeedForwardAll()
{
for (int i = 1; i < Layers.Count; i++)
{
Layer layer = Layers[i];
List<double> prevLayerSignals = Layers[i - 1].CollectSignals();
foreach (var item in layer.Neurons)
{
item.FeedForward(prevLayerSignals);
}
}
}
private void SendSignalsInputLayer(params double[] signals)
{
for (int i = 0; i < signals.Length; i++)
{
List<double> signal = new List<double>() { signals[i] };
Neuron neuron = Layers[0].Neurons[i];
neuron.FeedForward(signal);
}
}
private void CreateInputLayer()
{
List<Neuron> neurons = new List<Neuron>();
for (int i = 0; i < Topology.InputNeuronsCount; i++)
{
Neuron neuron = new Neuron(1, NeuronType.Input);
neurons.Add(neuron);
}
Layer layer = new Layer(neurons, NeuronType.Input);
Layers.Add(layer);
}
private void CreateHiddenLayers()
{
for (int j = 0; j < Topology.HiddenLayers.Count; j++)
{
List<Neuron> neurons = new List<Neuron>();
int lastLayerCount = Layers.Last().Neurons.Count;
for (int i = 0; i < Topology.HiddenLayers[j]; i++)
{
Neuron neuron = new Neuron(lastLayerCount, NeuronType.Normal);
neurons.Add(neuron);
}
Layer layer = new Layer(neurons, NeuronType.Normal);
Layers.Add(layer);
}
}
private void CreateOutputLayer()
{
List<Neuron> neurons = new List<Neuron>();
int lastLayerCount = Layers.Last().Neurons.Count;
for (int i = 0; i < Topology.OutputNeuronsCount; i++)
{
Neuron neuron = new Neuron(lastLayerCount, NeuronType.Output);
neurons.Add(neuron);
}
Layer layer = new Layer(neurons, NeuronType.Output);
Layers.Add(layer);
}
public double Learn(double[] expected, double[,] inputs, int epochs)
{
double[,] signals = inputs;
double error = 0.0;
for (int j = 0; j < epochs; j++)
{
for (int i = 0; i < expected.Length; i++)
{
double output = expected[i];
double[] input = GetRow(signals, i);
error += BackError(output, input);
}
}
double result = error / epochs;
return result;
}
public double[] GetRow(double[,] matrix, int row)
{
int columns = matrix.GetLength(1);
double[] array = new double[columns];
for (int i = 0; i < columns; ++i)
{
array[i] = matrix[row, i];
}
return array;
}
public double Sigmoid(double x)
{
double function = 1.0 / (1.0 + Math.Pow(Math.E, -x));
return function;
}
public double SigmoidDx(double x)
{
double functiondef = Sigmoid(x);
double function = functiondef * (1.0 - functiondef);
return function;
}
private double BackError(double expected, params double[] inputs)
{
var actual = Predict(inputs).Output;
var difference = actual - expected;
foreach (var neuron in Layers.Last().Neurons)
{
neuron.CheckDelta(difference, Topology.LearningRate);
}
for (int j = Layers.Count - 2; j >= 0; j--)
{
var layer = Layers[j];
var previousLayer = Layers[j + 1];
for (int i = 0; i < layer.Neurons.Count; i++)
{
var neuron = layer.Neurons[i];
double error = 0.0;
for (int k = 0; k < previousLayer.Neurons.Count; k++)
{
var previousNeuron = previousLayer.Neurons[k];
error += previousNeuron.Weights[i] * previousNeuron.Delta;
}
neuron.CheckDelta(error, Topology.LearningRate);
}
}
for (int i = 0; i < Layers.Count; i++)
{
for (int j = 0; j < Layers[i].Neurons.Count; j++)
{
Layers[i].Neurons[j].CorrectWeight(Topology.LearningRate);
}
}
var result = difference * difference;
return result;
}
}
When processing images, I get either the same result for different input data, or a completely wrong one. I want the images to be classified differently (if the name of the image starts with 1 - so that the result of the neural network when processing the image there is around 0 - the picture shows an airplane, if it starts with 2 - so that the result is around 1 - the picture shows a bus (some classification)). By analogy with some kind of digit recognition.
[TestMethod]
public void TestMethod1()
{
var size = 14;
var parasitizedPath = @"C:\Users\serez\source\repos\CSAI\newall";
//var unparasitizedPath = @"C:\Users\serez\source\repos\CSAI\масти\Крести";
var converter = new Picture();
var testParasitizedImageInput = converter.Processing(@"C:\Users\serez\source\repos\CSAI\newall\14.png");
var testUnparasitizedImageInput = converter.Processing(@"C:\Users\serez\source\repos\CSAI\newall\21.png");
var testParasitizedImageInput2 = converter.Processing(@"C:\Users\serez\source\repos\CSAI\newall\15.png");
var testUnparasitizedImageInput2 = converter.Processing(@"C:\Users\serez\source\repos\CSAI\newall\21.png");
var testParasitizedImageInput3 = converter.Processing(@"C:\Users\serez\source\repos\CSAI\newall\12.png");
var testUnparasitizedImageInput3 = converter.Processing(@"C:\Users\serez\source\repos\CSAI\newall\24.png");
var topology = new Topology(testParasitizedImageInput.Count, 2, 0.1, 32, 16);
var neuralNetwork = new NeuralNetwork(topology);
double[,] parasitizedInputs = GetData(parasitizedPath, converter, testParasitizedImageInput, size);
neuralNetwork.Learn(new double[] {0,0,0,0,0,0,1,1,1,1,1,1}, parasitizedInputs, 100);
var unpar = neuralNetwork.Predict(testUnparasitizedImageInput.Select(t => (double)t).ToArray());
var par = neuralNetwork.Predict(testParasitizedImageInput.Select(t => (double)t).ToArray());
var unpar2 = neuralNetwork.Predict(testParasitizedImageInput2.Select(t => (double)t).ToArray());
var par2 = neuralNetwork.Predict(testParasitizedImageInput2.Select(t => (double)t).ToArray());
var unpar3 = neuralNetwork.Predict(testUnparasitizedImageInput3.Select(t => (double)t).ToArray());
var par3 = neuralNetwork.Predict(testParasitizedImageInput3.Select(t => (double)t).ToArray());
Assert.AreEqual(1, Math.Round(unpar.Output, 2));
Assert.AreEqual(0, Math.Round(par.Output, 2));
}
private static double[,] GetData(string Path, Picture converter, List<double> testImageInput, int size)
{
var images = Directory.GetFiles(Path).OrderBy(f => f).ToArray();
var result = new double[size, testImageInput.Count];
for (int i = 0; i < size; i++)
{
var image = converter.Processing(images[i]);
for (int j = 0; j < image.Count; j++)
{
result[i, j] = image[j];
}
}
return result;
}
It is necessary for the neural network to always give the most correct answer (written for classifying small images)
本文标签:
版权声明:本文标题:artificial intelligence - Why sometimes same output values are obtained with different input data on neural network from scratc 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744090051a2589250.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论