#include <stdio.h> #include <math.h> #include <local/bgi.h> #define Pixel 42 #define Pattern 5 #define Study 1000000 #define check 1000 #define INP 42 #define CELL 30 #define OUT 2 #define Prob 2 #define alpha 0.40 #define epsilon 0.35 #define al2 0.40 #define ep2 0.35 #define fkm 0.50 #define fks 0.50 #define fkr 0.50 #define C_CODE (int)('A') #define W() (drand48() * 0.6 - 0.3) #define beep ('G' - '@') void Put_figure(); void Draw_graph(); void Message(); void Input_data(); void Data_arrange(); void Output_data(); void Teach_signal(); void Pattern_search(); void InitStruct(); void Chaos_calc(); void MidNeuro_calc(); double OutNeuro_calc(); void Change_wg(); void Change_pa(); void Kakunin(); double Function(); struct Unit{ double wi[INP]; double dwi[INP]; double wf[CELL]; double dwf[CELL]; double yi, sh, dsh; double xi, eta, zeta; double km, ks, kr; double dkm, dks, dkr; }chaos[CELL], *p; struct unit{ double w[CELL]; double dw[CELL]; double y, sk, dsk; }o_neuro[OUT], *u; struct mnit{ double w[CELL]; double dw[CELL]; double y, sk, dsk; }m_neuro[CELL], *q; int inc, inc2, inc3, inc4, inc5; int lp1, lp2, lp3, lp4; int gd, gm, gx1, gx2, gy1,gy2; int cycle; int data[3][5], len[3]; double *inp_top; double tsignal[2]; double output[2][40]; char ch[5], cdat[40]; struct Unit *mid_top; struct unit *out_top; struct mnit *m_top; double drand48(); static double PATTERN[Pattern][Pixel] = {{0,0,1,1,0,0, 0,1,0,0,1,0, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,1,1,1,1,1, 1,0,0,0,0,1, 1,0,0,0,0,1}, {1,1,1,1,1,0, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,1,1,1,1,0, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,1,1,1,1,0}, {0,0,1,1,1,0, 0,1,0,0,0,1, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 0,1,0,0,0,1, 0,0,1,1,1,0}, {1,1,1,1,0,0, 0,1,0,0,1,0, 0,1,0,0,0,1, 0,1,0,0,0,1, 0,1,0,0,0,1, 0,1,0,0,1,0, 1,1,1,1,0,0}, {0,0,1,1,1,1, 0,0,1,0,0,0, 0,1,0,0,0,0, 0,1,1,1,1,0, 0,1,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,1,0}}; main() { int flag, iput, rnd; int *pt; int ct[3], test[40]; double error, maxe; double input[INP], keep[CELL]; char pkind[5], fname[50]; /* static test[40] = {0,2,1,4,3,2,1,3,4,1,2,3,0,3,3,2,1,0,2,1, 0,1,2,4,4,3,2,3,4,0,1,3,0,2,4,3,2,1,0,4};*/ /* グラフィック処理 */ Put_figure(); /* 画面スクロール */ for(lp1 = 0 ; lp1 <= 40 ; lp1++) printf("\n"); /* メッセージ出力 */ Message(); /* 周期の形入力 , 整数に変換 */ Input_data(); /* 周期数、文字数の設定, 整数データの整理 */ Data_arrange(); closegraph(); /* データの出力 */ Output_data(); printf("\n リターンキーを押して下さい。\n"); fgetc(stdin); pkind[0] = 'A'; pkind[1] = 'B'; pkind[2] = 'C'; pkind[3] = 'D'; pkind[4] = 'E'; for(lp1 = 0 ; lp1 <= 4 ; lp1++) ch[lp1] = '\0'; for(lp1 = 0 ; lp1 <= CELL - 1 ; lp1++) keep[lp1] = 0.0; ct[0] = ct[1] = ct[2] = 0; flag = 0; rnd = 10; inc = 0; inc2 = 0; inc3 = 0; inc4 = 0; inc5 = 0; error = 0.0; maxe = 0.0; mid_top = &chaos[0]; out_top = &o_neuro[0]; m_top = &m_neuro[0]; /* 構造体の初期化 */ srand48(0); InitStruct(); /* 学習メインループ */ if(cycle == 0){ printf(" 学習を行なえません。\n"); goto label; } printf(" 周期パターンの学習を始めます。\n"); printf(" 終了するまで、しばらくお待ち下さい。\n\n"); for(lp1 = 1 ; lp1 <= Study ; lp1++){ if(rnd <= cycle - 1 || flag == 1){ flag = 1; iput = data[rnd][inc++]; if(len[rnd] == inc){ rnd = cycle; flag = 0; inc = 0; } } else{ rnd = (int)(drand48() * (Prob * cycle)); iput = (int)(drand48() * 5); } if(rnd >= Prob * cycle - 1 && flag == 0){ inc++; inc5++; if(inc5 > cycle) inc5 = 1; rnd = inc5 - 1; while(iput == data[rnd][0]) iput = (int)(drand48() * 5); } ch[0] = pkind[iput]; Teach_signal(&ct[0]); for(lp2 = 0 ; lp2 <= INP - 1 ; lp2++) input[lp2] = PATTERN[iput][lp2]; inp_top = &input[0]; Chaos_calc(); MidNeuro_calc(); error = OutNeuro_calc(); Change_wg(); Change_pa(); p = mid_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ keep[lp2] = p -> yi; ++p; } /* Kakunin(iput, rnd, error);*/ if(error > maxe) maxe = error; if(lp1 % check == 0){ printf(" 学習回数...%d回\n", ++inc3 * check); printf(" 最大平均自乗誤差...%f\n\n\n", maxe); maxe = 0.0; /* Kakunin(iput, rnd, error);*/ } for(lp2 = 3 ; lp2 >= 0 ; lp2--) ch[lp2 + 1] = ch[lp2]; } printf("\n\n"); for(lp1 = 0 ; lp1 <= 9 ; lp1++){ putchar('\0'); putchar(beep); for(lp2 = 0 ; lp2 <= 30000 ; lp2++) putchar('\0'); } printf("\n リターンキーを押して下さい。\n"); fgetc(stdin); /* 学習確認用データ作成 */ inc = 0; for(lp1 = 0 ; lp1 <= cycle - 1 ; lp1++){ rnd = (int)(drand48() * 5) + 3; for(lp2 = 0 ; lp2 <= rnd ; lp2++) test[inc++] = (int)(drand48() * 5); for(lp2 = 0 ; lp2 <= len[lp1] - 1 ; lp2++) test[inc++] = data[lp1][lp2]; } for(lp1 = inc ; lp1 <= 39 ; lp1 ++) test[lp1] = (int)(drand48() * 5); /* 学習確認 */ for(lp1 = 0 ; lp1 <= 39 ; lp1++){ iput = test[lp1]; for(lp2 = 0 ; lp2 <= INP - 1 ; lp2++) input[lp2] = PATTERN[iput][lp2]; inp_top = &input[0]; Chaos_calc(); MidNeuro_calc(); OutNeuro_calc(); Change_pa(); cdat[lp1] = pkind[iput]; u = out_top; output[0][lp1] = u++ -> y; output[1][lp1] = u -> y; } Draw_graph(); for(lp1 = 0 ; lp1 <= 2 ; lp1++) printf(" Pattern%d...%d 回\n", lp1, ct[lp1]); printf(" 学習回数 %d 回 平均自乗誤差 %f\n\n", Study, maxe); while(!kbhit()) ; sprintf(fname, "ChaosInDX%ld.xbm", Study); graph2xbm(fname); closegraph(); label: ; } void Put_figure() { initgraph(&gd,&gm,"935x248"); cleardevice(); for(lp1 = 50 ; lp1 <= 758 ; lp1 += 177){ for(lp2 = lp1 ; lp2 <= lp1 + 126 ; lp2 += 21) line(lp2, 50, lp2, 197); for(lp3 = 50 ; lp3 <= 197 ; lp3 += 21) line(lp1, lp3, lp1+126, lp3); } for(lp1 = 0 ; lp1 <= 4 ; lp1++){ inc = 0; for(lp2 = 0 ; lp2 <= 6 ; lp2++){ for(lp3 = 0 ; lp3 <= 5 ; lp3++){ if(PATTERN[lp1][inc] == 1){ gx1 = 50 + lp1 * 177 + lp3 * 21; gy1 = 50 + lp2 * 21; gx2 = gx1 + 21; gy2 = gy1 + 21; bar(gx1, gy1, gx2, gy2); } inc++; } } } } void Draw_graph() { char c[2]; initgraph(&gd,&gm,"800x930"); cleardevice(); ch[0] = ch[1] = ch[2] = ch[3] = ch[4] = '\0'; inc = 0; inc2 = 0; line(99, 429, 699, 429); line(99, 489, 699, 489); line(99, 449, 99, 29); line(99, 469, 99, 889); outtextxy(64, 448, "発火"); outtextxy(64, 484, "発火"); outtextxy(60, 350, "出"); outtextxy(60, 370, "力"); outtextxy(60, 390, "1"); outtextxy(60, 540, "出"); outtextxy(60, 560, "力"); outtextxy(60, 580, "2"); for(lp1 = 99 ; lp1 <= 684 ; lp1 += 15){ line(lp1, 429, lp1, 419); line(lp1, 489, lp1, 499); ch[0] = cdat[inc]; sprintf(c, "%c", cdat[inc++]); outtextxy(lp1 + 5, 467, c); for(lp2 = 0 ; lp2 <= cycle - 1 ; lp2++){ inc2 = 0; inc4 = 0; Pattern_search(); if(inc4 == len[lp2]){ switch(lp2){ case 2 : outtextxy(lp1 + 5, 447, "*"); case 1 : outtextxy(lp1 + 5, 487, "*"); break; case 0 : outtextxy(lp1 + 5, 447, "*"); break; } } } for(lp2 = 3 ; lp2 >= 0 ; lp2--) ch[lp2 + 1] = ch[lp2]; } for(lp1 = 429 ; lp1 >= 29 ; lp1 -= 40) line(99, lp1, 89, lp1); for(lp1 = 489 ; lp1 <= 889 ; lp1 += 40) line(99, lp1, 89, lp1); for(lp1 = 99 ; lp1 <= 699 ; lp1 += 12) line(lp1, 229, lp1 + 6, 229); for(lp1 = 99 ; lp1 <= 699 ; lp1 += 12) line(lp1, 689, lp1 + 6, 689); outtextxy(73, 222, "0.5"); outtextxy(73, 22, "1.0"); outtextxy(73, 709, "0.5"); outtextxy(73, 909, "1.0"); inc = 0; for(lp1 = 99 ; lp1 <= 684 ; lp1 += 15){ gx1 = lp1; gy1 = 429 - (int)(400 * output[0][inc]); gx2 = lp1 + 15; gy2 = 429; if(output[0][inc] <= 0.5) rectangle(gx1, gy1, gx2, gy2); else bar(gx1, gy1, gx2, gy2); gx1 = lp1; gy1 = 489; gx2 = lp1 + 15; gy2 = 489 + (int)(400 * output[1][inc]); if(output[1][inc++] <= 0.5) rectangle(gx1, gy1, gx2, gy2); else bar(gx1, gy1, gx2, gy2); } } void Message() { printf(" これから周期パターンの検出の学習を行います。\n"); printf(" 画面の上に表示されているパターンを使って\n"); printf(" 検出したい周期の形を入力して下さい。\n"); printf(" 入力には大文字のアルファベットを用いて下さい。\n"); printf(" A,B,C,D,E以外の文字は、無視されます。\n\n"); printf(" 例 Prease input cycle pattern :ABC\n\n"); printf(" 上記は、A,B,Cの周期パターンを検出させる入力例です。\n"); printf(" 入力できる周期の形は、3つまでです。\n"); printf(" 周期の長さは、5文字までです。\n"); printf(" 何も指定しない時は、入力なしでリターンしてください。\n\n"); } void Input_data() { char c[10]; for(lp1 = 0 ; lp1 <= 2 ; lp1++){ printf(" Prease input cycle pattern :"); fgets(c, 10 ,stdin); for(lp2 = 0 ; lp2 <= 4 ; lp2++){ data[lp1][lp2] = (int)(c[lp2]) - C_CODE; if(data[lp1][lp2] > 4 || data[lp1][lp2] < 0) data[lp1][lp2] = 5; } for(lp2 = 0 ; lp2 <= 8 ; lp2++) c[lp2] = '\0'; } } void Data_arrange() { int suu[5]; inc2 = 0; cycle = 0; for(lp1 = 0 ; lp1 <= 2 ; lp1++){ inc = 0; for(lp2 = 0 ; lp2 <= 4 ; lp2 ++){ if(data[lp1][lp2] != 5) suu[inc++] = data[lp1][lp2]; } if(inc != 0){ len[inc2] = inc; for(lp2 = 0 ; lp2 <= inc - 1 ; lp2 ++) data[inc2][lp2] = suu[lp2]; for(lp2 = inc ; lp2 <= 4 ; lp2 ++) data[inc2][lp2] = 5; inc2++; cycle++; } } } void Output_data() { printf("\n\n"); for(lp1 = 0 ; lp1 <= cycle - 1 ; lp1 ++){ printf(" 整数データ%d...", lp1 + 1); for(lp2 = 0 ; lp2 <= 4 ; lp2 ++) printf("%d", data[lp1][lp2]); printf("\n"); } printf("\n"); for(lp1 = 0 ; lp1 <= cycle - 1 ; lp1 ++) printf(" 文字長さ%d...%d\n", lp1 + 1, len[lp1]); printf("\n"); printf(" 検出する周期数...%d\n\n", cycle); } void Teach_signal(co) int *co; { tsignal[0] = 0.0; tsignal[1] = 0.0; for(lp2 = 0 ; lp2 <= cycle - 1 ; lp2 ++){ inc4 = 0; inc2 = 0; Pattern_search(); if(inc4 == len[lp2]){ switch(lp2){ case 0: ++(*co); tsignal[0] = 1.0; break; case 1: ++co; ++(*co); tsignal[1] = 1.0; break; case 2: ++co; ++co; ++(*co); tsignal[0] = 1.0; tsignal[1] = 1.0; break; } } } } void Pattern_search() { for(lp3 = len[lp2] - 1 ; lp3 >= 0 ; lp3--) if(data[lp2][inc2++] == (int)(ch[lp3] - C_CODE)) ++inc4; } void InitStruct() { p = mid_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ for(lp3 = 0 ; lp3 <= INP - 1 ; lp3++){ p -> wi[lp3] = W(); p -> dwi[lp3] = 0.0; } for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ p -> wf[lp3] = W(); p -> dwf[lp3] = 0.0; } p -> yi = 0.0; p -> km = fkm; p -> ks = fks; p -> kr = fkr; p -> dkm = 0.0; p -> dks = 0.0; p -> dkr = 0.0; p -> xi = 0.0; p -> eta = 0.0; p -> zeta = 0.0; ++p; } q = m_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ q -> w[lp3] = W(); q -> dw[lp3] = 0.0; } q -> sk = W(); q -> dsk = W(); q -> y = 0.0; ++q; } u = out_top; for(lp2 = 0 ; lp2 <= OUT - 1 ; lp2++){ for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ u -> w[lp3] = W(); u -> dw[lp3] = 0.0; } u -> sk = W(); u -> dsk = W(); u -> y = 0.0; ++u; } } void Chaos_calc() { double kali1, kali2; double fyi; double kali[CELL]; double *thp; struct Unit *tsp; p = mid_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ kali1 = kali2 = 0; thp = inp_top; for(lp3 = 0 ; lp3 <= INP - 1 ; lp3++){ kali1 += p -> wi[lp3] * (*thp); ++thp; } tsp = mid_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ kali2 += p -> wf[lp3] * tsp -> yi; ++tsp; } p -> eta = kali1 + p -> km * p -> eta; p -> xi = kali2 + p -> ks * p -> xi; p -> zeta = - p -> yi + p -> kr * p -> zeta - (p -> sh * (1 - p -> kr)); fyi = p -> xi + p -> eta + p -> zeta; kali[lp2] = Function(fyi); ++p; } p = mid_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ p -> yi = kali[lp2]; ++p; } } void MidNeuro_calc() { double kali; q = m_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ kali = 0; p = mid_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ kali += q -> w[lp3] * p -> yi; ++p; } kali -= q -> sk; q -> y = Function(kali); ++q; } } double OutNeuro_calc() { double kali, err; err = 0; u = out_top; for(lp2 = 0 ; lp2 <= OUT - 1 ; lp2++){ kali = 0; q = m_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ kali += u -> w[lp3] * q -> y; ++q; } kali -= u -> sk; u -> y = Function(kali); ++u; } u = out_top; for(lp2 = 0 ; lp2 <= OUT - 1 ; lp2++){ err += (u -> y - tsignal[lp2]) * (u -> y - tsignal[lp2]); ++u; } err = err / OUT; return(err); } void Change_wg() { double deltaw, dsikii, kali; double *thp; double deltak[OUT]; double deltai[CELL]; double deltaj[CELL]; struct Unit *tsp; u = out_top; for(lp2 = 0 ; lp2 <= OUT - 1 ; lp2++){ deltak[lp2] = (u -> y - tsignal[lp2]) * (u -> y) * (1 - u -> y); ++u; } q = m_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ kali = 0; u = out_top; for(lp3 = 0 ; lp3 <= OUT - 1 ; lp3++){ kali += deltak[lp3] * u -> w[lp2]; ++u; } deltai[lp2] = kali * q -> y * (1 - q -> y); ++q; } p = mid_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ kali = 0; q = m_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ kali += deltai[lp3] * q -> w[lp2]; ++q; } deltaj[lp2] = kali * p -> yi * (1 - p -> yi); ++p; } u = out_top; for(lp2 = 0 ; lp2 <= OUT - 1 ; lp2++){ q = m_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ deltaw = alpha * u -> dw[lp3] - epsilon * deltak[lp2] * q -> y; ++q; u -> w[lp3] += deltaw; u -> dw[lp3] = deltaw; } dsikii = alpha * u -> dsk - epsilon * deltak[lp2]; u -> sk += dsikii; u -> dsk = dsikii; ++u; } q = m_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ p = mid_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ deltaw = alpha * q -> dw[lp3] - epsilon * deltai[lp2] * p -> yi; ++p; q -> w[lp3] += deltaw; q -> dw[lp3] = deltaw; } dsikii = alpha * q -> dsk - epsilon * deltai[lp2]; q -> sk += dsikii; q -> dsk = dsikii; ++q; } p = mid_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ thp = inp_top; for(lp3 = 0 ; lp3 <= INP - 1 ; lp3++){ deltaw = alpha * p -> dwi[lp3] - epsilon * deltaj[lp2] * (*thp); ++thp; p -> wi[lp3] += deltaw; p -> dwi[lp3] = deltaw; } tsp = mid_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++){ deltaw = alpha * p -> dwf[lp3] - epsilon * deltaj[lp2] * tsp -> yi; ++tsp; p -> wf[lp3] += deltaw; p -> dwf[lp3] = deltaw; } dsikii = alpha * p -> dsh - epsilon * deltaj[lp2]; p -> sh += dsikii; p -> dsh = dsikii; ++p; } } void Change_pa() { p = mid_top; for(lp2 = 0 ; lp2 <= CELL - 1 ; lp2++){ p -> dks = - ep2 * p -> yi * (1 - p -> yi) * p -> xi + al2 * p -> dks; p -> ks = Function(p -> ks + p -> dks); p -> dkm = - ep2 * p -> yi * (1 - p -> yi) * p -> eta + al2 * p -> dkm; p -> km = Function(p -> km + p -> dkm); p -> dkr = - ep2 * p -> yi * (1 - p -> yi) * (p -> zeta + p -> sh) + al2 * p -> dkr; p -> kr = Function(p -> kr + p -> dkr); ++p; } } void Kakunin(ipt, ran, er) int ipt, ran; double er; { printf(" Study turn...%d\n\n", lp1); printf(" RND...%d\n", ran); printf(" Pattern type...%c\n", ch[0]); printf(" Cycle pattern..."); for(lp2 = 0 ; lp2 <= 4 ; lp2++) printf("%c", ch[lp2]); printf("\n Teach signal1...%f\n", tsignal[0]); printf(" Teach signal2...%f\n", tsignal[1]); printf(" Error avrage...%f\n\n", er); u = out_top; printf(" output1...%f output2...%f\n\n", u++ -> y, u -> y); printf(" Input data\n"); inc2 = 0; for(lp2 = 0 ; lp2 <= 6 ; lp2++){ printf(" "); for(lp3 = 0 ; lp3 <= 5 ; lp3++) printf("%d", (int)PATTERN[ipt][inc2++]); printf("\n"); } fgetc(stdin); printf("\n\n"); p = mid_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++) printf("ks%d...%f\n", lp3, p++ -> ks); fgetc(stdin); p = mid_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++) printf("km%d...%f\n", lp3, p++ -> km); fgetc(stdin); p = mid_top; for(lp3 = 0 ; lp3 <= CELL - 1 ; lp3++) printf("kr%d...%f\n", lp3, p++ -> kr); fgetc(stdin); } double Function(f) double f; { double ans; ans = 1 / (1 + exp(-(f))); return(ans); }