情報学部 | 菅沼ホーム | 目次 | 索引 |
/****************************/ /* Winner-Take-All Groups */ /* coded by Y.Suganuma */ /****************************/ #include <stdio.h> #include <stdlib.h> #include <time.h> #include "MT.h" /**********************/ /* Winnerクラスの定義 */ /**********************/ class Winner { long max; // 最大学習回数 long n; // 訓練例の数 long o; // 出力セルの数 long p; // 入力セルの数 long **W_p; // 重み(ポケット) long **W; // 重み long **E; // 訓練例 long **C; // 各訓練例に対する正しい出力 long *Ct; // 作業領域 public: Winner(long, long, long, long, long); ~Winner(); long Bunrui(); void Input(char *); void Learn(int, char *name = ""); long Pocket(long *); }; /******************/ /* コンストラクタ */ /******************/ Winner::Winner(long max_i, long n_i, long o_i, long p_i, long seed) { long i1; /* 設定 */ max = max_i; n = n_i; o = o_i; p = p_i; init_genrand(seed); /* 領域の確保 */ E = new long * [n]; C = new long * [n]; for (i1 = 0; i1 < n; i1++) { E[i1] = new long [p+1]; C[i1] = new long [o]; } W_p = new long * [o]; W = new long * [o]; for (i1 = 0; i1 < o; i1++) { W_p[i1] = new long [p+1]; W[i1] = new long [p+1]; } Ct = new long [o]; } /****************/ /* デストラクタ */ /****************/ Winner::~Winner() { int i1; for (i1 = 0; i1 < n; i1++) { delete [] E[i1]; delete [] C[i1]; } delete [] E; delete [] C; for (i1 = 0; i1 < o; i1++) { delete [] W_p[i1]; delete [] W[i1]; } delete [] W_p; delete [] W; delete [] Ct; } /******************************************/ /* 訓練例の分類 */ /* return : 正しく分類した訓練例の数 */ /******************************************/ long Winner::Bunrui() { long cor, i1, i2, i3, mx = 0, mx_v = 0, num = 0, s; int sw = 0; for (i1 = 0; i1 < n; i1++) { cor = 0; for (i2 = 0; i2 < o; i2++) { if (C[i1][i2] == 1) cor = i2; s = 0; for (i3 = 0; i3 <= p; i3++) s += W[i2][i3] * E[i1][i3]; if (i2 == 0) { mx = 0; mx_v = s; } else { if (s > mx_v) { mx = i2; mx_v = s; sw = 0; } else { if (s == mx_v) sw = 1; } } } if (sw == 0 && cor == mx) num++; } return num; } /**************************/ /* 学習データの読み込み */ /* name : ファイル名 */ /**************************/ void Winner::Input(char *name) { long i1, i2; FILE *st; st = fopen(name, "r"); fscanf(st, "%*s"); for (i1 = 0; i1 < n; i1++) { E[i1][0] = 1; for (i2 = 1; i2 <= p; i2++) fscanf(st, "%ld", &E[i1][i2]); for (i2 = 0; i2 < o; i2++) fscanf(st, "%ld", &C[i1][i2]); } fclose(st); } /*********************************/ /* 学習と結果の出力 */ /* seed : 乱数の初期値 */ /* pr : =0 : 画面に出力 */ /* =1 : ファイルに出力 */ /* name : 出力ファイル名 */ /*********************************/ void Winner::Learn(int pr, char *name) { long i1, i2, i3, mx = 0, mx_v = 0, n_tri, num, s; int sw; FILE *out; n_tri = Pocket(&num); if (pr == 0) out = stdout; else out = fopen(name, "w"); fprintf(out, "重み\n"); for (i1 = 0; i1 < o; i1++) { for (i2 = 0; i2 <= p; i2++) fprintf(out, "%5ld", W_p[i1][i2]); fprintf(out, "\n"); } fprintf(out, "分類結果\n"); for (i1 = 0; i1 < n; i1++) { sw = 0; for (i2 = 0; i2 < o; i2++) { s = 0; for (i3 = 0; i3 <= p; i3++) s += W_p[i2][i3] * E[i1][i3]; if (i2 == 0) { mx_v = s; mx = 0; } else { if (s > mx_v) { sw = 0; mx_v = s; mx = i2; } else { if (s == mx_v) sw = 1; } } } for (i2 = 1; i2 <= p; i2++) fprintf(out, "%2ld", E[i1][i2]); fprintf(out, " Cor "); for (i2 = 0; i2 < o; i2++) fprintf(out,"%2ld", C[i1][i2]); if (sw > 0) mx = -1; fprintf(out, " Res %2ld\n", mx+1); } if (n == num) printf(" !!すべてを分類(試行回数:%ld)\n", n_tri); else printf(" !!%ld 個を分類\n", num); } /********************************************/ /* Pocket Algorith with Ratcet */ /* num_p : 正しく分類した訓練例の数 */ /* return : =0 : 最大学習回数 */ /* >0 : すべてを分類(回数) */ /********************************************/ long Winner::Pocket(long *num_p) { long cor, count = 0, i1, i2, k, mx = 0, num, run = 0, run_p = 0, s, sw = -1; int sw1; /* 初期設定 */ *num_p = 0; for (i1 = 0; i1 < o; i1++) { for (i2 = 0; i2 <= p; i2++) W[i1][i2] = 0; } /* 実行 */ while (sw < 0) { // 終了チェック count++;; if (count > max) sw = 0; else { // 訓練例の選択 k = (long)(genrand_real3() * n); if (k >= n) k = n - 1; // 出力の計算 sw1 = 0; cor = -1; for (i1 = 0; i1 < o; i1++) { if (C[k][i1] == 1) cor = i1; s = 0; for (i2 = 0; i2 <= p; i2++) s += W[i1][i2] * E[k][i2]; Ct[i1] = s; if (i1 == 0) mx = 0; else { if (s > Ct[mx]) { mx = i1; sw1 = 0; } else { if (s == Ct[mx]) { sw1 = 1; if (cor >= 0 && mx == cor) mx = i1; } } } } // 正しい分類 if (sw1 == 0 && cor == mx) { run++; if (run > run_p) { num = Bunrui(); if (num > *num_p) { *num_p = num; run_p = run; for (i1 = 0; i1 < o; i1++) { for (i2 = 0; i2 <= p; i2++) W_p[i1][i2] = W[i1][i2]; } if (num == n) sw = count; } } } // 誤った分類 else { run = 0; for (i1 = 0; i1 <= p; i1++) { W[cor][i1] += E[k][i1]; W[mx][i1] -= E[k][i1]; } } } } return sw; } /****************/ /* main program */ /****************/ int main(int argc, char *argv[]) { long max, n, o, p; unsigned long seed = (unsigned)time(NULL); char name[100]; FILE *st; if (argc > 1) { // 基本データの入力 st = fopen(argv[1], "r"); fscanf(st, "%*s %ld %*s %ld %*s %ld %*s %ld", &max, &p, &o, &n); fscanf(st, "%*s %s", name); fclose(st); // ネットワークの定義と学習データ等の設定 Winner net(max, n, o, p, seed); net.Input(name); // 学習と結果の出力 if (argc == 2) net.Learn(0); else net.Learn(1, argv[2]); } else { printf("***error 入力データファイル名を指定して下さい\n"); exit(1); } return 0; } /* ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 //---------------------MT.h--------------------------- // A C-program for MT19937, with initialization improved 2002/1/26. // Coded by Takuji Nishimura and Makoto Matsumoto. // // Before using, initialize the state by using init_genrand(seed) // or init_by_array(init_key, key_length). // // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The names of its contributors may not be used to endorse or promote // products derived from this software without specific prior written // permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // // Any feedback is very welcome. // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html // email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) // The original version of http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c was modified by Takahiro Omi as // - delete line 47 "#include<stdio.h>" // - delete line 174 int main(void){...} // - change N -> MT_N // - change N -> MT_N // - change the file name "mt19937ar.c" -> "MT.h" // Period parameters #define MT_N 624 #define MT_M 397 #define MATRIX_A 0x9908b0dfUL // constant vector a #define UPPER_MASK 0x80000000UL // most significant w-r bits #define LOWER_MASK 0x7fffffffUL // least significant r bits static unsigned long mt[MT_N]; // the array for the state vector static int mti=MT_N+1; // mti==MT_N+1 means mt[MT_N] is not initialized // initializes mt[MT_N] with a seed void init_genrand(unsigned long s) { mt[0]= s & 0xffffffffUL; for (mti=1; mti<MT_N; mti++) { mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. // In the previous versions, MSBs of the seed affect // only MSBs of the array mt[]. // 2002/01/09 modified by Makoto Matsumoto mt[mti] &= 0xffffffffUL; // for >32 bit machines } } // initialize by an array with array-length // init_key is the array for initializing keys // key_length is its length // slight change for C++, 2004/2/26 void init_by_array(unsigned long init_key[], int key_length) { int i, j, k; init_genrand(19650218UL); i=1; j=0; k = (MT_N>key_length ? MT_N : key_length); for (; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + init_key[j] + j; // non linear mt[i] &= 0xffffffffUL; // for WORDSIZE > 32 machines i++; j++; if (i>=MT_N) { mt[0] = mt[MT_N-1]; i=1; } if (j>=key_length) j=0; } for (k=MT_N-1; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i; // non linear mt[i] &= 0xffffffffUL; // for WORDSIZE > 32 machines i++; if (i>=MT_N) { mt[0] = mt[MT_N-1]; i=1; } } mt[0] = 0x80000000UL; // MSB is 1; assuring non-zero initial array } // generates a random number on [0,0xffffffff]-interval unsigned long genrand_int32(void) { unsigned long y; static unsigned long mag01[2]={0x0UL, MATRIX_A}; // mag01[x] = x * MATRIX_A for x=0,1 if (mti >= MT_N) { // generate N words at one time int kk; if (mti == MT_N+1) // if init_genrand() has not been called, init_genrand(5489UL); // a default initial seed is used for (kk=0;kk<MT_N-MT_M;kk++) { y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); mt[kk] = mt[kk+MT_M] ^ (y >> 1) ^ mag01[y & 0x1UL]; } for (;kk<MT_N-1;kk++) { y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); mt[kk] = mt[kk+(MT_M-MT_N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; } y = (mt[MT_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); mt[MT_N-1] = mt[MT_M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; mti = 0; } y = mt[mti++]; // Tempering y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return y; } // generates a random number on [0,0x7fffffff]-interval long genrand_int31(void) { return (long)(genrand_int32()>>1); } // generates a random number on [0,1]-real-interval double genrand_real1(void) { return genrand_int32()*(1.0/4294967295.0); // divided by 2^32-1 } // generates a random number on [0,1)-real-interval double genrand_real2(void) { return genrand_int32()*(1.0/4294967296.0); // divided by 2^32 } // generates a random number on (0,1)-real-interval double genrand_real3(void) { return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); // divided by 2^32 } // generates a random number on [0,1) with 53-bit resolution double genrand_res53(void) { unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; return(a*67108864.0+b)*(1.0/9007199254740992.0); } // These real versions are due to Isaku Wada, 2002/01/09 added */
/****************************/ /* Winner-Take-All Groups */ /* coded by Y.Suganuma */ /****************************/ import java.io.*; import java.util.Random; import java.util.StringTokenizer; public class Test { /****************/ /* main program */ /****************/ public static void main(String args[]) throws IOException, FileNotFoundException { int max, n, o, p; StringTokenizer str; String name; if (args.length > 0) { // 基本データの入力 BufferedReader in = new BufferedReader(new FileReader(args[0])); str = new StringTokenizer(in.readLine(), " "); str.nextToken(); max = Integer.parseInt(str.nextToken()); str.nextToken(); p = Integer.parseInt(str.nextToken()); str.nextToken(); o = Integer.parseInt(str.nextToken()); str.nextToken(); n = Integer.parseInt(str.nextToken()); str = new StringTokenizer(in.readLine(), " "); str.nextToken(); name = str.nextToken(); in.close(); // ネットワークの定義 Winner net = new Winner (max, n, o, p); net.input(name); // 学習と結果の出力 if (args.length == 1) net.learn(0, ""); else net.learn(1, args[1]); } // エラー else { System.out.print("***error 入力データファイル名を指定して下さい\n"); System.exit(1); } } } /**********************/ /* Winnerクラスの定義 */ /**********************/ class Winner { private int max; // 最大学習回数 private int n; // 訓練例の数 private int o; // 出力セルの数 private int p; // 入力セルの数 private int W_p[][]; // 重み(ポケット) private int W[][]; // 重み private int E[][]; // 訓練例 private int C[][]; // 各訓練例に対する正しい出力 private int Ct[]; // 作業領域 private Random rn; // 乱数 /******************/ /* コンストラクタ */ /******************/ Winner (int max_i, int n_i, int o_i, int p_i) { /* 設定 */ max = max_i; n = n_i; o = o_i; p = p_i; rn = new Random(); // 乱数の初期設定 /* 領域の確保 */ E = new int [n][p+1]; W_p = new int [o][p+1]; W = new int [o][p+1]; C = new int [n][o]; Ct = new int [o]; } /******************************************/ /* 訓練例の分類 */ /* return : 正しく分類した訓練例の数 */ /******************************************/ int bunrui() { int cor, i1, i2, i3, mx = 0, mx_v = 0, num = 0, s, sw = 0; for (i1 = 0; i1 < n; i1++) { cor = 0; for (i2 = 0; i2 < o; i2++) { if (C[i1][i2] == 1) cor = i2; s = 0; for (i3 = 0; i3 <= p; i3++) s += W[i2][i3] * E[i1][i3]; if (i2 == 0) { mx = 0; mx_v = s; } else { if (s > mx_v) { mx = i2; mx_v = s; sw = 0; } else { if (s == mx_v) sw = 1; } } } if (sw == 0 && cor == mx) num++; } return num; } /**************************/ /* 学習データの読み込み */ /* name : ファイル名 */ /**************************/ void input (String name) throws IOException, FileNotFoundException { int i1, i2; StringTokenizer str; BufferedReader st = new BufferedReader(new FileReader(name)); str = new StringTokenizer(st.readLine(), " "); for (i1 = 0; i1 < n; i1++) { E[i1][0] = 1; str = new StringTokenizer(st.readLine(), " "); for (i2 = 1; i2 <= p; i2++) E[i1][i2] = Integer.parseInt(str.nextToken()); for (i2 = 0; i2 < o; i2++) C[i1][i2] = Integer.parseInt(str.nextToken()); } st.close(); } /*********************************/ /* 学習と結果の出力 */ /* pr : =0 : 画面に出力 */ /* =1 : ファイルに出力 */ /* name : 出力ファイル名 */ /*********************************/ void learn(int pr, String name) throws FileNotFoundException { int i1, i2, i3, mx = 0, mx_v = 0, n_tri, s, sw; int num[] = new int [1]; // 学習 n_tri = pocket(num); // 結果の出力 if (pr == 0) { System.out.print("重み\n"); for (i1 = 0; i1 < o; i1++) { for (i2 = 0; i2 <= p; i2++) System.out.print(" " + W_p[i1][i2]); System.out.println(); } System.out.print("分類結果\n"); for (i1 = 0; i1 < n; i1++) { sw = 0; for (i2 = 0; i2 < o; i2++) { s = 0; for (i3 = 0; i3 <= p; i3++) s += W_p[i2][i3] * E[i1][i3]; if (i2 == 0) { mx_v = s; mx = 0; } else { if (s > mx_v) { sw = 0; mx_v = s; mx = i2; } else { if (s == mx_v) sw = 1; } } } for (i2 = 1; i2 <= p; i2++) System.out.print(" " + E[i1][i2]); System.out.print(" Cor "); for (i2 = 0; i2 < o; i2++) System.out.print(" " + C[i1][i2]); if (sw > 0) mx = -1; System.out.println(" Res " + (mx+1)); } } else { PrintStream out = new PrintStream(new FileOutputStream(name)); out.print("重み\n"); for (i1 = 0; i1 < o; i1++) { for (i2 = 0; i2 <= p; i2++) out.print(" " + W_p[i1][i2]); out.println(); } out.print("分類結果\n"); for (i1 = 0; i1 < n; i1++) { sw = 0; for (i2 = 0; i2 < o; i2++) { s = 0; for (i3 = 0; i3 <= p; i3++) s += W_p[i2][i3] * E[i1][i3]; if (i2 == 0) { mx_v = s; mx = 0; } else { if (s > mx_v) { sw = 0; mx_v = s; mx = i2; } else { if (s == mx_v) sw = 1; } } } for (i2 = 1; i2 <= p; i2++) out.print(" " + E[i1][i2]); out.print(" Cor "); for (i2 = 0; i2 < o; i2++) out.print(" " + C[i1][i2]); if (sw > 0) mx = -1; out.println(" Res " + (mx+1)); } out.close(); } if (n == num[0]) System.out.print(" !!すべてを分類(試行回数:" + n_tri + ")\n"); else System.out.print(" !!" + num[0] + " 個を分類\n"); } /********************************************/ /* Pocket Algorith with Ratcet */ /* num_p : 正しく分類した訓練例の数 */ /* return : =0 : 最大学習回数 */ /* >0 : すべてを分類(回数) */ /********************************************/ int pocket(int num_p[]) { int cor, count = 0, i1, i2, k, mx = 0, num, run = 0, run_p = 0, s, sw = -1, sw1; /* 初期設定 */ num_p[0] = 0; for (i1 = 0; i1 < o; i1++) { for (i2 = 0; i2 <= p; i2++) W[i1][i2] = 0; } /* 実行 */ while (sw < 0) { // 終了チェック count++;; if (count > max) sw = 0; else { // 訓練例の選択 k = (int)(rn.nextDouble() * n); if (k >= n) k = n - 1; // 出力の計算 sw1 = 0; cor = -1; for (i1 = 0; i1 < o; i1++) { if (C[k][i1] == 1) cor = i1; s = 0; for (i2 = 0; i2 <= p; i2++) s += W[i1][i2] * E[k][i2]; Ct[i1] = s; if (i1 == 0) mx = 0; else { if (s > Ct[mx]) { mx = i1; sw1 = 0; } else { if (s == Ct[mx]) { sw1 = 1; if (cor >= 0 && mx == cor) mx = i1; } } } } // 正しい分類 if (sw1 == 0 && cor == mx) { run++; if (run > run_p) { num = bunrui(); if (num > num_p[0]) { num_p[0] = num; run_p = run; for (i1 = 0; i1 < o; i1++) { for (i2 = 0; i2 <= p; i2++) W_p[i1][i2] = W[i1][i2]; } if (num == n) sw = count; } } } // 誤った分類 else { run = 0; for (i1 = 0; i1 <= p; i1++) { W[cor][i1] += E[k][i1]; W[mx][i1] -= E[k][i1]; } } } } return sw; } } /* ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 */
<!DOCTYPE HTML> <HTML> <HEAD> <TITLE>Winner-Take-All Groups</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <SCRIPT TYPE="text/javascript"> res = ""; net = null; /****************/ /* main program */ /****************/ function main() { // 基本データの入力 let max = parseInt(document.getElementById("max").value); let p = parseInt(document.getElementById("p").value); let o = parseInt(document.getElementById("o").value); let n = parseInt(document.getElementById("n").value); // ネットワークの定義 net = new Winner (max, n, o, p); net.input(); // 学習と結果の出力 net.learn(); document.getElementById("result").value = res; } /**********************/ /* Winnerオブジェクト */ /**********************/ function Winner(max_i, n_i, o_i, p_i) { // // 設定 // this.max = max_i; this.n = n_i; this.o = o_i; this.p = p_i; // // 領域の確保 // this.E = new Array(this.n); this.W_p = new Array(this.o); this.W = new Array(this.o); this.C = new Array(this.n); for (let i1 = 0; i1 < this.n; i1++) { this.E[i1] = new Array(this.p+1); this.C[i1] = new Array(this.o); } for (let i1 = 0; i1 < this.o; i1++) { this.W_p[i1] = new Array(this.p+1); this.W[i1] = new Array(this.p+1); } this.Ct = new Array(this.o); } /******************************************/ /* 訓練例の分類 */ /* return : 正しく分類した訓練例の数 */ /******************************************/ Winner.prototype.bunrui = function() { let mx = 0, mx_v = 0, num = 0, sw = 0; for (let i1 = 0; i1 < net.n; i1++) { let cor = 0; for (let i2 = 0; i2 < net.o; i2++) { if (net.C[i1][i2] == 1) cor = i2; let s = 0; for (let i3 = 0; i3 <= net.p; i3++) s += net.W[i2][i3] * net.E[i1][i3]; if (i2 == 0) { mx = 0; mx_v = s; } else { if (s > mx_v) { mx = i2; mx_v = s; sw = 0; } else { if (s == mx_v) sw = 1; } } } if (sw == 0 && cor == mx) num++; } return num; } /************************/ /* 学習データの読み込み */ /************************/ Winner.prototype.input = function() { let lines = (document.getElementById("data").value).split('\n'); for (let i1 = 0; i1 < net.n; i1++) { let str = lines[1+i1].split(' ').filter(function(e){return e.length > 0;}); net.E[i1][0] = 1; for (let i2 = 1; i2 <= net.p; i2++) net.E[i1][i2] = parseInt(str[i2-1]); for (let i2 = 0; i2 < net.o; i2++) net.C[i1][i2] = parseInt(str[net.p+i2]); } } /*********************************/ /* 学習と結果の出力 */ /*********************************/ Winner.prototype.learn = function() { // 学習 let num = new Array(1); let n_tri = net.pocket(num); // 結果の出力 res += ("重み\n"); for (let i1 = 0; i1 < net.o; i1++) { for (let i2 = 0; i2 <= net.p; i2++) res += (" " + net.W_p[i1][i2]); res += "\n"; } res += ("分類結果\n"); let mx = 0; let mx_v = 0; for (let i1 = 0; i1 < net.n; i1++) { let sw = 0; for (let i2 = 0; i2 < net.o; i2++) { let s = 0; for (let i3 = 0; i3 <= net.p; i3++) s += net.W_p[i2][i3] * net.E[i1][i3]; if (i2 == 0) { mx_v = s; mx = 0; } else { if (s > mx_v) { sw = 0; mx_v = s; mx = i2; } else { if (s == mx_v) sw = 1; } } } for (let i2 = 1; i2 <= net.p; i2++) res += (" " + net.E[i1][i2]); res += " Cor "; for (let i2 = 0; i2 < net.o; i2++) res += (" " + net.C[i1][i2]); if (sw > 0) mx = -1; res += (" Res " + (mx+1) + "\n"); } if (net.n == num[0]) res += (" !!すべてを分類(試行回数:" + n_tri + ")\n"); else res += (" !!" + num[0] + " 個を分類\n"); } /********************************************/ /* Pocket Algorith with Ratcet */ /* num_p : 正しく分類した訓練例の数 */ /* return : =0 : 最大学習回数 */ /* >0 : すべてを分類(回数) */ /********************************************/ Winner.prototype.pocket = function(num_p) { // // 初期設定 // num_p[0] = 0; let count = 0, mx = 0, run = 0, run_p = 0, sw = -1; for (let i1 = 0; i1 < net.o; i1++) { for (let i2 = 0; i2 <= net.p; i2++) net.W[i1][i2] = 0; } // // 実行 // while (sw < 0) { // 終了チェック count++;; if (count > net.max) sw = 0; else { // 訓練例の選択 let k = Math.floor(Math.random() * net.n); if (k >= net.n) k = net.n - 1; // 出力の計算 let sw1 = 0; let cor = -1; for (let i1 = 0; i1 < net.o; i1++) { if (net.C[k][i1] == 1) cor = i1; let s = 0; for (let i2 = 0; i2 <= net.p; i2++) s += net.W[i1][i2] * net.E[k][i2]; net.Ct[i1] = s; if (i1 == 0) mx = 0; else { if (s > net.Ct[mx]) { mx = i1; sw1 = 0; } else { if (s == net.Ct[mx]) { sw1 = 1; if (cor >= 0 && mx == cor) mx = i1; } } } } // 正しい分類 if (sw1 == 0 && cor == mx) { run++; if (run > run_p) { let num = net.bunrui(); if (num > num_p[0]) { num_p[0] = num; run_p = run; for (let i1 = 0; i1 < net.o; i1++) { for (let i2 = 0; i2 <= net.p; i2++) net.W_p[i1][i2] = net.W[i1][i2]; } if (num == net.n) sw = count; } } } // 誤った分類 else { run = 0; for (let i1 = 0; i1 <= net.p; i1++) { net.W[cor][i1] += net.E[k][i1]; net.W[mx][i1] -= net.E[k][i1]; } } } } return sw; } </SCRIPT> </HEAD> <BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;"> <H2><B>Winner-Take-All Groups</B></H2> 最大試行回数:<INPUT ID="max" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="100"> 入力セル数:<INPUT ID="p" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="2"> 出力セル数:<INPUT ID="o" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="2"> 訓練例数:<INPUT ID="n" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="4"> <BUTTON STYLE="font-size: 100%; background-color: pink" onClick="return main()">実行</BUTTON><BR> <DIV STYLE="width: 800px; margin-right: auto; margin-left: auto"> <DIV STYLE="text-align:center; float: right; width: 400px"> <DIV STYLE="text-align:center">分類結果</DIV> <TEXTAREA ID="result" COLS="35" ROWS="10" STYLE="font-size: 100%; width: 380px"> </TEXTAREA> </DIV> <DIV STYLE="text-align:center; width: 400px"> <DIV STYLE="text-align:center">入力データ</DIV> <TEXTAREA ID="data" COLS="35" ROWS="10" STYLE="font-size: 100%; width: 380px"> OR演算の訓練例.各行の最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 </TEXTAREA> </DIV> </DIV> </BODY> </HTML>
<?php /****************************/ /* Winner-Take-All Groups */ /* coded by Y.Suganuma */ /****************************/ /**********************/ /* Winnerクラスの定義 */ /**********************/ class Winner { private $max; // 最大学習回数 private $n; // 訓練例の数 private $o; // 出力セルの数 private $p; // 入力セルの数 private $W_p; // 重み(ポケット) private $W; // 重み private $E; // 訓練例 private $C; // 各訓練例に対する正しい出力 private $Ct; // 作業領域 /******************/ /* コンストラクタ */ /******************/ function Winner($max_i, $n_i, $o_i, $p_i) { /* 設定 */ $this->max = $max_i; $this->n = $n_i; $this->o = $o_i; $this->p = $p_i; mt_srand(); /* 領域の確保 */ $this->E = array($this->n); $this->C = array($this->n); for ($i1 = 0; $i1 < $this->n; $i1++) { $this->E[$i1] = array($this->p+1); $this->C[$i1] = array($this->o); } $this->W_p = array($this->o); $this->W = array($this->o); for ($i1 = 0; $i1 < $this->o; $i1++) { $this->W_p[$i1] = array($this->p+1); $this->W[$i1] = array($this->p+1); } $this->Ct = array($this->o); } /******************************************/ /* 訓練例の分類 */ /* return : 正しく分類した訓練例の数 */ /******************************************/ function Bunrui() { $mx = 0; $mx_v = 0; $num = 0; $sw = 0; for ($i1 = 0; $i1 < $this->n; $i1++) { $cor = 0; for ($i2 = 0; $i2 < $this->o; $i2++) { if ($this->C[$i1][$i2] == 1) $cor = $i2; $s = 0; for ($i3 = 0; $i3 <= $this->p; $i3++) $s += $this->W[$i2][$i3] * $this->E[$i1][$i3]; if ($i2 == 0) { $mx = 0; $mx_v = $s; } else { if ($s > $mx_v) { $mx = $i2; $mx_v = $s; $sw = 0; } else { if ($s == $mx_v) $sw = 1; } } } if ($sw == 0 && $cor == $mx) $num++; } return $num; } /**************************/ /* 学習データの読み込み */ /* name : ファイル名 */ /**************************/ function Input($name) { $st = fopen($name, "rb"); fgets($st); for ($i1 = 0; $i1 < $this->n; $i1++) { $this->E[$i1][0] = 1; $str = trim(fgets($st)); $this->E[$i1][1] = intval(strtok($str, " ")); for ($i2 = 2; $i2 <= $this->p; $i2++) $this->E[$i1][$i2] = intval(strtok(" ")); for ($i2 = 0; $i2 < $this->o; $i2++) $this->C[$i1][$i2] = intval(strtok(" ")); } fclose($st); } /*********************************/ /* 学習と結果の出力 */ /* pr : =0 : 画面に出力 */ /* =1 : ファイルに出力 */ /* name : 出力ファイル名 */ /*********************************/ function Learn($pr, $name = "STDOUT") { $mx = 0; $mx_v = 0; $n_tri = $this->Pocket($num); if ($pr == 0) $out = STDOUT; else $out = fopen($name, "w"); fwrite($out, "重み\n"); for ($i1 = 0; $i1 < $this->o; $i1++) { $str = ""; for ($i2 = 0; $i2 <= $this->p; $i2++) $str = $str." ".$this->W_p[$i1][$i2]; fwrite($out, $str."\n"); } fwrite($out, "分類結果\n"); for ($i1 = 0; $i1 < $this->n; $i1++) { $sw = 0; for ($i2 = 0; $i2 < $this->o; $i2++) { $s = 0; for ($i3 = 0; $i3 <= $this->p; $i3++) $s += $this->W_p[$i2][$i3] * $this->E[$i1][$i3]; if ($i2 == 0) { $mx_v = $s; $mx = 0; } else { if ($s > $mx_v) { $sw = 0; $mx_v = $s; $mx = $i2; } else { if ($s == $mx_v) $sw = 1; } } } $str = ""; for ($i2 = 1; $i2 <= $this->p; $i2++) $str = $str." ".$this->E[$i1][$i2]; $str = $str." Cor "; for ($i2 = 0; $i2 < $this->o; $i2++) $str = $str." ".$this->C[$i1][$i2]; if ($sw > 0) $mx = -1; $str = $str." Res ".($mx+1); fwrite($out, $str."\n"); } if ($this->n == $num) printf(" !!すべてを分類(試行回数:%ld)\n", $n_tri); else printf(" !!%ld 個を分類\n", $num); } /********************************************/ /* Pocket Algorith with Ratcet */ /* num_p : 正しく分類した訓練例の数 */ /* return : =0 : 最大学習回数 */ /* >0 : すべてを分類(回数) */ /********************************************/ function Pocket(&$num_p) { /* 初期設定 */ $count = 0; $mx = 0; $run = 0; $run_p = 0; $sw = -1; $num_p = 0; for ($i1 = 0; $i1 < $this->o; $i1++) { for ($i2 = 0; $i2 <= $this->p; $i2++) $this->W[$i1][$i2] = 0; } /* 実行 */ while ($sw < 0) { // 終了チェック $count++;; if ($count > $this->max) $sw = 0; else { // 訓練例の選択 $k = intval(mt_rand() / mt_getrandmax() * $this->n); if ($k >= $this->n) $k = $this->n - 1; // 出力の計算 $sw1 = 0; $cor = -1; for ($i1 = 0; $i1 < $this->o; $i1++) { if ($this->C[$k][$i1] == 1) $cor = $i1; $s = 0; for ($i2 = 0; $i2 <= $this->p; $i2++) $s += $this->W[$i1][$i2] * $this->E[$k][$i2]; $this->Ct[$i1] = $s; if ($i1 == 0) $mx = 0; else { if ($s > $this->Ct[$mx]) { $mx = $i1; $sw1 = 0; } else { if ($s == $this->Ct[$mx]) { $sw1 = 1; if ($cor >= 0 && $mx == $cor) $mx = $i1; } } } } // 正しい分類 if ($sw1 == 0 && $cor == $mx) { $run++; if ($run > $run_p) { $num = $this->Bunrui(); if ($num > $num_p) { $num_p = $num; $run_p = $run; for ($i1 = 0; $i1 < $this->o; $i1++) { for ($i2 = 0; $i2 <= $this->p; $i2++) $this->W_p[$i1][$i2] = $this->W[$i1][$i2]; } if ($num == $this->n) $sw = $count; } } } // 誤った分類 else { $run = 0; for ($i1 = 0; $i1 <= $this->p; $i1++) { $this->W[$cor][$i1] += $this->E[$k][$i1]; $this->W[$mx][$i1] -= $this->E[$k][$i1]; } } } } return $sw; } } /****************/ /* main program */ /****************/ if (count($argv) > 1) { // 基本データの入力 $st = fopen($argv[1], "rb"); fscanf($st, "%*s %ld %*s %ld %*s %ld %*s %ld",$max, $p, $o, $n); fscanf($st, "%*s %s", $name); fclose($st); // ネットワークの定義と学習データ等の設定 $net = new Winner($max, $n, $o, $p); $net->Input($name); // 学習と結果の出力 if (count($argv) == 2) $net->Learn(0); else $net->Learn(1, $argv[2]); } else exit("***error 入力データファイル名を指定して下さい\n"); /* ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 */ ?>
#################################### # Winner-Take-All Groups # coded by Y.Suganuma #################################### ############################# # Winnerクラスの定義 # coded by Y.Suganuma ############################# class Winner ######################### # コンストラクタ # max : 最大学習回数 # n : 訓練例の数 # o : 出力セルの数 # p : 入力セルの数 ######################### def initialize(max_i, n_i, o_i, p_i) # 設定 @_max = max_i @_n = n_i @_o = o_i @_p = p_i # 領域の確保 @_e = Array.new(@_n) # 訓練例 @_c = Array.new(@_n) # 各訓練例に対する正しい出力 for i1 in 0 ... @_n @_e[i1] = Array.new(@_p+1) @_c[i1] = Array.new(@_o) end @_w_p = Array.new(@_o) # 重み(ポケット) @_w = Array.new(@_o) # 重み for i1 in 0 ... @_o @_w_p[i1] = Array.new(@_p+1) @_w[i1] = Array.new(@_p+1) end @_ct = Array.new(@_o) # 作業領域 end ######################################### # 訓練例の分類 # return : 正しく分類した訓練例の数 ######################################### def Bunrui() mx = 0 mx_v = 0 num = 0 sw = 0 for i1 in 0 ... @_n cor = 0 for i2 in 0 ... @_o if @_c[i1][i2] == 1 cor = i2 end s = 0 for i3 in 0 ... @_p+1 s += @_w[i2][i3] * @_e[i1][i3] end if i2 == 0 mx = 0 mx_v = s else if s > mx_v mx = i2 mx_v = s sw = 0 else if s == mx_v sw = 1 end end end end if sw == 0 and cor == mx num += 1 end end return num end #*************************/ # 学習データの読み込み */ # name : ファイル名 */ #*************************/ def Input(name) f = open(name, "r") f.gets() for i1 in 0 ... @_n @_e[i1][0] = 1 s = f.gets().split(" ") for i2 in 1 ... @_p+1 @_e[i1][i2] = Integer(s[i2-1]) end for i2 in 0 ... @_o @_c[i1][i2] = Integer(s[@_p+i2]) end end f.close() end ################################# # 学習と結果の出力 # pr : =0 : 画面に出力 # =1 : ファイルに出力 # name : 出力ファイル名 ################################# def Learn(pr, name="") mx = 0 mx_v = 0 num = Array.new(1) n_tri = Pocket(num) if pr == 0 out = $stdout else out = open(name, "w") end out.print("重み\n") for i1 in 0 ... @_o for i2 in 0 ... @_p+1 out.print(" " + String(@_w_p[i1][i2])) end out.print("\n") end out.print("分類結果\n") for i1 in 0 ... @_n sw = 0 for i2 in 0 ... @_o s = 0 for i3 in 0 ... @_p+1 s += @_w_p[i2][i3] * @_e[i1][i3] end if i2 == 0 mx_v = s mx = 0 else if s > mx_v sw = 0 mx_v = s mx = i2 else if s == mx_v sw = 1 end end end end for i2 in 1 ... @_p+1 out.print(" " + String(@_e[i1][i2])) end out.print(" Cor ") for i2 in 0 ... @_o out.print(" " + String(@_c[i1][i2])) end if sw > 0 mx = -1 end out.print(" Res " + String(mx+1) + "\n") end if @_n == num[0] print(" !!すべてを分類(試行回数:" + String(n_tri) + ")\n") else print(" !!" + String(num[0]) + " 個を分類\n") end end ############################################ # Pocket Algorith with Ratcet # num_p : 正しく分類した訓練例の数 # return : =0 : 最大学習回数 # >0 : すべてを分類(回数) ############################################ def Pocket(num_p) # 初期設定 count = 0 mx = 0 run = 0 run_p = 0 sw = -1 num_p[0] = 0 for i1 in 0 ... @_o for i2 in 0 ... @_p+1 @_w[i1][i2] = 0 end end # 実行 while sw < 0 # 終了チェック count += 1 if count > @_max sw = 0 else # 訓練例の選択 k = Integer(rand(0) * @_n) if k >= @_n k = @_n - 1 end # 出力の計算 sw1 = 0 cor = -1 for i1 in 0 ... @_o if @_c[k][i1] == 1 cor = i1 end s = 0 for i2 in 0 ... @_p+1 s += @_w[i1][i2] * @_e[k][i2] end @_ct[i1] = s if i1 == 0 mx = 0 else if s > @_ct[mx] mx = i1 sw1 = 0 else if s == @_ct[mx] sw1 = 1 if cor >= 0 and mx == cor mx = i1 end end end end end # 正しい分類 if sw1 == 0 and cor == mx run += 1 if run > run_p num = Bunrui() if num > num_p[0] num_p[0] = num run_p = run for i1 in 0 ... @_o for i2 in 0 ... @_p+1 @_w_p[i1][i2] = @_w[i1][i2] end end if num == @_n sw = count end end end # 誤った分類 else run = 0 for i1 in 0 ... @_p+1 @_w[cor][i1] += @_e[k][i1] @_w[mx][i1] -= @_e[k][i1] end end end end return sw end end if ARGV[0] != nil # 基本データの入力 s = gets().split(" ") max = Integer(s[1]) p = Integer(s[3]) o = Integer(s[5]) n = Integer(s[7]) s = gets().split(" ") name = s[1] # ネットワークの定義 srand() net = Winner.new(max, n, o, p) net.Input(name) # 学習と結果の出力 if ARGV[0] == nil net.Learn(0) else net.Learn(1, ARGV[0]) end else print("***error 入力ファイル名を指定して下さい\n") end =begin ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 =end
# -*- coding: UTF-8 -*- import numpy as np import sys from math import * from random import * ############################# # Winnerクラスの定義 # coded by Y.Suganuma ############################# class Winner : ######################### # コンストラクタ # max : 最大学習回数 # n : 訓練例の数 # o : 出力セルの数 # p : 入力セルの数 ######################### def __init__(self, max_i, n_i, o_i, p_i) : # 設定 self.max = max_i self.n = n_i self.o = o_i self.p = p_i # 領域の確保 self.E = np.empty((self.n, self.p+1), np.int) # 訓練例 self.C = np.empty((self.n, self.o), np.int) # 各訓練例に対する正しい出力 self.W_p = np.empty((self.o, self.p+1), np.int) # 重み(ポケット) self.W = np.empty((self.o, self.p+1), np.int) # 重み self.Ct = np.empty(self.o, np.int) # 作業領域 ######################################### # 訓練例の分類 # return : 正しく分類した訓練例の数 ######################################### def Bunrui(self) : mx = 0 mx_v = 0 num = 0 sw = 0 for i1 in range(0, self.n) : cor = 0 for i2 in range(0, self.o) : if self.C[i1][i2] == 1 : cor = i2 s = 0 for i3 in range(0, self.p+1) : s += self.W[i2][i3] * self.E[i1][i3] if i2 == 0 : mx = 0 mx_v = s else : if s > mx_v : mx = i2 mx_v = s sw = 0 else : if s == mx_v : sw = 1 if sw == 0 and cor == mx : num += 1 return num #*************************/ # 学習データの読み込み */ # name : ファイル名 */ #*************************/ def Input(self, name) : f = open(name, "r") f.readline() for i1 in range(0, self.n) : self.E[i1][0] = 1 s = f.readline().split() for i2 in range(1, self.p+1) : self.E[i1][i2] = int(s[i2-1]) for i2 in range(0, self.o) : self.C[i1][i2] = int(s[self.p+i2]) f.close() ################################# # 学習と結果の出力 # pr : =0 : 画面に出力 # =1 : ファイルに出力 # name : 出力ファイル名 ################################# def Learn(self, pr, name="") : mx = 0 mx_v = 0 num = np.empty(1, np.int) n_tri = self.Pocket(num) if pr == 0 : out = sys.stdout else : out = open(name, "w") out.write("重み\n") for i1 in range(0, self.o) : for i2 in range(0, self.p+1) : out.write(" " + str(self.W_p[i1][i2])) out.write("\n") out.write("分類結果\n") for i1 in range(0, self.n) : sw = 0 for i2 in range(0, self.o) : s = 0 for i3 in range(0, self.p+1) : s += self.W_p[i2][i3] * self.E[i1][i3] if i2 == 0 : mx_v = s mx = 0 else : if s > mx_v : sw = 0 mx_v = s mx = i2 else : if s == mx_v : sw = 1 for i2 in range(1, self.p+1) : out.write(" " + str(self.E[i1][i2])) out.write(" Cor ") for i2 in range(0, self.o) : out.write(" " + str(self.C[i1][i2])) if sw > 0 : mx = -1 out.write(" Res " + str(mx+1) + "\n") if self.n == num[0] : print(" !!すべてを分類(試行回数:" + str(n_tri) + ")") else : print(" !!" + str(num[0]) + " 個を分類") ############################################ # Pocket Algorith with Ratcet # num_p : 正しく分類した訓練例の数 # return : =0 : 最大学習回数 # >0 : すべてを分類(回数) ############################################ def Pocket(self, num_p) : # 初期設定 count = 0 mx = 0 run = 0 run_p = 0 sw = -1 num_p[0] = 0 for i1 in range(0, self.o) : for i2 in range(0, self.p+1) : self.W[i1][i2] = 0 # 実行 while sw < 0 : # 終了チェック count += 1 if count > self.max : sw = 0 else : # 訓練例の選択 k = int(random() * self.n) if k >= self.n : k = self.n - 1 # 出力の計算 sw1 = 0 cor = -1 for i1 in range(0, self.o) : if self.C[k][i1] == 1 : cor = i1 s = 0 for i2 in range(0, self.p+1) : s += self.W[i1][i2] * self.E[k][i2] self.Ct[i1] = s if i1 == 0 : mx = 0 else : if s > self.Ct[mx] : mx = i1 sw1 = 0 else : if s == self.Ct[mx] : sw1 = 1 if cor >= 0 and mx == cor : mx = i1 # 正しい分類 if sw1 == 0 and cor == mx : run += 1 if run > run_p : num = self.Bunrui() if num > num_p[0] : num_p[0] = num run_p = run for i1 in range(0, self.o) : for i2 in range(0, self.p+1) : self.W_p[i1][i2] = self.W[i1][i2] if num == self.n : sw = count # 誤った分類 else : run = 0 for i1 in range(0, self.p+1) : self.W[cor][i1] += self.E[k][i1] self.W[mx][i1] -= self.E[k][i1] return sw #################################### # Winner-Take-All Groups # coded by Y.Suganuma #################################### if len(sys.argv) > 1 : # 基本データの入力 f = open(sys.argv[1], "r") s = f.readline().split() max = int(s[1]) p = int(s[3]) o = int(s[5]) n = int(s[7]) s = f.readline().split() name = s[1] f.close() # ネットワークの定義 seed() net = Winner(max, n, o, p) net.Input(name) # 学習と結果の出力 if len(sys.argv) == 2 : net.Learn(0) else : net.Learn(1, sys.argv[2]) else : print("***error 入力ファイル名を指定して下さい") """ ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 """
/****************************/ /* Winner-Take-All Groups */ /* coded by Y.Suganuma */ /****************************/ using System; using System.IO; class Program { /****************/ /* main program */ /****************/ static void Main(String[] args) { if (args.Length > 0) { char[] charSep = new char[] {' '}; // 基本データの入力 String[] lines = File.ReadAllLines(args[0]); String[] str = lines[0].Split(charSep, StringSplitOptions.RemoveEmptyEntries); int max = int.Parse(str[1]); int p = int.Parse(str[3]); int o = int.Parse(str[5]); int n = int.Parse(str[7]); str = lines[1].Split(charSep, StringSplitOptions.RemoveEmptyEntries); String name = str[1]; // ネットワークの定義 Winner net = new Winner (max, n, o, p); net.input(name); // 学習と結果の出力 if (args.Length == 1) net.learn(0, ""); else net.learn(1, args[1]); } // エラー else { Console.WriteLine("***error 入力データファイル名を指定して下さい"); Environment.Exit(1); } } } /**********************/ /* Winnerクラスの定義 */ /**********************/ class Winner { int max; // 最大学習回数 int n; // 訓練例の数 int o; // 出力セルの数 int p; // 入力セルの数 int[][] W_p; // 重み(ポケット) int[][] W; // 重み int[][] E; // 訓練例 int[][] C; // 各訓練例に対する正しい出力 int[] Ct; // 作業領域 Random rn; // 乱数 /******************/ /* コンストラクタ */ /******************/ public Winner (int max_i, int n_i, int o_i, int p_i) { // // 設定 // max = max_i; n = n_i; o = o_i; p = p_i; rn = new Random(); // 乱数の初期設定 // // 領域の確保 // E = new int [n][]; W_p = new int [o][]; W = new int [o][]; C = new int [n][]; for (int i1 = 0; i1 < n; i1++) { E[i1] = new int [p+1]; C[i1] = new int [o]; } for (int i1 = 0; i1 < o; i1++) { W_p[i1] = new int [p+1]; W[i1] = new int [p+1]; } Ct = new int [o]; } /******************************************/ /* 訓練例の分類 */ /* return : 正しく分類した訓練例の数 */ /******************************************/ int bunrui() { int mx = 0, mx_v = 0, num = 0, sw = 0; for (int i1 = 0; i1 < n; i1++) { int cor = 0; for (int i2 = 0; i2 < o; i2++) { if (C[i1][i2] == 1) cor = i2; int s = 0; for (int i3 = 0; i3 <= p; i3++) s += W[i2][i3] * E[i1][i3]; if (i2 == 0) { mx = 0; mx_v = s; } else { if (s > mx_v) { mx = i2; mx_v = s; sw = 0; } else { if (s == mx_v) sw = 1; } } } if (sw == 0 && cor == mx) num++; } return num; } /**************************/ /* 学習データの読み込み */ /* name : ファイル名 */ /**************************/ public void input (String name) { char[] charSep = new char[] {' '}; String[] lines = File.ReadAllLines(name); for (int i1 = 0; i1 < n; i1++) { String[] str = lines[1+i1].Split(charSep, StringSplitOptions.RemoveEmptyEntries); E[i1][0] = 1; for (int i2 = 1; i2 <= p; i2++) E[i1][i2] = int.Parse(str[i2-1]); for (int i2 = 0; i2 < o; i2++) C[i1][i2] = int.Parse(str[p+i2]); } } /*********************************/ /* 学習と結果の出力 */ /* pr : =0 : 画面に出力 */ /* =1 : ファイルに出力 */ /* name : 出力ファイル名 */ /*********************************/ public void learn(int pr, String name) { // 学習 int num = 0; int n_tri = pocket(ref num); // 結果の出力 if (pr == 0) { Console.WriteLine("重み"); for (int i1 = 0; i1 < o; i1++) { for (int i2 = 0; i2 <= p; i2++) Console.Write(" " + W_p[i1][i2]); Console.WriteLine(); } Console.WriteLine("分類結果"); int mx = 0; int mx_v = 0; for (int i1 = 0; i1 < n; i1++) { int sw = 0; for (int i2 = 0; i2 < o; i2++) { int s = 0; for (int i3 = 0; i3 <= p; i3++) s += W_p[i2][i3] * E[i1][i3]; if (i2 == 0) { mx_v = s; mx = 0; } else { if (s > mx_v) { sw = 0; mx_v = s; mx = i2; } else { if (s == mx_v) sw = 1; } } } for (int i2 = 1; i2 <= p; i2++) Console.Write(" " + E[i1][i2]); Console.Write(" Cor "); for (int i2 = 0; i2 < o; i2++) Console.Write(" " + C[i1][i2]); if (sw > 0) mx = -1; Console.WriteLine(" Res " + (mx+1)); } } else { StreamWriter OUT = new StreamWriter(name, true); OUT.WriteLine("重み"); for (int i1 = 0; i1 < o; i1++) { for (int i2 = 0; i2 <= p; i2++) OUT.Write(" " + W_p[i1][i2]); OUT.WriteLine(); } OUT.WriteLine("分類結果"); int mx = 0; int mx_v = 0; for (int i1 = 0; i1 < n; i1++) { int sw = 0; for (int i2 = 0; i2 < o; i2++) { int s = 0; for (int i3 = 0; i3 <= p; i3++) s += W_p[i2][i3] * E[i1][i3]; if (i2 == 0) { mx_v = s; mx = 0; } else { if (s > mx_v) { sw = 0; mx_v = s; mx = i2; } else { if (s == mx_v) sw = 1; } } } for (int i2 = 1; i2 <= p; i2++) OUT.Write(" " + E[i1][i2]); OUT.Write(" Cor "); for (int i2 = 0; i2 < o; i2++) OUT.Write(" " + C[i1][i2]); if (sw > 0) mx = -1; OUT.WriteLine(" Res " + (mx+1)); } OUT.Close(); } if (n == num) Console.WriteLine(" !!すべてを分類(試行回数:" + n_tri + ")"); else Console.WriteLine(" !!" + num + " 個を分類"); } /********************************************/ /* Pocket Algorith with Ratcet */ /* num_p : 正しく分類した訓練例の数 */ /* return : =0 : 最大学習回数 */ /* >0 : すべてを分類(回数) */ /********************************************/ int pocket(ref int num_p) { // // 初期設定 // num_p = 0; int count = 0, mx = 0, run = 0, run_p = 0, sw = -1; for (int i1 = 0; i1 < o; i1++) { for (int i2 = 0; i2 <= p; i2++) W[i1][i2] = 0; } // // 実行 // while (sw < 0) { // 終了チェック count++;; if (count > max) sw = 0; else { // 訓練例の選択 int k = (int)(rn.NextDouble() * n); if (k >= n) k = n - 1; // 出力の計算 int sw1 = 0; int cor = -1; for (int i1 = 0; i1 < o; i1++) { if (C[k][i1] == 1) cor = i1; int s = 0; for (int i2 = 0; i2 <= p; i2++) s += W[i1][i2] * E[k][i2]; Ct[i1] = s; if (i1 == 0) mx = 0; else { if (s > Ct[mx]) { mx = i1; sw1 = 0; } else { if (s == Ct[mx]) { sw1 = 1; if (cor >= 0 && mx == cor) mx = i1; } } } } // 正しい分類 if (sw1 == 0 && cor == mx) { run++; if (run > run_p) { int num = bunrui(); if (num > num_p) { num_p = num; run_p = run; for (int i1 = 0; i1 < o; i1++) { for (int i2 = 0; i2 <= p; i2++) W_p[i1][i2] = W[i1][i2]; } if (num == n) sw = count; } } } // 誤った分類 else { run = 0; for (int i1 = 0; i1 <= p; i1++) { W[cor][i1] += E[k][i1]; W[mx][i1] -= E[k][i1]; } } } } return sw; } } /* ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 */
'**************************' ' Winner-Take-All Groups ' ' coded by Y.Suganuma ' '**************************' Imports System.IO Imports System.Text.RegularExpressions Module Test Sub Main(args() As String) If args.Length > 0 ' 基本データの入力 Dim inp As StreamReader = New StreamReader(args(0)) Dim MS As Regex = New Regex("\s+") Dim str() As String = MS.Split(inp.ReadLine().Trim()) Dim max As Integer = Integer.Parse(str(1)) Dim p As Integer = Integer.Parse(str(3)) Dim o As Integer = Integer.Parse(str(5)) Dim n As Integer = Integer.Parse(str(7)) str = MS.Split(inp.ReadLine().Trim()) Dim name As String = str(1) inp.Close() ' ネットワークの定義 Dim net As Winner = new Winner (max, n, o, p) net.input(name) ' 学習と結果の出力 If args.Length = 1 net.learn(0, "") Else net.learn(1, args(1)) End If ' エラー Else Console.WriteLine("***error 入力データファイル名を指定して下さい") Environment.Exit(1) End If End Sub '********************' ' Winnerクラスの定義 ' '********************' Class Winner Private max As Integer ' 最大学習回数 Private n As Integer ' 訓練例の数 Private o As Integer ' 出力セルの数 Private p As Integer ' 入力セルの数 Private W_p(,) As Integer ' 重み(ポケット) Private W(,) As Integer ' 重み Private E(,) As Integer ' 訓練例 Private C(,) As Integer ' 各訓練例に対する正しい出力 Private Ct() As Integer ' 作業領域 Private rn As Random ' 乱数 '****************' ' コンストラクタ ' '****************' Public Sub New (max_i As Integer, n_i As Integer, o_i As Integer, p_i As Integer) ' ' 設定 ' max = max_i n = n_i o = o_i p = p_i rn = new Random() ' 乱数の初期設定 ' ' 領域の確保 ' ReDim E(n,p+1) ReDim W_p(o,p+1) ReDim W(o,p+1) ReDim C(n,o) ReDim Ct(o) End Sub '****************************************' ' 訓練例の分類 ' ' return : 正しく分類した訓練例の数 ' '****************************************' Function bunrui() Dim mx As Integer = 0 Dim mx_v As Integer = 0 Dim num As Integer = 0 Dim sw As Integer = 0 For i1 As Integer = 0 To n-1 Dim cor As Integer = 0 For i2 As Integer = 0 To o-1 If C(i1,i2) = 1 cor = i2 End If Dim s As Integer = 0 For i3 As Integer = 0 To p s += W(i2,i3) * E(i1,i3) Next If i2 = 0 mx = 0 mx_v = s Else If s > mx_v mx = i2 mx_v = s sw = 0 Else If s = mx_v sw = 1 End If End If End If Next If sw = 0 and cor = mx num += 1 End If Next Return num End Function '************************' ' 学習データの読み込み ' ' name : ファイル名 ' '************************' Public Sub input (name As String) Dim inp As StreamReader = New StreamReader(name) Dim MS As Regex = New Regex("\s+") inp.ReadLine() For i1 As Integer = 0 To n-1 Dim str() As String = MS.Split(inp.ReadLine().Trim()) E(i1,0) = 1 For i2 As Integer = 1 To p E(i1,i2) = Integer.Parse(str(i2-1)) Next For i2 As Integer = 0 To o-1 C(i1,i2) = Integer.Parse(str(p+i2)) Next Next inp.Close() End Sub '*******************************' ' 学習と結果の出力 ' ' pr : =0 : 画面に出力 ' ' =1 : ファイルに出力 ' ' name : 出力ファイル名 ' '*******************************' Public Sub learn(pr As Integer, name As String) ' 学習 Dim num As Integer = 0 Dim n_tri As Integer = pocket(num) ' 結果の出力 If pr = 0 Console.WriteLine("重み") For i1 As Integer = 0 To o-1 For i2 As Integer = 0 To p Console.Write(" " & W_p(i1,i2)) Next Console.WriteLine() Next Console.WriteLine("分類結果") Dim mx As Integer = 0 Dim mx_v As Integer = 0 For i1 As Integer = 0 To n-1 Dim sw As Integer = 0 For i2 As Integer = 0 To o-1 Dim s As Integer = 0 For i3 As Integer = 0 To p s += W_p(i2,i3) * E(i1,i3) Next If i2 = 0 mx_v = s mx = 0 Else If s > mx_v sw = 0 mx_v = s mx = i2 Else If s = mx_v sw = 1 End If End If End If Next For i2 As Integer = 1 To p Console.Write(" " & E(i1,i2)) Next Console.Write(" Cor ") For i2 As Integer = 0 To o-1 Console.Write(" " & C(i1,i2)) Next If sw > 0 mx = -1 End If Console.WriteLine(" Res " & (mx+1)) Next Else Dim OUT As StreamWriter = new StreamWriter(name) OUT.WriteLine("重み") For i1 As Integer = 0 To o-1 For i2 As Integer = 0 To p OUT.Write(" " & W_p(i1,i2)) Next OUT.WriteLine() Next OUT.WriteLine("分類結果") Dim mx As Integer = 0 Dim mx_v As Integer = 0 For i1 As Integer = 0 To n-1 Dim sw As Integer = 0 For i2 As Integer = 0 To o-1 Dim s As Integer = 0 For i3 As Integer = 0 To p s += W_p(i2,i3) * E(i1,i3) Next If i2 = 0 mx_v = s mx = 0 Else If s > mx_v sw = 0 mx_v = s mx = i2 Else If s = mx_v sw = 1 End If End If End If Next For i2 As Integer = 1 To p OUT.Write(" " & E(i1,i2)) Next OUT.Write(" Cor ") For i2 As Integer = 0 To o-1 OUT.Write(" " & C(i1,i2)) Next If sw > 0 mx = -1 End If OUT.WriteLine(" Res " & (mx+1)) Next OUT.Close() End If If n = num Console.WriteLine(" !!すべてを分類(試行回数:" & n_tri & ")") Else Console.WriteLine(" !!" & num & " 個を分類") End If End Sub '******************************************' ' Pocket Algorith with Ratcet ' ' num_p : 正しく分類した訓練例の数 ' ' return : =0 : 最大学習回数 ' ' >0 : すべてを分類(回数) ' '******************************************' Function pocket(ByRef num_p As Integer) ' ' 初期設定 ' num_p = 0 Dim count As Integer = 0 Dim mx As Integer = 0 Dim run As Integer = 0 Dim run_p As Integer = 0 Dim sw As Integer = -1 For i1 As Integer = 0 To o-1 For i2 As Integer = 0 To p W(i1,i2) = 0 Next Next ' ' 実行 ' Do While sw < 0 ' 終了チェック count += 1 If count > max sw = 0 Else ' 訓練例の選択 Dim k As Integer = Math.Floor(rn.NextDouble() * n) If k >= n k = n - 1 End If ' 出力の計算 Dim sw1 As Integer = 0 Dim cor As Integer = -1 For i1 As Integer = 0 To o-1 If C(k,i1) = 1 cor = i1 End If Dim s As Integer = 0 For i2 As Integer = 0 To p s += W(i1,i2) * E(k,i2) Next Ct(i1) = s If i1 = 0 mx = 0 Else If s > Ct(mx) mx = i1 sw1 = 0 Else If s = Ct(mx) sw1 = 1 If cor >= 0 and mx = cor mx = i1 End If End If End If End If Next ' 正しい分類 If sw1 = 0 and cor = mx run += 1 If run > run_p Dim num As Integer = bunrui() If num > num_p num_p = num run_p = run For i1 As Integer = 0 To o-1 For i2 As Integer = 0 To p W_p(i1,i2) = W(i1,i2) Next Next If num = n sw = count End If End If End If ' 誤った分類 Else run = 0 For i1 As Integer = 0 To p W(cor,i1) += E(k,i1) W(mx,i1) -= E(k,i1) Next End If End If Loop Return sw End Function End Class End Module /* ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後の2つのデータが目標出力値 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 1 1 -1 */
情報学部 | 菅沼ホーム | 目次 | 索引 |