Politechnika Radomska |
||||
Wydział: Nauczycielski |
Kierunek: Informatyka |
Grupa: L3 |
||
Przedmiot: Techniczne zastosowanie sieci neuronowych. |
||||
Temat: 1-7
|
Prowadzący: Mgr A. Hermanowicz |
|||
Wykonała: Michał Liwacki |
Data: 27.03.2008 |
Ocena: |
Cel:
Celem zadania jest skonstruowanie sieci neuronowej MLP [1] bez uczenia o strukturze 2x5x3x1 (Rysunek nr 1). Sprawdzenie odpowiedzi sieci i jej granic decyzyjnych. Przeprowadzenie testów dla dwóch różnych funkcji aktywacji:
1, dla y>=0 (1)
-1, dla y<0
dla β=1 (2)
Struktura sieci:
Rys. 1. Struktura sieci 2x3x1x1
Funkcje aktywacji:
Funkcje aktywacji podane są w punkcie 1. (Równania (1) i (2)).
Opis programu:
Rysunek nr 2 przedstawia interfejs graficzny programu. Dane do programu można wprowadzać na dwa sposoby:
Ręcznie - zatwierdzając klikając przycisk „Wprowadź wagi - zatwierdź.
Automatycznie po przez wciśnięcie przycisku „Losuj wagi - zatwierdź”.
Rys. 2. Interfejs graficzny programu
Rys. 3. Wynik programu dla pierwszej z funkcji aktywacji przy podanych wagach
Rys. 4. Wynik programu dla drugiej z funkcji aktywacji przy podanych wagach
Rys. 3 i Rys. 4 przedstawiają wynik programu dla tych samych danych, ale przy zastosowaniu dwóch różnych funkcji aktywacji.
Kod źródłowy:
public void won()
{
int x;
int y;
double[] wejs = new double[2];
double[] wejs2 = new double[3];
double[] wejs3 = new double[1];
Random los = new Random();
Graphics g = Graphics.FromImage(bmp);
while (true)
{
double koniec = 0;
x = los.Next(-100, 100);
wejs[0] = x;
y = los.Next(-100, 100);
wejs[1] = y;
if (radioButton1.Checked == true)
{
double neu1 = neur.wyjscia(wejs, wa1);
wejs2[0] = neur.fun_a(neu1);
double neu2 = neur.wyjscia(wejs, wa2);
wejs2[1] = neur.fun_a(neu2);
double neu3 = neur.wyjscia(wejs, wa3);
wejs2[2] = neur.fun_a(neu3);
double neu4 = neur.wyjscia(wejs2, wa4);
wejs3[0] = neur.fun_a(neu4);
double neu5 = neur.wyjscia(wejs2, wa5);
koniec = neur.fun_a(neu5);
Brush gr = new SolidBrush(Color.Green);
Pen z = new Pen(Color.Green, 1.0f);
Brush re = new SolidBrush(Color.Red);
Pen r = new Pen(Color.Red, 1.0f);
if (koniec == 1)
{
g.DrawEllipse(z, x + 100, 100 - y, 3, 3);
g.FillEllipse(gr, x + 100, 100 - y, 3, 3);
}
else
{
g.DrawEllipse(r, x + 100, 100 - y, 3, 3);
g.FillEllipse(re, x + 100, 100 - y, 3, 3);
}
try { pictureBox1.Image = bmp; }
catch { }
pictureBox1.Invalidate();
}
if (radioButton2.Checked == true)
{
double neu1 = neur.wyjscia(wejs, wa1);
wejs2[0] = neur.fun_b(neu1);
double neu2 = neur.wyjscia(wejs, wa2);
wejs2[1] = neur.fun_b(neu2);
double neu3 = neur.wyjscia(wejs, wa3);
wejs2[2] = neur.fun_b(neu3);
double neu4 = neur.wyjscia(wejs2, wa4);
wejs3[0] = neur.fun_b(neu4);
double neu5 = neur.wyjscia(wejs2, wa5);
koniec = neur.fun_b(neu5);
Brush gr = new SolidBrush(Color.Green);
Pen z = new Pen(Color.Green, 1.0f);
Brush re = new SolidBrush(Color.Red);
Pen r = new Pen(Color.Red, 1.0f);
if (koniec > 0)
{
g.DrawEllipse(z, x + 100, 100 - y, 3, 3);
g.FillEllipse(gr, x + 100, 100 - y, 3, 3);
}
else
{
g.DrawEllipse(r, x + 100, 100 - y, 3, 3);
g.FillEllipse(re, x + 100, 100 - y, 3, 3);
}
try { pictureBox1.Image = bmp; }
catch { }
pictureBox1.Invalidate();
}
Thread.Sleep(2);
}
}
private void Form1_Load(object sender, EventArgs e)
{
neur = new Tneur();
bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
}
private void sta_Click(object sender, EventArgs e)
{
wont = new Thread(new ThreadStart(won));
wont.Priority = ThreadPriority.Normal;
wont.IsBackground = true;
wont.Start();
sta.Enabled = false;
stp.Enabled = true;
res.Enabled = true;
}
private void stp_Click(object sender, EventArgs e)
{
wont.Suspend();
pon.Enabled = true;
stp.Enabled = false;
res.Enabled = false;
}
private void pon_Click(object sender, EventArgs e)
{
wont.Resume();
pon.Enabled = false;
stp.Enabled = true;
res.Enabled = true;
}
private void res_Click(object sender, EventArgs e)
{
res.Enabled = false;
stp.Enabled = false;
pon.Enabled = false;
sta.Enabled = true;
wont.Abort();
Graphics c = Graphics.FromImage(bmp);
c.Clear(Color.White);
pictureBox1.Image = bmp;
pictureBox1.Invalidate();
c.Dispose();
}
private void butLos_Click(object sender, EventArgs e)
{
this.w1.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w2.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w3.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w4.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w5.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w6.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w7.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w8.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w9.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w10.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w11.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w12.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w13.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w14.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.w15.Text = Convert.ToString(String.Format("{0:F2}", los.NextDouble() * 2 - 1));
this.dos = 1;
wa1 = new double[3];
wa2 = new double[3];
wa3 = new double[3];
wa4 = new double[4];
wa5 = new double[2];
this.wa1[0] = wag1;
this.wa1[1] = wag2;
this.wa1[2] = wag3; /// bias1
this.wa2[0] = wag4;
this.wa2[1] = wag5;
this.wa2[2] = wag6; ///bias2
this.wa3[0] = wag7;
this.wa3[1] = wag8;
this.wa3[2] = wag9; ///bias3
this.wa4[0] = wag10;
this.wa4[1] = wag11;
this.wa4[2] = wag12;
this.wa4[3] = wag13; ///bias4
this.wa5[0] = wag14;
this.wa5[1] = wag15;///bias5
if (dos == 1)
{ sta.Enabled = true; }
else
{ sta.Enabled = false; }
}
private void butAnuluj_Click(object sender, EventArgs e)
{
this.dos = 0;
}
private void button1_Click(object sender, EventArgs e)
{
if ((this.w1.Text.Trim() == "") || (this.w2.Text.Trim() == "") || (this.w3.Text.Trim() == "")
|| (this.w4.Text.Trim() == "") || (this.w5.Text.Trim() == "") || (this.w6.Text.Trim() == "")
|| (this.w7.Text.Trim() == "") || (this.w8.Text.Trim() == "") || (this.w9.Text.Trim() == "")
|| (this.w10.Text.Trim() == "") || (this.w11.Text.Trim() == "") || (this.w12.Text.Trim() == "")
|| (this.w13.Text.Trim() == "") || (this.w14.Text.Trim() == "") || (this.w15.Text.Trim() == "")
)
{
System.Windows.Forms.MessageBox.Show(this, "Pole niewypełnione",
"Komunikat", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
this.wag1 = Convert.ToDouble(this.w1.Text);
this.wag2 = Convert.ToDouble(this.w2.Text);
this.wag3 = Convert.ToDouble(this.w3.Text);
this.wag4 = Convert.ToDouble(this.w4.Text);
this.wag5 = Convert.ToDouble(this.w5.Text);
this.wag6 = Convert.ToDouble(this.w6.Text);
this.wag7 = Convert.ToDouble(this.w7.Text);
this.wag8 = Convert.ToDouble(this.w8.Text);
this.wag9 = Convert.ToDouble(this.w9.Text);
this.wag10 = Convert.ToDouble(this.w10.Text);
this.wag11 = Convert.ToDouble(this.w11.Text);
this.wag12 = Convert.ToDouble(this.w12.Text);
this.wag13 = Convert.ToDouble(this.w13.Text);
this.wag14 = Convert.ToDouble(this.w14.Text);
this.wag15 = Convert.ToDouble(this.w15.Text);
}
this.dos = 1;
wa1 = new double[3];
wa2 = new double[3];
wa3 = new double[3];
wa4 = new double[4];
wa5 = new double[2];
this.wa1[0] = wag1;
this.wa1[1] = wag2;
this.wa1[2] = wag3; /// bias1
this.wa2[0] = wag4;
this.wa2[1] = wag5;
this.wa2[2] = wag6; ///bias2
this.wa3[0] = wag7;
this.wa3[1] = wag8;
this.wa3[2] = wag9; ///bias3
this.wa4[0] = wag10;
this.wa4[1] = wag11;
this.wa4[2] = wag12;
this.wa4[3] = wag13; ///bias4
this.wa5[0] = wag14;
this.wa5[1] = wag15;///bias5
if (dos == 1)
{ sta.Enabled = true; }
else
{ sta.Enabled = false; }
}
public double fun_a(double ne)
{
int w;
if (ne >= 0) w = 1;
else w = -1;
return w;
}
public double fun_b(double ne)
{
double w;
w = (1 - Math.Exp(-ne)) / (1 + Math.Exp(-ne));
return w;
}
public double wyjscia(double[] wejs, double[] wa)
{
wyjscie = 0;
for (int i = 0; i <= wa.Length - 2; i++)
{
wyjscie= wyjscie + wa[i] * wejs[i];
}
wyjscie = wyjscie + wa[wa.Length - 1];
return wyjscie;
}
Dane:
Dane wejściowe to wektory dwuwymiarowe, każda składowa wektora wejściowego zawiera się w przedziale od -1 do 1.
Wnioski:
Zmiana wag powoduje zmianę odpowiedzi sieci.
Nie zawsze dla tych samych wag przy zastosowaniu różnych funkcji aktywacji odpowiedź sieci jest taka sama. (Rys. 3. i rys. 4.)
Bibliografia:
Masters T. Sieci neuronowe w praktyce, WNT, Warszawa 1996.