Continuous Perceptron Weights Change Zero - c#

I am working on 2 class simple perceptron problem. My project work getting user mouse click from GUI panel and make classification. Class 1 expected output: 1 and Class 2 expected output -1. My problem is discrete perceptron working fine but continuous perceptron after one point stop decrease error. I don't know what I am doing wrong. I look so much code and source.
My formulas;
E=1/2 Σ(d-o)^2
f(net)=(2/(1+ⅇ^(-net)))-1
ΔW=n(d-o)(1-o^2)y
like this.
d: Expected output,
net: weight*input sum,
y: input matrix ([x1 x2 -1]) and
o: Actual output.
Code for continuous perceptron below;
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 selected. Project working like this. You can see it not correct line location. Class 1 is blue and class 2 red.
I think problem in for loop.
Console Output of Code:
Edit:
After discuss with #TaW (Thanks for showing road), I find out my problem in output (activation function). It always return 1 or -1. After that in weight change function [1-Math.Pow(o,2)] part return 0 and that make weight change equal 0. So my question how can I solve this problem. Type casting not work.

My question's solution is using normalization. For normalization I use standard deviation. Standart deviation code is below;
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;
The last division is used to decrease the value.

Related

Calculation results in NaN [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I was trying to calculate the result of a second degree equation using C#, but i get the result NaN. Can someone check my code to locate the error ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace desafio2_2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please insert the values that multiply x², x and the independent term respectively: ");
float a = float.Parse(Console.ReadLine());
float b = float.Parse(Console.ReadLine());
float c = float.Parse(Console.ReadLine());
double bhaskarap1 = (Math.Pow(b, 2)) + (- 4 * a * c);
double raiz1 = (-b + Math.Sqrt(bhaskarap1)) / (2 * a);
double raiz2= (-b - Math.Sqrt(bhaskarap1)) / (2 * a);
Console.WriteLine(raiz1);
Console.WriteLine(raiz2);
}
}
}
It may be possible that the quadratic equation has no real roots. In this case the discriminant will be negative.
Math.Sqrt(x) returns NaN when when x is negative. You should test the discriminant for negative number before you call the square root function.
static void Main(string[] args)
{
Console.WriteLine("Please insert the values that multiply x², x and the independent term respectively: ");
float a = float.Parse(Console.ReadLine());
float b = float.Parse(Console.ReadLine());
float c = float.Parse(Console.ReadLine());
double bhaskarap1 = (Math.Pow(b, 2)) + (- 4 * a * c);
if (bhaskarap1 < 0)
{
Console.WriteLine("There are no real solutions.");
return;
}
double raiz1 = (-b + Math.Sqrt(bhaskarap1)) / (2 * a);
double raiz2= (-b - Math.Sqrt(bhaskarap1)) / (2 * a);
Console.WriteLine(raiz1);
Console.WriteLine(raiz2);
}
argument of sqrt method must be positive.
I would check for NaN using a ternary operator like I did below to handle the case of a negative value for sqrt.
float a = 4.0f, b = 7.0f, c = -3.0f;
double my_var = ((Math.Pow(b, 2)) + (-4 * a * c));
Console.WriteLine(my_var);
Console.WriteLine(((-b + Math.Sqrt(-1 * my_var)) / (2 * a)));
double temp = (-b + Math.Sqrt(my_var)) / (2 * a);
double raiz1 = temp.CompareTo(Double.NaN) < 1 ? 0.00 : temp;
temp = (-b + Math.Sqrt(-1 * my_var)) / (2 * a);
double raiz2 = temp.CompareTo(Double.NaN) < 1 ? 0.00 : temp;
Console.WriteLine($"Raiz1: {raiz1}\tRaiz2: {raiz2}");
Output:
97
NaN
Raiz1: 0.356107225224513 Raiz2: 0
The roots of the second degree equations are complex numbers in general case, e.g.
x**2 + 1 = 0
That's why I suggest using Complex, not float:
...
using System.Numerics;
...
// float.Parse - if you want to allow just real coefficients
Complex a = float.Parse(Console.ReadLine());
Complex b = float.Parse(Console.ReadLine());
Complex c = float.Parse(Console.ReadLine());
Complex bhaskarap1 = b * b - 4 * a * c;
Complex raiz1 = (-b + Complex.Sqrt(bhaskarap1)) / (2 * a);
Complex raiz2 = (-b - Complex.Sqrt(bhaskarap1)) / (2 * a);
Console.WriteLine(raiz1);
Console.WriteLine(raiz2);

