現在、ニューラルネットワークの誤差逆伝搬法をC言語で作成しているのですが、
Target1とTarget2のどちらにあたっているかを教師信号1と0を与えて学習させて判定する予定なのですが、
(定義部分)
#define LAYER 3 //階層数
#define INPUT 2 //入力層数
#define HIDDEN 3 //隠れ層(中間層)数
#define OUTPUT 1 //出力層数
#define CTG 256 //カテゴリ数
・
・(長いため省略)
・
double i_lay[CTG][INPUT+1], //入力層の配列(バイアス+1)
h_lay[HIDDEN+1], //隠れ層の配列(バイアス+1)
o_lay[OUTPUT], //出力層の配列
teach[CTG][OUTPUT]; //教師信号の配列
下記の方法でファイルを開くと、1列256行のデータが縦に表示されてしまいます。(Targetのデータは256行あります)
(ファイルを開く部分)
fp = fopen( fname, "r" );
if( fp == NULL ){
printf( "%sファイルが開けません\n", fname );
return -1;
}
while( ( ret = fscanf( fp, "%lf, &i_lay[counter][1] ) != EOF ){
counter+=1;
}
fclose( fp );
現在はTaget1とTaget2が1列256行のデータが縦に表示されているため、Target1とTarget2の1行目のデータが教師信号を与えられて
学習してしまっていますので
例
≪Target1≫ ≪Target2≫ ≪教師信号≫
1行 1行 1
2行 2行 0
. .
. .
256行 256行
のようになってしまっているため、Target1とTarget2が混合されているためどちらにあたっているか分らない状態になっています。
↓ (変更したい形)
Taget1の1列256行のデータを横に表示させて、教師信号を1とし
Target2の1列256行のデータを横に表示させて、教師信号を0としたいと思っております。(Target1が正解の場合)
例
≪Target1≫1行 2行 ..............256行≪教師信号≫1
≪Target2≫1行 2行 ..............256行≪教師信号≫0
分りにくい説明になってしまったかもしれませんが、教えて下さい。
ファイルの出力方法
Re: ファイルの出力方法
まずフォーラムルールと投稿前チェックリストをお読みください。
そしてソースコードはcodeタグで囲んでください。
ファイルを開く方法と表示方法はほとんど関係ないと思います。
どのように読み込んだとしても、出力方法が間違っていたら希望する出力にはなりません。
リクさんが提示されたソースコードには出力部分が記載されていないようですから、アドバイスできません。
出力部分を含むソースコードをお示しください。(codeタグを用いてください)
そしてソースコードはcodeタグで囲んでください。
ファイルを開く方法と表示方法はほとんど関係ないと思います。
ここでいう「ファイルを開く」というのは、「ファイルの内容を読み込む」という意味でしょうか。リク さんが書きました:下記の方法でファイルを開くと、1列256行のデータが縦に表示されてしまいます。
どのように読み込んだとしても、出力方法が間違っていたら希望する出力にはなりません。
リクさんが提示されたソースコードには出力部分が記載されていないようですから、アドバイスできません。
出力部分を含むソースコードをお示しください。(codeタグを用いてください)
-
リク
Re: ファイルの出力方法
すいません。ルールを見ていませんでした。以後気をつけます。
ファイルを開くというのは、ファイルの内容を読み込むということです。
囲めていますか?もし、色が変わってなければ申し訳ございません。
現在、このコードを参考に動かしてみて正常に動けば自分の力で書きなおすつもりです。
まだ、掲示板に書き込むということに慣れていなく、気を悪くしてしまっていたら申し訳ございません。
ファイルを開くというのは、ファイルの内容を読み込むということです。
//重み,重み修正量の初期値の設定
for(j=0;j<HIDDEN;j++)
for(i=0;i<=INPUT;i++){
ih_w[i][j]=WD*drand();
ih_dw[i][j]=0.;
}
for(j=0;j<OUTPUT;j++)
for(i=0;i<=HIDDEN;i++){
ho_w[i][j]=WD*drand();
ho_dw[i][j]=0.;
}
/*繰り返し学習*/
for(ite=0;ite<=ITERATIONS; ite++){
for(ctg=0,err=0.;ctg<CTG;ctg++){
//隠れ層の出力計算
for(j=0;j<HIDDEN;j++){
for(i=0,sum=0.;i<=INPUT;i++)
sum += i_lay[CTG][i]*ih_w[i][j];
h_lay[j]=sigmoid(sum);
}
//出力層の出力計算
for(j=0;j<OUTPUT;j++){
for(i=0,sum=0.;i<=HIDDEN;i++)
sum+=h_lay[i]*ho_w[i][j];
o_lay[j]=sigmoid(sum);
}
//逆方向へ誤差の計算(デルタ)
for(i=0;i<OUTPUT;i++){
err+=sq(teach[ctg][i]-o_lay[i])/2./(double)CTG;
o_del[i]=EPSILON*(teach[ctg][i]-o_lay[i])*o_lay[i]*(1.-o_lay[i]);
}
//隠れ層の推定誤差
for(j=0;j<=HIDDEN;j++){
h_del[j]=0.;
for(i=0;i<OUTPUT;i++)
h_del[j]+=o_del[i]*ho_w[j][i];
h_del[j]*=EPSILON*h_lay[j]*(1.-h_lay[j]);
}
//結合荷重(慣性項を用いた重み)の修正量
for(j=0;j<=HIDDEN;j++)
for(i=0;i<OUTPUT;i++){
ho_dw[j][i]=ETA*o_del[i]*h_lay[j]+ALPHA*ho_dw[j][i];
ho_w[j][i]+=ho_dw[j][i];
}
for(j=0;j<=INPUT;j++)
for(i=0;i<HIDDEN;i++){
ih_dw[j][i]=ETA*h_del[i]*i_lay[CTG][j]+ALPHA*ih_dw[j][i];
ih_w[j][i]+=ih_dw[j][i];
}
}
/*結果の出力*/
fprintf(stderr,"iteration = %4d, error = %lf\n",ite,err);
//学習結果の検証(収束判定)
if((err<MIN_ERR)||(ite==ITERATIONS)){
for(ctg=0;ctg<CTG;ctg++){
fprintf(stderr,"ctg[%d] : ",ctg);
for(i=0;i<INPUT;i++)
fprintf(stderr,"i[%d] = %lf ",i,i_lay[CTG][i]);
//隠れ層の出力計算
for(j=0;j<HIDDEN;j++){
for(i=0,sum=0.;i<=INPUT;i++)
sum+=i_lay[CTG][i]*ih_w[i][j];
h_lay[j]=sigmoid(sum);
}
//出力層の出力計算
for(j=0;j<OUTPUT;j++){
for(i=0,sum=0.;i<=HIDDEN;i++)
sum+=h_lay[i]*ho_w[i][j];
o_lay[j]=sigmoid(sum);
fprintf(stderr,"o[%d] = %lf, t{%d] = %lf\n",j,o_lay[j],j,teach[ctg][j]);
}
}
fprintf(stderr,"iteration = %4d, error = %lf\n",ite,err);
break;
}
}
while(true)
{
}
}
/*シグモイド関数(活性化関数)*/
double sigmoid(double s)
{
/*double s;*/
double sm;
sm=EPSILON*s;
if(sm>SMAX) return(MAX);
else if(sm<SMIN) return(MIN);
else return(1./(1.+exp(-sm)));
}
現在、このコードを参考に動かしてみて正常に動けば自分の力で書きなおすつもりです。
まだ、掲示板に書き込むということに慣れていなく、気を悪くしてしまっていたら申し訳ございません。
Re: ファイルの出力方法
囲めているかどうかなどは投稿前にプレビューで確認する癖をつけましょう。リク さんが書きました:囲めていますか?もし、色が変わってなければ申し訳ございません。
codeタグでは囲めているものの途中からインデントがひどくなっており対応がわかりにくくなっております。
こちらにある投稿前チェックリストの「チェック3 : インデントを揃えよう」にてインデントについて確認してみてください。beatle さんが書きました:まずフォーラムルールと投稿前チェックリストをお読みください。
そしてソースコードはcodeタグで囲んでください。
-
リク
Re: ファイルの出力方法
//重み,重み修正量の初期値の設定
for(j=0;j<HIDDEN;j++)
for(i=0;i<=INPUT;i++)
{
ih_w[i][j]=WD*drand();
ih_dw[i][j]=0.;
}
for(j=0;j<OUTPUT;j++)
for(i=0;i<=HIDDEN;i++)
{
ho_w[i][j]=WD*drand();
ho_dw[i][j]=0.;
}
/*繰り返し学習*/
for(ite=0;ite<=ITERATIONS; ite++)
{
for(ctg=0,err=0.;ctg<CTG;ctg++)
{
//隠れ層の出力計算
for(j=0;j<HIDDEN;j++)
{
for(i=0,sum=0.;i<=INPUT;i++)
sum += i_lay[CTG][i]*ih_w[i][j];
h_lay[j]=sigmoid(sum);
}
//出力層の出力計算
for(j=0;j<OUTPUT;j++)
{
for(i=0,sum=0.;i<=HIDDEN;i++)
sum+=h_lay[i]*ho_w[i][j];
o_lay[j]=sigmoid(sum);
}
//逆方向へ誤差の計算(デルタ)
for(i=0;i<OUTPUT;i++)
{
err+=sq(teach[ctg][i]-o_lay[i])/2./(double)CTG;
o_del[i]=EPSILON*(teach[ctg][i]-o_lay[i])*o_lay[i]*(1.-o_lay[i]);
}
//隠れ層の推定誤差
for(j=0;j<=HIDDEN;j++)
{
h_del[j]=0.;
for(i=0;i<OUTPUT;i++)
h_del[j]+=o_del[i]*ho_w[j][i];
h_del[j]*=EPSILON*h_lay[j]*(1.-h_lay[j]);
}
//結合荷重(慣性項を用いた重み)の修正量
for(j=0;j<=HIDDEN;j++)
for(i=0;i<OUTPUT;i++)
{
ho_dw[j][i]=ETA*o_del[i]*h_lay[j]+ALPHA*ho_dw[j][i];
ho_w[j][i]+=ho_dw[j][i];
}
for(j=0;j<=INPUT;j++)
for(i=0;i<HIDDEN;i++)
{
ih_dw[j][i]=ETA*h_del[i]*i_lay[CTG][j]+ALPHA*ih_dw[j][i];
ih_w[j][i]+=ih_dw[j][i];
}
}
/*結果の出力*/
fprintf(stderr,"iteration = %4d, error = %lf\n",ite,err);
//学習結果の検証(収束判定)
if((err<MIN_ERR)||(ite==ITERATIONS))
{
for(ctg=0;ctg<CTG;ctg++)
{
fprintf(stderr,"ctg[%d] : ",ctg);
for(i=0;i<INPUT;i++)
fprintf(stderr,"i[%d] = %lf ",i,i_lay[CTG][i]);
//隠れ層の出力計算
for(j=0;j<HIDDEN;j++)
{
for(i=0,sum=0.;i<=INPUT;i++)
sum+=i_lay[CTG][i]*ih_w[i][j];
h_lay[j]=sigmoid(sum);
}
//出力層の出力計算
for(j=0;j<OUTPUT;j++)
{
for(i=0,sum=0.;i<=HIDDEN;i++)
sum+=h_lay[i]*ho_w[i][j];
o_lay[j]=sigmoid(sum);
fprintf(stderr,"o[%d] = %lf, t{%d] = %lf\n",j,o_lay[j],j,teach[ctg][j]);
}
}
fprintf(stderr,"iteration = %4d, error = %lf\n",ite,err);
break;
}
}
}
/*シグモイド関数(活性化関数)*/
double sigmoid(double s)
{
/*double s;*/
double sm;
sm=EPSILON*s;
if(sm>SMAX) return(MAX);
else if(sm<SMIN) return(MIN);
else return(1./(1.+exp(-sm)));
}
まだ見にくい部分があるかもしれませんが、宜しくお願いします。
Re: ファイルの出力方法
書き直してみた、というのは、インデントを直してみたということでしょうか。
だとしたらインデントについてきちんと勉強する必要がありますね。
具体的にはこういう部分が良くないのです。2番目のfor文は1番目のfor文より内側にありますから、1番目のfor文より
右側に書くべきなのです。こんな感じに。
だとしたらインデントについてきちんと勉強する必要がありますね。
具体的にはこういう部分が良くないのです。2番目のfor文は1番目のfor文より内側にありますから、1番目のfor文より
右側に書くべきなのです。こんな感じに。
-
リク
Re: ファイルの出力方法
これでどうでしょうか?
良ければ初めに質問した内容について何か解決案を教えて頂きたいです。
良ければ初めに質問した内容について何か解決案を教えて頂きたいです。
/*重み,重み修正量の初期値の設定*/
for(j=0;j<HIDDEN;j++)
{
for(i=0;i<=INPUT;i++)
{
ih_w[i][j]=WD*drand();
ih_dw[i][j]=0.;
}
}
for(j=0;j<OUTPUT;j++)
{
for(i=0;i<=HIDDEN;i++)
{
ho_w[i][j]=WD*drand();
ho_dw[i][j]=0.;
}
}
/*繰り返し学習*/
for(ite=0;ite<=ITERATIONS; ite++)
{
for(ctg=0,err=0.;ctg<CTG;ctg++)
{
/*隠れ層の出力計算*/
for(j=0;j<HIDDEN;j++)
{
for(i=0,sum=0.;i<=INPUT;i++)
{
sum += i_lay[CTG][i]*ih_w[i][j];
h_lay[j]=sigmoid(sum);
}
}
}
/*出力層の出力計算*/
for(j=0;j<OUTPUT;j++)
{
for(i=0,sum=0.;i<=HIDDEN;i++)
{
sum+=h_lay[i]*ho_w[i][j];
o_lay[j]=sigmoid(sum);
}
}
/*逆方向へ誤差の計算(デルタ)*/
for(i=0;i<OUTPUT;i++)
{
err+=sq(teach[ctg][i]-o_lay[i])/2./(double)CTG;
o_del[i]=EPSILON*(teach[ctg][i]-o_lay[i])*o_lay[i]*(1.-o_lay[i]);
}
/*隠れ層の推定誤差*/
for(j=0;j<=HIDDEN;j++)
{
h_del[j]=0.;
}
for(i=0;i<OUTPUT;i++)
{
h_del[j]+=o_del[i]*ho_w[j][i];
h_del[j]*=EPSILON*h_lay[j]*(1.-h_lay[j]);
}
/*結合荷重(慣性項を用いた重み)の修正量*/
for(j=0;j<=HIDDEN;j++)
{
for(i=0;i<OUTPUT;i++)
{
ho_dw[j][i]=ETA*o_del[i]*h_lay[j]+ALPHA*ho_dw[j][i];
ho_w[j][i]+=ho_dw[j][i];
}
}
for(j=0;j<=INPUT;j++)
{
for(i=0;i<HIDDEN;i++)
{
ih_dw[j][i]=ETA*h_del[i]*i_lay[CTG][j]+ALPHA*ih_dw[j][i];
ih_w[j][i]+=ih_dw[j][i];
}
}
/*結果の出力*/
fprintf(stderr,"iteration = %4d, error = %lf\n",ite,err);
/*学習結果の検証(収束判定)*/
if((err<MIN_ERR)||(ite==ITERATIONS))
{
for(ctg=0;ctg<CTG;ctg++)
{
fprintf(stderr,"ctg[%d] : ",ctg);
}
for(i=0;i<INPUT;i++)
{
fprintf(stderr,"i[%d] = %lf ",i,i_lay[CTG][i]);
}
}
/*隠れ層の出力計算*/
for(j=0;j<HIDDEN;j++)
{
for(i=0,sum=0.;i<=INPUT;i++)
{
sum+=i_lay[CTG][i]*ih_w[i][j];
h_lay[j]=sigmoid(sum);
}
}
/*出力層の出力計算*/
for(j=0;j<OUTPUT;j++)
{
for(i=0,sum=0.;i<=HIDDEN;i++)
{
sum+=h_lay[i]*ho_w[i][j];
o_lay[j]=sigmoid(sum);
fprintf(stderr,"o[%d] = %lf, t{%d] = %lf\n",j,o_lay[j],j,teach[ctg][j]);
}
fprintf(stderr,"iteration = %4d, error = %lf\n",ite,err);
break;
}
}/*繰り返し学習終了*/
/*シグモイド関数(活性化関数)*/
double sigmoid(double s)
{
double sm;
sm=EPSILON*s;
if(sm>SMAX) return(MAX);
else if(sm<SMIN) return(MIN);
else return(1./(1.+exp(-sm)));
}
Re: ファイルの出力方法
インデントを直すつもりはないでしょうか?
リクさんが載せているコー
ドは部分的なもので定
義などこち
らでは分からないものもあります
し、インデントが整っていないため非常に読みにくい
のです。
また、コメントも少なく何をやりたいかが見えづらいです。
こちらでコンパイルできない状態のコード
を載せて、部分
だ
けを確認したいのであれば、まずインデント
を整えて変数・定数などに説明(コメント)をつけませんか?
[hr]
さぁ、上の文はわざとこのように書かせていただいております。
あなたはこの文が読みやすいと思いますか?
インデントを整えてと言っているのは、上の文中にも書いておりますが、
括弧の対応など非常に読みにくく解析しにくいのです。
なので、まずそこからしっかりとやって頂きたいということです。
リクさんが載せているコー
ドは部分的なもので定
義などこち
らでは分からないものもあります
し、インデントが整っていないため非常に読みにくい
のです。
また、コメントも少なく何をやりたいかが見えづらいです。
こちらでコンパイルできない状態のコード
を載せて、部分
だ
けを確認したいのであれば、まずインデント
を整えて変数・定数などに説明(コメント)をつけませんか?
[hr]
さぁ、上の文はわざとこのように書かせていただいております。
あなたはこの文が読みやすいと思いますか?
インデントを整えてと言っているのは、上の文中にも書いておりますが、
括弧の対応など非常に読みにくく解析しにくいのです。
なので、まずそこからしっかりとやって頂きたいということです。
Re: ファイルの出力方法
インデントは兎も角、これは、ニューラルネットワークのことがわからないと解けない話なのでしょうか?
私は、ニューラルネットワークはやったことがないのでちんぷんかんぷんですが・・・
どのような配列や変数に格納されているものをどのような形で出力すればよいのかという話ではないのですか?
私では力になれないかもしれませんが・・・意味が分からない。
私は、ニューラルネットワークはやったことがないのでちんぷんかんぷんですが・・・
どのような配列や変数に格納されているものをどのような形で出力すればよいのかという話ではないのですか?
私では力になれないかもしれませんが・・・意味が分からない。
non