以下,複数のファイル構成になっていますので,ファイル間の 区切りを「---・・・」で示します. ------------------------入力ファイル-------------- 最大試行回数 100 入力セルの数 2 訓練例の数 4 乱数 123 入力データファイル or.dat ------------------------or.dat-------------------- OR演算の訓練例.最後のデータが目標出力値 -1 -1 -1 -1 1 1 1 -1 1 1 1 1 ------------------------Per class----------------- /***************************************/ /* パーセプトロン学習 */ /* (Pocket Algorith with Ratcet) */ /* coded by Y.Suganuma */ /***************************************/ import java.io.*; public class Per { /********************/ /* main program */ /********************/ public static void main(String args[]) throws IOException, FileNotFoundException { int max, n, p, seed; String line, name; Data dt; if (args.length > 0) { // 基本データの入力 BufferedReader in = new BufferedReader(new FileReader(args[0])); line = in.readLine(); dt = new Data (line); dt.next(); dt.next(); max = Integer.parseInt(dt.data); dt.next(); dt.next(); p = Integer.parseInt(dt.data); dt.next(); dt.next(); n = Integer.parseInt(dt.data); dt.next(); dt.next(); seed = Integer.parseInt(dt.data); line = in.readLine(); dt = new Data (line); dt.next(); dt.next(); name = dt.data; in.close(); // ネットワークの定義 Perceptron net = new Perceptron (max, n, p, seed); 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); } } } ------------------------Perceptron class---------- /******************************/ /* Perceptronクラスの定義 */ /******************************/ import java.io.*; import java.util.Random; class Perceptron { private int max; // 最大学習回数 private int n; // 訓練例の数 private int p; // 入力セルの数 private int W_p[]; // 重み(ポケット) private int W[]; // 重み private int E[][]; // 訓練例 private int C[]; // 各訓練例に対する正しい出力 private Random rn; // 乱数 /**********************/ /* コンストラクタ */ /**********************/ Perceptron(int max_i, int n_i, int p_i, int seed) { /* 設定 */ max = max_i; n = n_i; p = p_i; rn = new Random(seed); // 乱数の初期設定 /* 領域の確保 */ E = new int [n][p+1]; W_p = new int [p+1]; W = new int [p+1]; C = new int [n]; } /**********************************************/ /* 訓練例の分類 */ /* return : 正しく分類した訓練例の数 */ /**********************************************/ int Bunrui() { int i1, i2, num = 0, s; for (i1 = 0; i1 < n; i1++) { s = 0; for (i2 = 0; i2 <= p; i2++) s += W[i2] * E[i1][i2]; if ((s > 0 && C[i1] > 0) || (s < 0 && C[i1] < 0)) num++; } return num; } /******************************/ /* 学習データの読み込み */ /* name : ファイル名 */ /******************************/ void Input (String name) throws IOException, FileNotFoundException { int i1, i2; String line; Data dt; BufferedReader st = new BufferedReader(new FileReader(name)); line = st.readLine(); for (i1 = 0; i1 < n; i1++) { E[i1][0] = 1; line = st.readLine(); dt = new Data (line); for (i2 = 1; i2 <= p; i2++) { dt.next(); E[i1][i2] = Integer.parseInt(dt.data); } dt.next(); C[i1] = Integer.parseInt(dt.data); } st.close(); } /*************************************/ /* 学習と結果の出力 */ /* pr : =0 : 画面に出力 */ /* =1 : ファイルに出力 */ /* name : 出力ファイル名 */ /*************************************/ void Learn(int pr, String name) throws FileNotFoundException { int i1, i2, n_tri, s; int num[] = new int [1]; // 学習 n_tri = Pocket(num); // 結果の出力 if (pr == 0) { System.out.print("重み\n"); for (i1 = 0; i1 <= p; i1++) System.out.print(" " + W_p[i1]); System.out.println(); System.out.print("分類結果\n"); for (i1 = 0; i1 < n; i1++) { s = 0; for (i2 = 0; i2 <= p; i2++) s += E[i1][i2] * W_p[i2]; if (s > 0) s = 1; else s = (s < 0) ? -1 : 0; for (i2 = 1; i2 <= p; i2++) System.out.print(" " + E[i1][i2]); System.out.println(" Cor " + C[i1] + " Res " + s); } } else { PrintStream out = new PrintStream(new FileOutputStream(name)); out.print("重み\n"); for (i1 = 0; i1 <= p; i1++) out.print(" " + W_p[i1]); out.println(); out.print("分類結果\n"); for (i1 = 0; i1 < n; i1++) { s = 0; for (i2 = 0; i2 <= p; i2++) s += E[i1][i2] * W_p[i2]; if (s > 0) s = 1; else s = (s < 0) ? -1 : 0; for (i2 = 1; i2 <= p; i2++) out.print(" " + E[i1][i2]); out.println(" Cor " + C[i1] + " Res " + s); } 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 count = 0, i1, k, num, run = 0, run_p = 0, s, sw = -1; /* 初期設定 */ num_p[0] = 0; for (i1 = 0; i1 <= p; i1++) W[i1] = 0; /* 実行 */ while (sw < 0) { count++; if (count > max) sw = 0; else { // 訓練例の選択 k = (int)(rn.nextDouble() * n); if (k >= n) k = n - 1; // 出力の計算 s = 0; for (i1 = 0; i1 <= p; i1++) s += W[i1] * E[k][i1]; // 正しい分類 if ((s > 0 && C[k] > 0) || (s < 0 && C[k] < 0)) { run++; if (run > run_p) { num = Bunrui(); if (num > num_p[0]) { num_p[0] = num; run_p = run; for (i1 = 0; i1 <= p; i1++) W_p[i1] = W[i1]; if (num == n) sw = count; } } } // 誤った分類 else { run = 0; for (i1 = 0; i1 <= p; i1++) W[i1] += C[k] * E[k][i1]; } } } return sw; } } ------------------------Data class---------------- /**********************************************/ /* 1行のデータから個々のデータを取り出す */ /* coded by Y.Suganuma */ /**********************************************/ class Data { private int len, start, end; private String line; String data; // コンストラクタ Data (String l) { line = l; len = line.length(); start = 0; end = 0; data = new String (); // 次のデータ } // 次のデータの取り出し // =0 : 成功,=-1 : 失敗 int next() { int k = 0; if (start < len) { int sw = 0; while (sw == 0) { end = line.indexOf(" ", start); if (end >= 0) { if ((end - start) > 0) { data = line.substring(start, end); sw = 1; } } else { end = len; sw = 1; if ((end - start) > 0) data = line.substring(start, end); else k = -1; } start = end + 1; } } else k = -1; return k; } }