What does 1.e0 mean in the following code

What does 1.e0 mean in the following code
product *=
((1.e0-pow((double)2,i-32))*(1.e0-pow((double)2,i-32)))/(1.e0-pow((double)2,i-r));
It is c++ code, and how i can write 1.e0 in c#
<number>e<power> = <number> * 10^<power>
Where the power is a power of ten. Basically the number after e tells you how many zeroes you have to append if it is positive. Negative powers make the number move by one digit to the right.
Examples
1.2e-3 = 1.2 * 10^-3 = 1.2 * 0.001 = 0.0012
1.2e-2 = 1.2 * 10^-2 = 1.2 * 0.01 = 0.012
1.2e-1 = 1.2 * 10^-1 = 1.2 * 0.1 = 0.12
1.2e0 = 1.2 * 10^0 = 1.2 * 1 = 1.2
1.2e1 = 1.2 * 10^1 = 1.2 * 10 = 12
1.2e2 = 1.2 * 10^2 = 1.2 * 100 = 120
1.2e3 = 1.2 * 10^3 = 1.2 * 1000 = 1200
You can see this notation on calculators. When the result is too large and would not fit into the display otherwise, the calculator automatically switches to the exponential notation.
In C# you would write the formula like this:
product *= (1 - Math.Pow(2, i - 32)) * (1 - Math.Pow(2, i - 32)) /
(1 - Math.Pow(2, i - r));
The conversions to double happen automatically. One pair of parentheses is superfluous. One sub-expression occurs twice, you could write:
double temp = 1 - Math.Pow(2, i - 32);
product *= temp * temp / (1 - Math.Pow(2, i - r));
See:
- Math.Pow Method (Double, Double) (msdn)
Providing that pow is raising into power, C# code will be
product *= (1.0 - Math.Pow(2, i - 32)) *
(1.0 - Math.Pow(2, i - 32)) /
(1.0 - Math.Pow(2, i - r));
As you can see 1.e0 is just 1.0 - double representation of 1

Get value between a range of two values from percentage

Let's say I have a range of two values:
5...........98
and let's assume the user position's the slider at value 40
Now I want to get the value from another range of values at the exact percentage position as from range 1
let's say the second range of values are 10.........80
int nRange1 = 98 - 5;
int nRange2 = 80 - 10;
int nValue1 = 40;
int nPercentOnRange1 = ((nValue1 - 5) / nRange1)*100;
Now I have to get the value from Range2 at the exact percentage as nPercentOnRange1, but I don't know how
First need to find % from first range and apply that % to new range.
Here is what I will do:
Range1(A to B) Selected value: c
Range2(E to F)
Range1 % = (C-A) / (B-A) * 100
Range 2 corresponding value = ((F - E) * (Range 1 %) / 100) + E
C#:
int Range1Min = 5, Range1Max=90, Range1SelectedValue = 40;
int Range2Min = 6, Range2Max=80;
decimal range1Percent = (Range1SelectedValue-Range1Min ) / (Range1Max-Range1Min) * 100.0
decimal range2NewValue = (Range2Max - Range2Min) * range1Percent / 100 + Range2Min;
Watch out for
int nPercentOnRange1 = ((nValue1 - 5)/ nRange1) * 100;
ending up as zero since nValue1 and nRange1 are integers. This might be better:
int nPercentOnRange1 = ((nValue1 - 5) * 100 / nRange1);
Then you can do
int nValue2 = 10 + nPercentOnRange1*nRange2/100;
The value you need is
x = 10 + nRange2 * nPercentOnRange1 / 100.0
Let me explain why. You need a number x such that
((x - 10) / nRange2) * 100.0 = nPercentOnRange1
Therefore, just solve for x.
((x - 10) / nRange2) * 100.0 = nPercentOnRange1 =>
((x - 10) / nRange2) = nPercentOnRange1 / 100.0 =>
x - 10 = nRange2 * nPercentOnRange1 / 100.0 =>
x = 10 + nRange2 * nPercentOnRange1 / 100.0
And note that this actually makes intuitive sense. We're saying take the percentage, scale that into the length of the second range (that's what nRange2 * nPercentOnRange1 / 100.0) is doing and then add that to the lower bound of the second range. Basically we are saying step nPercentOnRange1 percent into the second range. That's exactly what the formula is expressing.
Perhaps this will work:
nValue2 = nPercentage1 * nRange2 / 100 + 10

