ソースコードは以下になります。 使用するデータも添付します。
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define Iunits 5 //入力層
#define Hunits 10 //中間層
#define Ounits 1 //出力層
#define SMAX 256
#define Rlow -0.30
#define Rhigh 0.30
#define A 1.4
#define B 0.3
#define fout(x) (1 / (1 + exp( -(x) ) ) )
#define urand() ( drand48() * (Rhigh - Rlow) + Rlow )
double wih[Hunits][Iunits];//結合加重
double who[Ounits][Hunits];
double dwih[Hunits][Iunits];//重みの変化量
double dwho[Ounits][Hunits];
double shikiih[Hunits];//しきい値
double shikiio[Ounits];
double iout[Iunits]; /* 各層の出力 */
double hout[Hunits];
double oout[Ounits];
double dshikiih[Hunits];//しきい値の変化量
double dshikiio[Ounits];
double Eta,Alpha ;/*η,α値*/
double ts[SMAX];/*boxデータを配列*/
double st[SMAX];//教師信号を配列
int tsmax ;//教師信号数
double drand48();
double tsignal[Ounits]; //教師信号
FILE *fpbox;
void initialize();
void foward_propagation();
void back_propagation();
int main (int argc, char *argv[])
{
unsigned int i,j,kk,k,dn;
int ct = 0, flag1 = 0 , flag2 = 0;
int count = 0,number = 0;
FILE *fp , *fp2;
char name[SMAX];
if(argc != 3){
printf("///can't action the program.///\n");
printf(" ./a.out , Eta , Alpha , boxname ,please \n");
exit(1);
}
Eta = atof(argv[1]);
Alpha = atof(argv[2]);
kk = 15 ; //学習回数
//ニューロンの初期化
initialize();
/* 為替データのopen */
fpbox = fopen("data.txt","r");
if( fpbox == NULL){
printf("Can't open the file \n");
exit(1);
}
/*為替・データの読み込みとデータ数のカウント*/
while( fscanf(fpbox,"%lf %lf %lf %lf %lf %lf",&ts[ct],&ts[ct+1],&ts[ct+2],&ts[ct+3],&ts[ct+4],&st[number]) == 6 ){
ct += 5 ;//入力信号数
number++;
}
for(i = 0 ; i < ct ; i++){
printf("boxdate ts[%d]=[ %f ]\n", i,ts[i]);
}
tsmax = ct / 5;//教師信号数
fclose(fpbox);
//処理スタート
while(count < tsmax){
//データを入力層を格納
printf("ct = %d\n",ct);
getchar();
printf("Eta = %f Alpha = %f ct = %d tsmax = %d \n",Eta,Alpha,ct,tsmax);
getchar();
for(i = 0 ; i < 5 ; i++){
iout[i] = ts[flag1];
flag1 = flag1 + 1 ;
}
//教師信号
tsignal[0] = st[flag2];
//学習
for(k = 1 ; k <= kk ; k++){
foward_propagation();
back_propagation();
}
printf("out[] = %lf\n",oout[0]);
/*
if( k == kk ){
dn = k / 100 ;
sprintf(name,"b%d_E%0.4f_A%0.2f.data",dn,Eta,Alpha);
fp2 = fopen(name,"w");
if (fp2 == NULL){
fprintf(stderr,"error\n");
exit(1);
}
fwrite(wih,sizeof(double),Iunits * Hunits,fp2);
fwrite(who,sizeof(double),Hunits * Ounits,fp2);
fwrite(shikiih,sizeof(double),Hunits,fp2);
fwrite(shikiio,sizeof(double),Ounits,fp2);
fclose(fp2);
}*/
flag2 ++ ;
count ++ ;
printf("count = %d tsmax = %d tsignal = %f \n",count,tsmax,tsignal[0]);
}
}
//各ユニットの結合加重に重みを振り分ける
void initialize()
{
int i,j;
for(i = 0 ; i < Hunits ; i++){
for(j = 0 ; j < Iunits ; j++){
wih[i][j] = urand(); //結合加重
/*
printf("wih[i][j] = %lf urand() = %lf",wih[i][j],urand());
getchar();
*/
}
shikiih[i] = urand();
//printf("shikiih[] = %lf\n",shikiih[i]); //しきい値
}
for(i = 0 ; i < Ounits ; i++){
for(j = 0 ; j < Hunits ; j++){
who[i][j] = urand();
}
shikiio[i] = urand();
}
}
//フォワードプロパゲーション
void foward_propagation()
{
int i,j;
double sum;
for( i = 0 ; i < Hunits ; i++){
sum = 0 ;
for(j = 0 ; j < Iunits ; j++){
sum += wih[i][j] * iout[j];
}
//printf("sum = %lf shikiih = %lf\n",sum , shikiih[i]);
hout[i] = fout (sum + shikiih[i]);
}
//printf("hout[%d] = %f\n",i,hout[i]);
for ( i = 0 ; i < Ounits ; i++ ){
sum = 0 ;
for(j = 0 ; j < Hunits ; j++ ){
sum += who[i][j] * hout[j];
}
oout[i] = fout(sum + shikiio[i]);
printf("oout[] = %lf ",oout[i]);
}
printf("sum = %f\n",sum);
}
//バックプロパゲーション
void back_propagation()
{
int i,j;
double dih[Hunits],dho[Ounits]; //学習信号
double sum = 0 ;
for(i = 0 ; i < Ounits ; i++){
//出力の伝達関数はy = x という形になっているので伝達関数の微分は1ということになる
//出力層の学習信号の計算
dho[i] = oout[i] * ( 1 - oout[i] ) * ( tsignal[i] - oout[i] );
}
//出力の重み補正
for(i = 0 ; i < Hunits ; i++){
for (sum = 0 , j = 0 ; j < Ounits ; j++){
dwho[j][i] = (Eta * dho[j] * hout[i]) + (Alpha * dwho[j][i]);//結合加重の変化量計算
sum += ( dho[j] * who[j][i] );
who[j][i] += dwho[j][i]; //修正
}
dih[i] = hout[i] * (1 - hout[i] ) * sum;
}
/*出力のしきい値補正*/
for ( i = 0 ; i < Ounits ; i++ ){
dshikiio[i] = ( Eta * dho[i] ) + ( Alpha * dshikiio[i] );
shikiio[i] += dshikiio[i];
}
/*中間層の重み補正*/
for ( i = 0 ; i < Iunits ; i++ ){
for ( j = 0 ; j < Hunits ; j++ ){
dwih[j][i] = ( Eta * dih[j] * iout[i] ) + ( Alpha * dwih[j][i] );
wih[j][i] += dwih[j][i];
}
}
/*中間層のしきい値補正*/
for ( i = 0 ; i < Hunits ; i++ ){
dshikiih[i] = ( Eta * dih[i] ) + ( Alpha * dshikiih[i] );
shikiih[i] += dshikiih[i];
}
}
データdata.txt
76.672 76.664 77.191 77.048 76.886 76.825
75.672 72.664 74.191 74.048 73.886 77.822
注:最初の5つのデータは、初値・高値・低値など、 最後のデータは教師信号です。
実行結果は:
実行結果をご覧になると、oout[]は2回目からすべて1に収束してしまいます。k11067kk@pck11067kk$ cc nyu.c
k11067kk@pck11067kk$ ./a.out 0.75 0.8
shikiih[] = 0.231857
shikiih[] = -0.264685
shikiih[] = 0.049619
shikiih[] = -0.254677
shikiih[] = -0.298347
shikiih[] = -0.115929
shikiih[] = -0.208884
shikiih[] = 0.018977
shikiih[] = 0.266334
shikiih[] = -0.177022
boxdate ts[0]=[ 76.672000 ]
boxdate ts[1]=[ 76.664000 ]
boxdate ts[2]=[ 77.191000 ]
boxdate ts[3]=[ 77.048000 ]
boxdate ts[4]=[ 76.886000 ]
boxdate ts[5]=[ 75.672000 ]
boxdate ts[6]=[ 72.664000 ]
boxdate ts[7]=[ 74.191000 ]
boxdate ts[8]=[ 74.048000 ]
boxdate ts[9]=[ 73.886000 ]
ct = 10
Eta = 0.750000 Alpha = 0.800000 ct = 10 tsmax = 2
hout[10] = 76.672000
oout[] = 0.604669 sum = 0.449866
hout[10] = 76.672000
oout[] = 1.000000 sum = 68.924082
hout[10] = 76.672000
oout[] = 1.000000 sum = 123.516245
hout[10] = 76.672000
oout[] = 1.000000 sum = 167.176937
hout[10] = 76.672000
oout[] = 1.000000 sum = 202.081842
hout[10] = 76.672000
oout[] = 1.000000 sum = 229.971421
hout[10] = 76.672000
oout[] = 1.000000 sum = 252.241066
hout[10] = 76.672000
oout[] = 1.000000 sum = 270.011840
hout[10] = 76.672000
oout[] = 1.000000 sum = 284.185239
hout[10] = 76.672000
oout[] = 1.000000 sum = 295.485752
hout[10] = 76.672000
oout[] = 1.000000 sum = 304.494571
hout[10] = 76.672000
oout[] = 1.000000 sum = 311.676850
hout[10] = 76.672000
oout[] = 1.000000 sum = 317.404041
hout[10] = 76.672000
oout[] = 1.000000 sum = 321.972240
hout[10] = 76.672000
oout[] = 1.000000 sum = 325.617193
out[] = 1.000000
count = 1 tsmax = 2 tsignal = 76.825000
ct = 10
Eta = 0.750000 Alpha = 0.800000 ct = 10 tsmax = 2
hout[10] = 75.672000
oout[] = 1.000000 sum = 328.072610
hout[10] = 75.672000
oout[] = 1.000000 sum = 330.373848
hout[10] = 75.672000
oout[] = 1.000000 sum = 332.211104
hout[10] = 75.672000
oout[] = 1.000000 sum = 333.678426
hout[10] = 75.672000
oout[] = 1.000000 sum = 334.850643
hout[10] = 75.672000
oout[] = 1.000000 sum = 335.787342
hout[10] = 75.672000
oout[] = 1.000000 sum = 336.535999
hout[10] = 75.672000
oout[] = 1.000000 sum = 337.134469
hout[10] = 75.672000
oout[] = 1.000000 sum = 337.612949
hout[10] = 75.672000
oout[] = 1.000000 sum = 337.995542
hout[10] = 75.672000
oout[] = 1.000000 sum = 338.301494
hout[10] = 75.672000
oout[] = 1.000000 sum = 338.546175
hout[10] = 75.672000
oout[] = 1.000000 sum = 338.741869
hout[10] = 75.672000
oout[] = 1.000000 sum = 338.898392
hout[10] = 75.672000
oout[] = 1.000000 sum = 339.023589
out[] = 1.000000
count = 2 tsmax = 2 tsignal = 77.822000
原因がわかりません。
ご指摘をお願い致します。