C# 有人能告诉我这种反向传播实现有什么问题吗
所以我尝试用c#实现一个反向传播神经网络。我遇到了一个小问题。训练网络时,所有输出为0.49°???。。。还是0.51 这是我的网络课C# 有人能告诉我这种反向传播实现有什么问题吗,c#,.net,neural-network,artificial-intelligence,backpropagation,C#,.net,Neural Network,Artificial Intelligence,Backpropagation,所以我尝试用c#实现一个反向传播神经网络。我遇到了一个小问题。训练网络时,所有输出为0.49°???。。。还是0.51 这是我的网络课 namespace BackPropNetwork { public class Network { public double[][] Values { get; set; } public double[][] Deltas { get; set; } public double[][][] Weights { get; set;
namespace BackPropNetwork
{
public class Network
{
public double[][] Values { get; set; }
public double[][] Deltas { get; set; }
public double[][][] Weights { get; set; }
public Network(params int[] size)
{
Values = new double[size.Length][];
Weights = new double[size.Length][][];
Deltas = new double[size.Length][];
Random r = new Random();
for(int i = 0; i < size.Length; i++)
{
Values[i] = new double[size[i]];
Weights[i] = new double[size[i]][];
Deltas[i] = new double[size[i]];
if (i != size.Length - 1) {
for (int j = 0; j < size[i]; j++)
{
Weights[i][j] = new double[size[i + 1]];
for(int k= 0; k < size[i + 1]; k++)
{
Weights[i][j][k] = r.NextDouble() ;
}
}
}
}
}
public double[] FeedThrough (double[] input)
{
if(input.Length!= Values[0].Length)
{
throw new InvalidOperationException();
}
Values[0] = input;
for(int i = 0; i < Values.Length-1; i++)
{
for(int j = 0; j < Values[i + 1].Length; j++)
{
Values[i + 1][j] = Sigmoid(GetPassValue(i, j),false);
}
}
return Values[Values.Length - 1];
}
double GetPassValue(int layer,int neuron)
{
double sum = 0;
for(int i = 0; i < Values[layer].Length; i++)
{
sum += Values[layer][i] * Weights[layer][i][neuron];
}
return sum;
}
public double Sigmoid(double d, bool dir)
{
if (dir)
{
return d * (1 - d);
}else
{
return 1 / (1 + Math.Exp(d));
}
}
public void CorrectError(double[] error)
{
for(int i = Values.Length - 1; i >= 0; i--)
{
if (i !=Values.Length - 1)
{
error = new double[Values[i].Length];
for(int j = 0; j < Values[i].Length; j++)
{
error[j] = 0;
for(int k = 0; k < Values[i + 1].Length; k++)
{
error[j] += Weights[i][j][k] * Deltas[i + 1][k];
}
}
}
for(int j = 0; j < Values[i].Length; j++)
{
Deltas[i][j] = error[j] * Sigmoid(Values[i][j],true);
}
}
}
public void ApplyCorrection(double rate)
{
for(int i = 0; i < Values.Length-1; i++)
{
for(int j = 0; j < Values[i].Length; j++)
{
for(int k = 0; k < Values[i + 1].Length; k++)
{
Weights[i][j][k] = rate * Deltas[i + 1][k] * Values[i][j];
}
}
}
}
}
就这样一直持续下去
编辑1:
我在ApplyCorrection()函数中做了一个更改,其中替换了
Weights[i][j][k] = rate * Deltas[i + 1][k] * Values[i][j];
与`
Weights[i][j][k] += rate * Deltas[i + 1][k] * Values[i][j];
现在权重似乎在更新。但我仍然怀疑这个实现的正确性。A.k.A仍然需要帮助:)
编辑2:
我不是对输出层的总错误求和,而是对每个样本错误分别进行反向传播。现在我是,但是输出非常混乱:
我还将输出对从(0,1)更改为(-1,1),试图使计算的错误值更大。
这是在1000000个时代之后,学习率为0.1:
预期值:-1已获取:0.99999429209274
预期:1获得:0.99999843901661
预期值:-1已获得:0.687098308461306
预期值:-1已获得:0.788960893508226
预期值:-1获得:0.99999429209274
预期值:-1获得:0.863022549216158
预期值:-1已获得:0.788960893508226
预期:-1得到:0.9999998474717769
尝试使用以下内容,并检查错误是否减少或仍然相同
public double Sigmoid(double d, bool dir)
{
if (dir)
{
return d * (1 - d);
}else
{
if (d < -45.0) return 0.0;
else if (d > 45.0) return 1.0;
else return 1.0 / (1.0 + Math.Exp(-d));
}
}
public双S形(双d,布尔方向)
{
if(dir)
{
返回d*(1-d);
}否则
{
如果(d<-45.0)返回0.0;
如果(d>45.0),则返回1.0;
否则返回1.0/(1.0+Math.Exp(-d));
}
}
我想这是因为非线性的S形函数,我实际上认为这可能是因为我在ApplyCorrection函数中设置了权重。其中为权重[i][j][k]=速率*增量[i+1][k]*值[i][j];我认为应该是权重[I][j][k]+=速率*增量[I+1][k]*值[I][j];这似乎改变了输出,并使网络学习。但我仍然不确定我的实现是否正确。如果它是真的,它将返回导数。不,我不是。但无论如何,谢谢你,我试过了,现在的情况是重量不再改变了,不管它是否真的起作用了。非常感谢你!对于实际输出-1,它是作为预测输出给出-1值,还是仍然在0和1之间?我会首先使用sigmoid函数,而不是尝试-1到1的任何替代函数。请参阅链接“”。其他选项是分配下一组随机值以启动网络。
Weights[i][j][k] += rate * Deltas[i + 1][k] * Values[i][j];
public double Sigmoid(double d, bool dir)
{
if (dir)
{
return d * (1 - d);
}else
{
if (d < -45.0) return 0.0;
else if (d > 45.0) return 1.0;
else return 1.0 / (1.0 + Math.Exp(-d));
}
}