zbiory danych

0

Potrzebuję analizy pewnych części kodu programu do którego treść przedstawiam poniżej(punkty generowane są losowo we wcześniejszym programie).Zaznaczonych na czerwono częsci nie rozumiem, a potrzebuję ich by wypowiedzieć się na temat tego programu na zaliczeniu ćwiczeń.

Zadanie to polega na napisaniu algorytmu będącego prostym rozszerzeniem algorytmu uczenia perceptronu na zadania rozpoznawania wielu klas, takich że każda z nich może być oddzielona od pozostałych za pomocą prostej. Najpierw idea tego algorytmu zostanie zaprezentowana na przykładzie rozpoznawania trzech klas, których punkty zaprezentowano na poniższym rysunku:

Zadanie rozpoznawania trzech klas zaprezentowanych na powyższym rysunku może być zrealizowane następująco:
Ustalamy, z wykorzystaniem algorytmu uczenia perceptronu, parametry pierwszej prostej tak aby rozdzielała elementy klasy pierwszej od elementów pozostałych klas. Parametry prostej należy ustalić tak aby dla wszystkich punktów x klasy pierwszej wartość funkcji decyzyjnej g1(x) = x* związanej z prostą była większa od zera, natomiast dla pozostałych punktów wartość funkcji g1 w tych punktach była mniejsza od 0. Podobna procedura realizowana jest dla pozostałych klas: dla klasy drugiej wyznaczamy parametry drugiej prostej tak aby rozdzielała elementy klasy drugiej od elementów pozostałych klas. Parametry prostej należy ustalić tak aby dla wszystkich punktów x klasy drugiej wartość funkcji decyzyjnej g2(x) = x* związanej z prostą była większa od zera, natomiast dla pozostałych punktów wartość funkcji g2 w tych punktach była mniejsza od 0. Ostatecznie wyznaczamy parametry trzeciej prostej tak aby rozdzielała elementy klasy trzeciej od elementów pozostałych klas. Parametry prostej należy ustalić tak aby dla wszystkich punktów klasy trzeciej wartość funkcji decyzyjnej g3 związanej z prostą była większa od zera, natomiast dla pozostałych punktów wartość funkcji g3 w tych punktach była mniejsza od 0. Interpretację geometryczną rozwiązania powyższego zadania rozpoznawania trzech klas zaprezentowano na poniższym rysunku

Ogólnie dla zadania rozpoznawania n klas budujemy, z wykorzystaniem algorytmu perceptronu, n prostych tak aby spełniony był poniższy warunek:

Po ustaleniu parametrów prostych system potrafi rozpoznawać punkty n klas. Po podaniu na wejście systemu punktu x z klasy i uzyskujemy na wyjściu: gi(x)>0 i gj(x)<0 dla
j =1,..i-1, i+1,...,n.
Zaprezentowany algorytm realizuje uczenie sieci neuronowej jednowarstwowej o n neuronach liniowych. Graficzną interpretację takiej sieci zaprezentowano na poniższym rysunku:
Po nauczeniu sieci i podaniu na wejście punktu z klasy i tylko neuron i-ty będzie posiadał na wyjściu wartość dodatnią, na wyjściach pozostałych neuronów pojawi się wartość ujemna.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(void)

