连续感知器权重变化为零
Continuous Perceptron Weights Change Zero
我正在研究 2 class 个简单的感知器问题。我的项目工作是让用户从 GUI 面板单击鼠标并进行 class 化。 Class 1 预期输出:1 和 Class 2 预期输出 -1。我的问题是离散感知器工作正常但连续感知器在一个点停止后减少错误。我不知道我做错了什么。我看了这么多代码和源码。
我的公式;
- E=1/2 Σ(d-o)^2
- f(净)=(2/(1+ⅇ^(-净)))-1
- ΔW=n(d-o)(1-o^2)y
像这样。
d
:预期输出,
net
: 权重*输入总和,
y
:输入矩阵([x1 x2 -1])和
o
: 实际输出。
下面连续感知器的代码;
while (totalError > Emax)
{
totalError = 0;
for(i=0; i<point.Count; i++)
{
double x1 = point[i].X1;
double x2 = point[i].X2;
double net = (x1 * w0) + (x2 * w1) + (x0 * w2);
double o = (2 / (1 + Math.Exp(-net))) - 1;
double error = Math.Pow(point[i].Class - o, 2);
w0 += (x1 * c * (point[i].Class - o) * (1 - Math.Pow(o, 2))) / 2;
w1 += (x2 * c * (point[i].Class - o) * (1 - Math.Pow(o, 2))) / 2;
w2 += (x0 * c * (point[i].Class - o) * (1 - Math.Pow(o, 2))) / 2;
totalError += error;
}
totalError = totalError / 2;
ErrorShow(cycle, totalError);
objGraphic.Clear(Color.White);
DrawSeperationLine();
cycle++;
}
Emax=0.001 已选择。项目是这样工作的。您可以看到它不正确的行位置。 Class 1 是蓝色,class 2 是红色。
我觉得是for循环的问题。
代码的控制台输出:
编辑:
在与@TaW(感谢您展示道路)讨论后,我在输出(激活功能)中发现了我的问题。它总是 return 1 或 -1。之后在权重变化函数 [1-Math.Pow(o,2)
] 部分 return 0 中使权重变化等于 0。所以我的问题是如何解决这个问题。类型转换无效。
我的问题的解决方案是使用规范化。对于标准化,我使用标准偏差。标准偏差代码如下;
for(i=0;i<point.Count;i++){
x1 += point[i].X1;
x2 += point[i].X2;
}
meanx1 = x1 / point.Count;
meanx2 = x2 / point.Count;
for(i=0;i<point.Count;i++){
totalX1 += Math.Pow(point[i].X1 - meanx1, 2);
totalX2 += Math.Pow(point[i].X2 - meanx2, 2);
}
normX1 = totalX1 / (point.Count - 1);
normX2 = totalX2 / (point.Count - 1);
normX1 = normX1 / 100;
normX2 = normX2 / 100;
最后一个除法用于减小值。
我正在研究 2 class 个简单的感知器问题。我的项目工作是让用户从 GUI 面板单击鼠标并进行 class 化。 Class 1 预期输出:1 和 Class 2 预期输出 -1。我的问题是离散感知器工作正常但连续感知器在一个点停止后减少错误。我不知道我做错了什么。我看了这么多代码和源码。
我的公式;
- E=1/2 Σ(d-o)^2
- f(净)=(2/(1+ⅇ^(-净)))-1
- ΔW=n(d-o)(1-o^2)y
像这样。
d
:预期输出,
net
: 权重*输入总和,
y
:输入矩阵([x1 x2 -1])和
o
: 实际输出。
下面连续感知器的代码;
while (totalError > Emax)
{
totalError = 0;
for(i=0; i<point.Count; i++)
{
double x1 = point[i].X1;
double x2 = point[i].X2;
double net = (x1 * w0) + (x2 * w1) + (x0 * w2);
double o = (2 / (1 + Math.Exp(-net))) - 1;
double error = Math.Pow(point[i].Class - o, 2);
w0 += (x1 * c * (point[i].Class - o) * (1 - Math.Pow(o, 2))) / 2;
w1 += (x2 * c * (point[i].Class - o) * (1 - Math.Pow(o, 2))) / 2;
w2 += (x0 * c * (point[i].Class - o) * (1 - Math.Pow(o, 2))) / 2;
totalError += error;
}
totalError = totalError / 2;
ErrorShow(cycle, totalError);
objGraphic.Clear(Color.White);
DrawSeperationLine();
cycle++;
}
Emax=0.001 已选择。项目是这样工作的。您可以看到它不正确的行位置。 Class 1 是蓝色,class 2 是红色。
我觉得是for循环的问题。
代码的控制台输出:
编辑:
在与@TaW(感谢您展示道路)讨论后,我在输出(激活功能)中发现了我的问题。它总是 return 1 或 -1。之后在权重变化函数 [1-Math.Pow(o,2)
] 部分 return 0 中使权重变化等于 0。所以我的问题是如何解决这个问题。类型转换无效。
我的问题的解决方案是使用规范化。对于标准化,我使用标准偏差。标准偏差代码如下;
for(i=0;i<point.Count;i++){
x1 += point[i].X1;
x2 += point[i].X2;
}
meanx1 = x1 / point.Count;
meanx2 = x2 / point.Count;
for(i=0;i<point.Count;i++){
totalX1 += Math.Pow(point[i].X1 - meanx1, 2);
totalX2 += Math.Pow(point[i].X2 - meanx2, 2);
}
normX1 = totalX1 / (point.Count - 1);
normX2 = totalX2 / (point.Count - 1);
normX1 = normX1 / 100;
normX2 = normX2 / 100;
最后一个除法用于减小值。