Translating Excel formula to c# (annuity)

I have a excel formula I am trying to "translate" into c# code.
It is used to calculate an "annuity rate" over time (for example 20 years).
=(((1+E26/100)^D28*((1+E26/100)-1))/((1+E26/100)^D28-1))*100
D28 = 20 (years)
E26 = 5,00 (the rate in percent)
the ^ stands for exponent in Excel
As a result with these numbers I expect 8,02% per annum.
I tried several approaches using Math.Pow but wasn't successful.
Here is my first approach which gives me a result of 5 somehow.
double usagePanels = 20.0
double rate = 5.0
annPanels = (Math.Pow((1 + rate / 100), usagePanels) *
((1 + rate / 100) - 1) /
Math.Pow(1+rate/100, (usagePanels-1))) * 100;
Thank you.
Try:
double usagePanels = 20.0
double rate = 5.0
double annPanels = (Math.Pow((1 + rate / 100), usagePanels) *
(rate / 100.0)) /
Math.Pow(1+rate/100, usagePanels)-1)) * 100;
You've got the closing bracket, between usagePanels and the -1, wrong...
(I found this by breaking the formula apart in Excel and in C# and comparing each part.)
EDIT: Another handy tip for comparing Excel to C# is to give the cells in Excel a name (via the Named Range feature) that way the Excel formula can be made to look closer to variable names...
This should do the trick:
double rate = 5;
double years = 20;
double annunity = Math.Pow(1 + rate / 100, years) * (rate / 100) / Math.Pow(1 + rate / 100, years - 1) * 100;
For clarity, the working result is
double usagePanels = 20.0
double rate = 5.0
annPanels = (Math.Pow((1 + rate / 100), usagePanels) *
((1 + rate / 100) - 1) /
(Math.Pow(1+rate/100, (usagePanels))-1)) * 100;
Thanks to Jason Allen and Grhm who basically figured it out and gave great advice.

Dicom Window width & level formula not giving greyvalues

I'm trying to implement the Window Width and level formula from de Dicom specification in my application. Only it's not returning any grayscales at the moment. The dicom specifies the formula as following:
These Attributes are applied according to the following pseudo-code, where x is the input value, y
is an output value with a range from ymin to ymax, c is Window Center (0028,1050) and w is
Window Width (0028,1051):
if (x <= c - 0.5 - (w-1)/2), then y = ymin
else if (x > c - 0.5 + (w-1)/2), then y = ymax,
else y = ((x - (c - 0.5)) / (w-1) + 0.5) * (ymax - ymin)+ ymin
So i've translated this into the following c# syntax:
if (pixelData[i] <= wLevel - 0.5 - (wWidth - 1) / 2)
oColor = 0;
else if (pixelData[i] > wLevel - 0.5 + (wWidth - 1) / 2)
oColor = 255;
else
oColor = (int)((pixelData[i] - (wLevel - 0.5)) / (wWidth - 1) + 0.5) * (255 - 0) + 0;
Howevery, the last part of the formula
oColor = (int)((pixelData[i] - (wLevel - 0.5)) / (wWidth - 1) + 0.5) * (255 - 0) + 0;
Only seems to return 0
Anyone sees how this is possible?
The meaning of VOI LUT is to map a given pixel range to displayable values (usually 0..0xFF), using clamping for out of range pixel values.
This means that for a given window/level we can compute the displayable range:
level-window/2 , level + window/2 .
For pixel values that are in that range, linear transformation is used:
((pixel - lower_window_limit) / window) * displayable_range
where lower_window_limit is level - window/2
This -window/2 is missing in your formula.

Categories