{

int n=1;
float Pn[1000][2];
int Kl[1000];
char NazZb[100];
char NazZbSpr[100];

long max=100;

float abc[10][3];
char abc_zm;
Po co zmienne a,b,c?
int i=0;
int j=0;
long k;
int nk=0;
char ch;
time_t t;
float los;
float a; float b; float c;
float tmp;
long x1;
long x2;
long y1;
long y2;
long kl;
FILE *in;
char prosta[250];

puts ("Wyznaczone zostana parametry rownan linii\n");
puts ("a * x + b * y + c = 0\n");
puts ("rozdzielajacych klasy punktow.\n");

printf ("\nPodaj nazwe zbioru z wspolrzednymi: ");scanf("%s",&NazZb);

if ((in = fopen(NazZb, "r+")) == NULL)

{

fprintf(stderr, "\nNie moge otworzyc pliku z wspolrzednymi.\n");
return 1;

}

if (fgets(prosta,250,in) == NULL)

{

fprintf(stderr,"\nBlad odczytu z pliku.\n");
exit(2);

}

else

{

sscanf(prosta,"%d",&n);
printf("\nn = %d\n",n);

}

while (fgets(prosta,250,in) != NULL)

{

sscanf(prosta,"%ld.%ld %ld.%ld %d",&x1,&x2,&y1,&y2,&kl);
if(x1>=0)

{

Pn[i][0]=x1+float(x2)/1000000;
}

else

{

Pn[i][0]=x1-float(x2)/1000000;
}

if(y1>=0)

{

Pn[i][1]=y1+float(y2)/1000000;dokładność po przecinkach???
}

else

{

Pn[i][1]=y1-float(y2)/1000000;

}

Kl[i]=kl;

printf("%d %f %f %d\n",i+1,Pn[i][0],Pn[i][1],Kl[i]);
i++;

}

fclose(in);

for(nk=0;nk<n;nk++)

{

srand((unsigned) time(&t));
los = rand() % 1000000;
a=(rand() % 2)+los/1000000-1;
los = rand() % 1000000;
b=(rand() % 2)+los/1000000-1;
los = rand() % 1000000;
c=(rand() % 2)+los/1000000-1;
printf("\n\nWylosowane parametry a, b, c.");
printf("\na = %f\tb = %f\tc = %f",a,b,c);
???jak wyzej printf("\nPrzystepuje do obliczania parametrow %d prostej.",nk+1);
printf("\nIteracja\tRezultat");
abc_zm='1';po co ='1'
k=0;
while ((abc_zm == '1') && (k<max))

{

abc_zm='0';
for (j=0;j<i;j++)

{

tmp=a*Pn[j][0]+b*Pn[j][1]+c;
if ((tmp<=0) && (Kl[j]==nk+1))

{

 a+=Pn[j][0];
 b+=Pn[j][1];
 c++;
 abc_zm='1';

}

else

{

 if ((tmp>=0) && (Kl[j]!=nk+1))
 
 {

  a-=Pn[j][0];
  b-=Pn[j][1];
  c--;
  abc_zm='1';
 
 }


}

}

printf("\n%ld\t\t%c",k+1,abc_zm);
k++;

}

abc[nk][0]=a;
abc[nk][1]=b;
abc[nk][2]=c;

}

printf("\n\nObliczone parametry a, b, c");
printf("\n\prosta\ta\t\tb\t\tc");
for(nk=0;nk<n;nk++)

{

printf("\n%d\t%f\t%f\t%f",nk+1,abc[nk][0],abc[nk][1],abc[nk][2]);

}

printf("\n\nCzy uruchomic modul sprawdzajacy? [T,N]: ");
scanf("%s",&ch);
if (ch == 'T' || ch =='t')</span>

{

printf ("\nPodaj nazwe zbioru, do ktorego zostana zapisane wyniki sprawdzenia: ");scanf("%s",&NazZbSpr);
if ((in = fopen(NazZbSpr, "wt")) == NULL)

{

fprintf(stderr, "\nNie moge otworzyc pliku do zapisu wynikow sprawdzenia.\n");
return 1;

}

for (j=0;j<i;j++)

{

fputs("Lp.\tx\t\ty\t\tKlasa\n",in);
fprintf(in,"%d\t%f\t%f\t%d\n",j+1,Pn[j][0],Pn[j][1],Kl[j]);
fputs("Prosta\tWynik funkcji\n",in);
for(nk=0;nk<n;nk++)

{

fprintf(in,"%d\t%f\n",nk+1,abc[nk][0]*Pn[j][0]+abc[nk][1]*Pn[j][1]+abc[nk][2]);

}

fputs("\n",in);

}

fclose(in);

}

return 0;

}

Dodam tylko że prostą generują instrukcje napisane wg poniższej treści:

Dotyczy implementacji najprostszej sieci neuronowej, złożonej z jednego neuronu o liniowej funkcji aktywacji i zastosowania jej do rozwiązania jednego z najprostszych zadań klasyfikacji, dotyczącego rozpoznawania separowanych liniowo zbiorów dwóch klas, których elementy są punktami płaszczyzny.

Na wstępie zaprezentowana zostanie interpretacja geometryczna prostej w kartezjańskim układzie współrzędnych.

Prostą w kartezjańskim układzie współrzędnych można jednoznacznie opisać za pomocą trzech liczb w1, w2, w0, gdzie w1, w2 definiuje wspórzędne wektora prostopadłego do prostej, natomiast w0 determinuje punkt przecięcia prostej z osią poziomą. Wszystkie punkty należące do prostej spełniają następujące równanie:

w1x1 + w2x2 + w0 = wx + w0 = 0

Z prostą możemy związać funkcję zdefiniowaną na płaszczyźnie ( g:R2->R) zdefiniowaną następująco:

Dla wszystkich punktów leżących nad prostą spełniony jest warunek: g(x) > 0. Natomiast dla każdego punktu x leżącego pod prostą spełniony jest warunek: g(x) < 0. Ostatnie dwa warunki zostaną wykorzystane do budowy klasyfikatora. Algorytm wyznaczający klasyfikator liniowy będzie, na podstawie danych wejściowych (punktów klas), ustalał parametry prostej (w1, w2, w0,), tak że prosta ta będzie rozdzielała zbiory w ten sposób aby jeden leżał nad prostą a drugi pod prostą.

