#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);
}