Program powinien odczytywać ze zbioru danych wygenerowanego programem pierwszym punkty dwóch klas. Oznaczmy te punkty następująco:

x11 x12 1
x21 x22 1
...

...

gdzie: pierwszy indeks dolny oznacza numer punktu a drugi numer współrzędnej. Klasa pierwsza zawiera n1 punktów a klasa druga n2. Trzecia liczba w każdym wierszu oznacza numer klasy do której należy punkt.

Zbiór powyższych danych będzie dalej nazywany zbiorem uczącym i oznaczany krótko: , gdzie ik - numer klasy do której należy k-ty punkt
(i = 1, 2). Wprowadźmy ponadto dodatkowe oznaczenia:
w*(t) - wektor opisujący prostą w kroku t algorytmu: w*(t) = (w1(t), w2(t), w0(t)),

wektor rozszerzony k-tego punktu zbioru uczącego , k = 1,2,...,n1+n2.</li> </ul>

Po wczytaniu zbioru uczącego program losuje parametry prostej: w1(0), w2(0), w0(0) jako liczby rzeczywiste z przedziału [-1 1]. Nastepnie dla każdego punktu ze zbioru uczącego algorytm realizuje następujące przetwarzanie:

Jeżeli zastosowanie procedury (1) do każdego punktu zbioru uczącego spowodowało przynajmniej jedną modyfikację wektora parametrów prostej w* to algorytm ponownie stosuje procedurę (1) dla każdego elementu zbioru uczącego.
Program kończy działanie kiedy dla wszystkich punktów zbioru uczącego w procedurze (1) nie trzeba było ani razu modyfikować parametrów prostej w*.
Zaprezentowany schemat nazywany jest algorytmem uczenia perceptronu.

Przykład
Zbiór uczący:

1 1 1
-1 -1 2
0 0 2

Program losuje parametry prostej: w1(0) = 1, w2(0) = -1, w0(0) = 0
Realizuje pr. (1) dla punktu pierwszego: , stąd modyfikacja parametrów prostej: .

Realizacja pr. (1) dla punktu drugiego: i punkt należy do klasy 2, stąd .

Realizacja pr. (1) dla punktu trzeciego: i punkt należy do klasy 2, stąd modyfikacja prostej: .

Niestety dla dwóch punktów zbioru uczącego algorytm zmodyfikował parametry prostej. Stąd powtarzamy pr. (1) dla każdego elementu zbioru uczącego:

Realizuje pr. (1) dla punktu pierwszego: i punkt należy do klasy 1, stąd .

Realizacja pr. (1) dla punktu drugiego: i punkt należy do klasy 2, stąd .

Realizacja pr. (1) dla punktu trzeciego: i punkt należy do klasy 2, stąd modyfikacja prostej: .

Niestety dla trzeciego punktu zbioru uczącego algorytm zmodyfikował parametry prostej. Stąd powtarzamy pr. (1) dla każdego elementu zbioru uczącego:

Realizuje pr. (1) dla punktu pierwszego: i punkt należy do klasy 1, stąd .

Realizacja pr. (1) dla punktu drugiego: i punkt należy do klasy 2, stąd .

Realizacja pr. (1) dla punktu trzeciego: i punkt należy do klasy 2, stąd .

Ponieważ ostatnie przeglądanie zbioru uczącego nie spowodowało modyfikacji parametrów prostej to algorytm kończy działanie. Wyznaczone parametry prostej to:
Interpretacja geometryczna rozwiązanego zadania:

Na powyższym rysunku punkt klasy pierwszej oznaczony jest za pomocą czarnego kwadracika natomiast punkty klasy drugiej za pomocą czarnego kółeczka.
Widać że wyznaczona przez algorytm uczenia perceptronu prosta rozdziela dwa zbiory.

Proces ustalania parametrów prostej może być interpretowany jako uczenie jednego neuronu rozpoznawania dwóch klas. Reprezentację graficzną neuronu przedstawia poniższy rysunek:

Rysunków niestety nie dodaję, ale ich przydatność uważam za znikomą.</i>

0

Człowieku ty chyba jestes nie powazny.

Powiedz szczerze, ile w ciagu semestru poswieciles czasu na zajecia ?

0

dosłownie 0(uczelnia prywatna) [browar] .Od października idę na specjalkę z grafiki więc coding mi ><>.Potrzebuję tego tylko na zaliczenie jednych zajęć.

1 użytkowników online, w tym zalogowanych: 0, gości: 1