------------------------制御データ----------------
誤差 0.1 出力 -2 出力ファイル kekka
順番 0 η 0.5 α 0.8 乱数 123
画面表示(円の大きさ,フォントサイズ,幅,高さ) 20 20 400 300
------------------------構造データ----------------
入力ユニット数 2 出力ユニット数 1 関数タイプ 0
隠れ層の数 1 各隠れ層のユニット数(下から) 1
バイアス入力ユニット数 1
ユニット番号:出力ユニットから順に番号付け
入力方法:=-3:固定,=-2:入力後学習,=-1:乱数(default,[-0.1,0.1]))
値:バイアス値(ー2またはー3の時)または一様乱数の範囲(下限,上限)
1 -1 -0.05 0.05
接続方法の数 2
ユニット番号:ユニットk1からk2を,k3からk4に接続
接続方法:=0:接続なし,=1:乱数,=2:重み入力後学習,=3:重み固定
値:重み(2または3の時)または一様乱数の範囲(1の時:下限,上限)
3 4 1 2 1 -0.1 0.1
2 2 1 1 1 -0.1 0.1
------------------------学習データ----------------
パターンの数 4 入力ユニット数 2 出力ユニット数 1
入力1 0 0
出力1 0
入力2 0 1
出力2 1
入力3 1 0
出力3 1
入力4 1 1
出力4 0
------------------------認識データ----------------
パターンの数 4 入力ユニット数 2 出力ユニット数 1
入力1 0 0
出力1 0
入力2 0 1
出力2 1
入力3 1 0
出力3 1
入力4 1 1
出力4 0
-----------------------プログラム------------------
/****************************/
/* back propagation model */
/* coded by Y.Suganuma */
/****************************/
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.StringTokenizer;
class Test {
/****************/
/* main program */
/****************/
public static void main(String args[]) throws IOException, FileNotFoundException
{
int conv; // 収束確認回数
int m_tri; // 最大学習回数
int max = 0, no = 1, sw, tri;
String f_name;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// エラー
if (args.length != 2) {
System.out.print("***error 入力データファイル名を指定して下さい\n");
System.exit(1);
}
else {
// ネットワークの定義
Backpr net = new Backpr (args[0], args[1]);
// 学習パターン等の入力
System.out.print("学習回数は? ");
m_tri = Integer.parseInt(in.readLine());
System.out.print("何回毎に収束を確認しますか? ");
conv = Integer.parseInt(in.readLine());
System.out.print("学習パターンのファイル名は? ");
f_name = in.readLine();
BackData dt1 = new BackData(f_name);
// 学習
while (max < m_tri && no > 0) {
tri = ((max + conv) < m_tri) ? conv : m_tri - max;
max += tri;
net.Learn(dt1, tri); // 学習
no = net.Recog(dt1, 0, max); // 学習対象の認識
System.out.println(" 回数 " + max + " 誤って認識したパターン数 " + no);
}
no = net.Recog(dt1, 1, max); // 学習対象の認識と出力
// 未学習パターンの認識
System.out.print("未学習パターンの認識を行いますか?(=1:行う,=0:行わない) ");
sw = Integer.parseInt(in.readLine());
if (sw > 0) {
System.out.print("未学習パターンのファイル名は? ");
f_name = in.readLine();
BackData dt2 = new BackData(f_name);
no = net.Recog(dt2, 2, max); // 未学習対象の認識と出力
}
}
in.close();
}
}
/******************************************************/
/* バックプロパゲーションの制御(クラス BackControl) */
/******************************************************/
class BackControl {
protected double alpha, eata; //重み及びバイアス修正パラメータ
protected double eps; // 許容誤差
protected int seed; // 乱数の初期値;
protected int order; // 入力パターンの与え方(=0:順番,=1:ランダム)
protected int p_type; // 出力先・方法の指定
// =0 : 誤って認識した数だけ出力
// =1 : 認識結果を出力
// =2 : 認識結果と重みを出力
// (負の時は,認識結果と重みをファイルへも出力)
protected int c_size; // 円の大きさ(直径,0のときは画面を表示しない)
protected int f_size; // フォントサイズ(0のときはユニット番号を表示しない)
protected int width; // 画面の幅
protected int hight; // 画面の高さ
protected String o_file; // 出力ファイル名
/*************************************/
/* クラスBackControlのコンストラクタ */
/* name : 入力データファイル名 */
/*************************************/
BackControl(String name) throws IOException, FileNotFoundException
{
StringTokenizer str;
BufferedReader in = new BufferedReader(new FileReader(name));
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
eps = Double.parseDouble(str.nextToken());
str.nextToken();
p_type = Integer.parseInt(str.nextToken());
if (p_type < 0) {
str.nextToken();
o_file = str.nextToken();
}
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
order = Integer.parseInt(str.nextToken());
str.nextToken();
eata = Double.parseDouble(str.nextToken());
str.nextToken();
alpha = Double.parseDouble(str.nextToken());
str.nextToken();
seed = Integer.parseInt(str.nextToken());
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
c_size = Integer.parseInt(str.nextToken());
if (c_size > 0) {
f_size = Integer.parseInt(str.nextToken());
width = Integer.parseInt(str.nextToken());
hight = Integer.parseInt(str.nextToken());
}
in.close();
}
}
/*****************************************************/
/* バックプロパゲーションのデータ(クラス BackData) */
/*****************************************************/
class BackData {
int noiu; // 入力ユニットの数
int noou; // 出力ユニットの数
int noip; // 入力パターンの数
double iptn[][]; // iptn[i][j] : (i+1)番目の入力パターンの(j+1)番目の
// 入力ユニットの入力値
// i=0,noip-1 j=0,noiu-1
double optn[][]; // optn[i][j] : (i+1)番目の入力パターンに対する(j+1)
// 番目の出力ユニットの目標出力値
// i=0,noip-1 j=0,noou-1
/************************************/
/* クラスBackDataのコンストラクタ */
/* name : 入力データファイル名 */
/************************************/
BackData(String name) throws IOException, FileNotFoundException
{
int i1, i2;
StringTokenizer str;
BufferedReader in = new BufferedReader(new FileReader(name));
/*
入力パターン数等
*/
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
noip = Integer.parseInt(str.nextToken());
str.nextToken();
noiu = Integer.parseInt(str.nextToken());
str.nextToken();
noou = Integer.parseInt(str.nextToken());
/*
領域の確保
*/
iptn = new double [noip][noiu];
optn = new double [noip][noou];
/*
入力パターン及び各入力パターンに対する出力パターンの入力
*/
for (i1 = 0; i1 < noip; i1++) {
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
for (i2 = 0; i2 < noiu; i2++)
iptn[i1][i2] = Double.parseDouble(str.nextToken());
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
for (i2 = 0; i2 < noou; i2++)
optn[i1][i2] = Double.parseDouble(str.nextToken());
}
in.close();
}
}
/*******************************************/
/* バックプロパゲーション(クラス Backpr) */
/*******************************************/
class Backpr extends BackControl {
private byte con[][]; // con[i][j] : 各ユニットに対するバイアスの与え方,及び,
// 接続方法
// [i][i] : ユニット(i+1)のバイアスの与え方
// =-3 : 入力値で固定
// =-2 : 入力値を初期値として,学習により変更
// =-1 : 乱数で初期値を設定し,学習により変更
// [i][j] : ユニット(i+1)と(j+1)の接続方法(j>i)
// =0 : 接続しない
// =1 : 接続する(重みの初期値を乱数で設定し,学習)
// =2 : 接続する(重みの初期値を入力で与え,学習)
// =3 : 接続する(重みを入力値に固定)
// i=0,nou-1 j=0,nou-1
private int f_type; // シグモイド関数のタイプ
// 0 : [0,1]
// 1 : [-1,1])
private int noiu; // 入力ユニットの数
private int noou; // 出力ユニットの数
private int nohu[]; // nohu[i] : レベル(i+1)の隠れ層のユニット数(隠れ層
// には下から順に番号が付けられ,出力層はレ
// ベル(nolvl+1)の隠れ層とも見做される)
// i=0,nolvl
private int nolvl; // 隠れユニットの階層数
private int nou; // 入力,出力,及び,隠れ層の各ユニットの数の和(各ユニ
// ットには最も上の出力ユニットから,隠れ層の各ユニット,
// 及び,入力ユニットに至る一連のユニット番号が付けられ
// る)
private double dp[]; // dp[i] : ユニット(i+1)の誤差 i=0,nou-1
private double op[]; // op[i] : ユニット(i+1)の出力 i=0,nou-1
private double theta[]; //theta[i] : ユニット(i+1)のバイアス i=0,nou
private double w[][]; // w[i][j] : ユニット(i+1)から(j+1)への重み(j>i)
// w[j][i] : (i+1)から(j+1)への重みの前回修正量(j>i)
// w[i][i] : ユニット(i+1)のバイアスの前回修正量
// i=0,nou-1 j=0,nou-1
private Random rn; // 乱数
/************************************************/
/* クラスBackprのコンストラクタ */
/* name_c : 制御データ用入力ファイル名 */
/* name_s : ネットワーク記述入力ファイル名 */
/************************************************/
Backpr(String name_c, String name_s) throws IOException, FileNotFoundException
{
super(name_c);
double x1, x2;
int i0, i1, i2, id, k, k1, k2, k3, k4, l1, l2, n, sw;
StringTokenizer str;
BufferedReader in = new BufferedReader(new FileReader(name_s));
/*
乱数の初期化
*/
rn = new Random(seed); // 乱数の初期設定
/*
入力ユニット,出力ユニットの数,関数タイプ
*/
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
noiu = Integer.parseInt(str.nextToken());
str.nextToken();
noou = Integer.parseInt(str.nextToken());
str.nextToken();
f_type = Integer.parseInt(str.nextToken());
nou = noiu + noou; // 入力ユニットと出力ユニットの和
/*
隠れユニットの階層数と各階層のユニット数
*/
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
nolvl = Integer.parseInt(str.nextToken());
nohu = new int [nolvl+1];
nohu[nolvl] = noou; // 出力ユニットの数
if (nolvl > 0) {
str.nextToken();
for (i1 = 0; i1 < nolvl; i1++) {
nohu[i1] = Integer.parseInt(str.nextToken());
nou += nohu[i1];
}
}
/*
領域の確保
*/
con = new byte [nou][nou];
for (i1 = 0; i1 < nou; i1++) {
for (i2 = 0; i2 < nou; i2++)
con[i1][i2] = (i1 == i2) ? (byte)-1 : (byte)0;
}
w = new double [nou][nou];
for (i1 = 0; i1 < nou; i1++) {
for (i2 = 0; i2 < nou; i2++)
w[i1][i2] = 0.0;
}
dp = new double [nou];
op = new double [nou];
theta = new double [nou];
for (i1 = 0; i1 < nou; i1++)
theta[i1] = 0.2 * rn.nextDouble() - 0.1;
/*
各ユニットのバイアスとユニット間の接続関係
*/
// バイアス
// バイアスデータの数
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
n = Integer.parseInt(str.nextToken());
in.readLine();
in.readLine();
in.readLine();
if (n > 0) {
// バイアスデータの処理
for (i0 = 0; i0 < n; i0++) {
// ユニット番号
str = new StringTokenizer(in.readLine(), " ");
k1 = Integer.parseInt(str.nextToken());
// 不適当なユニット番号のチェック
if (k1 < 1 || k1 > (nou-noiu)) {
System.out.print("***error ユニット番号 " + k1 + " が不適当\n");
System.exit(1);
}
// バイアスの与え方
k1--;
id = Integer.parseInt(str.nextToken());
con[k1][k1] = (byte)id;
// バイアスの初期設定
switch (con[k1][k1]) {
case -1:
x1 = Double.parseDouble(str.nextToken());
x2 = Double.parseDouble(str.nextToken());
theta[k1] = (x2 - x1) * rn.nextDouble() + x1;
break;
case -2:
theta[k1] = Double.parseDouble(str.nextToken());
break;
case -3:
theta[k1] = Double.parseDouble(str.nextToken());
break;
default:
System.out.print("***error バイアスの与え方が不適当\n");
System.exit(1);
}
}
}
// 接続方法
// 接続データの数
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
n = Integer.parseInt(str.nextToken());
in.readLine();
in.readLine();
in.readLine();
if (n > 0) {
// 接続データの処理
for (i0 = 0; i0 < n; i0++) {
// 接続情報
str = new StringTokenizer(in.readLine(), " ");
k1 = Integer.parseInt(str.nextToken());
k2 = Integer.parseInt(str.nextToken());
k3 = Integer.parseInt(str.nextToken());
k4 = Integer.parseInt(str.nextToken());
// 不適切な接続のチェック
sw = 0;
if (k1 < 1 || k2 < 1 || k3 < 1 || k4 < 1)
sw = 1;
else {
if (k1 > nou || k2 > nou || k3 > nou || k4 > nou)
sw = 1;
else {
if (k1 > k2 || k3 > k4)
sw = 1;
else {
if (k4 >= k1)
sw = 1;
else {
l1 = -1;
k = 0;
for (i1 = nolvl; i1 >= 0 && l1 < 0; i1--) {
k += nohu[i1];
if (k1 <= k)
l1 = i1;
}
l2 = -1;
k = 0;
for (i1 = nolvl; i1 >= 0 && l2 < 0; i1--) {
k += nohu[i1];
if (k4 <= k)
l2 = i1;
}
if (l2 <= l1)
sw = 1;
}
}
}
}
if (sw > 0) {
System.out.print("***error ユニット番号が不適当("
+ k1 + " " + k2 + " " + k3 + " " + k4 + ")\n");
System.exit(1);
}
// 重みの初期値の与え方
k1--;
k2--;
k3--;
k4--;
id = Integer.parseInt(str.nextToken());
x1 = 0.0;
x2 = 0.0;
if (id == 1) {
x1 = Double.parseDouble(str.nextToken());
x2 = Double.parseDouble(str.nextToken());
}
else {
if (id > 1)
x1 = Double.parseDouble(str.nextToken());
else {
if (id != 0) {
System.out.print("***error 接続方法が不適当\n");
System.exit(1);
}
}
}
// 重みの初期値の設定
for (i1 = k3; i1 <= k4; i1++) {
for (i2 = k1; i2 <= k2; i2++) {
con[i1][i2] = (byte)id;
switch (id) {
case 0:
w[i1][i2] = 0.0;
case 1:
w[i1][i2] = (x2 - x1) * rn.nextDouble() + x1;
break;
case 2:
w[i1][i2] = x1;
break;
case 3:
w[i1][i2] = x1;
break;
}
}
}
}
}
in.close();
/*
画面表示
*/
Win win;
if (c_size > 0)
win = new Win("Network Structure", c_size, f_size, width, hight,
noiu, nohu, nolvl, con);
}
/******************************************/
/* 誤差の計算,及び,重みとバイアスの修正 */
/* ptn[i1] : 出力パターン */
/******************************************/
void Err_back(double ptn[])
{
double x1;
int i1, i2;
for (i1 = 0; i1 < nou-noiu; i1++) {
// 誤差の計算
if (i1 < noou) {
if (f_type == 0)
dp[i1] = (ptn[i1] - op[i1]) * op[i1] * (1.0 - op[i1]);
else
dp[i1] = 0.5 * (ptn[i1] - op[i1]) *
(op[i1] - 1.0) * (op[i1] + 1.0);
}
else {
x1 = 0.0;
for (i2 = 0; i2 < i1; i2++) {
if (con[i2][i1] > 0)
x1 += dp[i2] * w[i2][i1];
}
if (f_type == 0)
dp[i1] = op[i1] * (1.0 - op[i1]) * x1;
else
dp[i1] = 0.5 * (op[i1] - 1.0) * (op[i1] + 1.0) * x1;
}
// 重みの修正
for (i2 = i1+1; i2 < nou; i2++) {
if (con[i1][i2] == 1 || con[i1][i2] == 2) {
x1 = eata * dp[i1] * op[i2] + alpha * w[i2][i1];
w[i2][i1] = x1;
w[i1][i2] += x1;
}
}
// バイアスの修正
if (con[i1][i1] >= -2) {
x1 = eata * dp[i1] + alpha * w[i1][i1];
w[i1][i1] = x1;
theta[i1] += x1;
}
}
}
/********************************************************/
/* 与えられた入力パターンに対する各ユニットの出力の計算 */
/********************************************************/
void Forward()
{
double sum;
int i1, i2;
for (i1 = nou-noiu-1; i1 >= 0; i1--) {
sum = -theta[i1];
for (i2 = i1+1; i2 < nou; i2++) {
if (con[i1][i2] > 0)
sum -= w[i1][i2] * op[i2];
}
op[i1] = (f_type == 0) ? 1.0 / (1.0 + Math.exp(sum)) :
1.0 - 2.0 / (1.0 + Math.exp(sum));
}
}
/*****************************/
/* 学習の実行 */
/* p : 認識パターン */
/* m_tri : 最大学習回数 */
/*****************************/
void Learn(BackData p, int m_tri)
{
int i1, i2, k0 = -1, k1;
/*
エラーチェック
*/
if (noiu != p.noiu || noou != p.noou) {
System.out.print("***error 入力または出力ユニットの数が違います\n");
System.exit(1);
}
for (i1 = 0; i1 < m_tri; i1++) {
/*
パターンを与える順番の決定
*/
if (order == 0) { // 順番
k0++;
if (k0 >= p.noip)
k0 = 0;
}
else { // ランダム
k0 = (int)(rn.nextDouble() * p.noip);
if (k0 >= p.noip)
k0 = p.noip - 1;
}
/*
出力ユニットの結果を計算
*/
k1 = nou - noiu;
for (i2 = 0; i2 < noiu; i2++)
op[k1+i2] = p.iptn[k0][i2];
Forward();
/*
重みとバイアスの修正
*/
Err_back(p.optn[k0]);
}
}
/***********************************************/
/* 与えられた対象の認識と出力 */
/* p : 認識パターン */
/* pr : =0 : 出力を行わない */
/* =1 : 出力を行う */
/* =2 : 出力を行う(未学習パターン) */
/* tri : 現在の学習回数 */
/* return : 誤って認識したパターンの数 */
/***********************************************/
int Recog(BackData p, int pr, int tri) throws IOException, FileNotFoundException
{
int i1, i2, k1, No = 0, ln, sw;
String next;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
/*
ファイルのオープン
*/
PrintStream out = null;
if (p_type < 0 && pr > 0) {
if (pr == 1) {
out = new PrintStream(new FileOutputStream(o_file));
out.print("***学習パターン***\n\n");
}
else {
out = new PrintStream(new FileOutputStream(o_file, true));
out.print("\n***未学習パターン***\n\n");
}
}
/*
各パターンに対する出力
*/
for (i1 = 0; i1 < p.noip; i1++) {
// 入力パターンの設定
k1 = nou - noiu;
for (i2 = 0; i2 < noiu; i2++)
op[k1+i2] = p.iptn[i1][i2];
// 出力の計算
Forward();
// 結果の表示
if (p_type != 0 && pr > 0) {
System.out.print("入力パターン" + (i1+1) + " ");
for (i2 = 0; i2 < noiu; i2++) {
System.out.print(" " + op[k1+i2]);
if (i2 == noiu-1)
System.out.print("\n");
else {
if(((i2+1) % 10) == 0)
System.out.print("\n ");
}
}
System.out.print("\n 出力パターン(理想) ");
for (i2 = 0; i2 < noou; i2++) {
System.out.print(" " + p.optn[i1][i2]);
if (i2 == noou-1)
System.out.print("\n");
else {
if(((i2+1) % 5) == 0)
System.out.print("\n ");
}
}
}
sw = 0;
if (p_type != 0 && pr > 0)
System.out.print(" (実際) ");
for (i2 = 0; i2 < noou; i2++) {
if (p_type != 0 && pr > 0) {
System.out.print(" " + op[i2]);
if (i2 == noou-1)
System.out.print("\n");
else {
if(((i2+1) % 5) == 0)
System.out.print("\n ");
}
}
if (Math.abs(op[i2]-p.optn[i1][i2]) > eps)
sw = 1;
}
if (sw > 0)
No++;
if (p_type < 0 && pr > 0) {
out.print("入力パターン" + (i1+1) + " ");
for (i2 = 0; i2 < noiu; i2++) {
out.print(" " + op[k1+i2]);
if (i2 == noiu-1)
out.print("\n");
else {
if(((i2+1) % 10) == 0)
out.print("\n ");
}
}
out.print("\n 出力パターン(理想) ");
for (i2 = 0; i2 < noou; i2++) {
out.print(" " + p.optn[i1][i2]);
if (i2 == noou-1)
out.print("\n");
else {
if(((i2+1) % 5) == 0)
out.print("\n ");
}
}
out.print(" (実際) ");
for (i2 = 0; i2 < noou; i2++) {
out.print(" " + op[i2]);
if (i2 == noou-1)
out.print("\n");
else {
if(((i2+1) % 5) == 0)
out.print("\n ");
}
}
}
if (p_type != 0 && pr > 0)
next = in.readLine();
}
/*
重みの出力
*/
if ((p_type < -1 || p_type > 1) && pr == 1) {
System.out.print(" 重み\n");
for (i1 = 0; i1 < nou-noiu; i1++) {
System.out.print(" to " + (i1+1) + " from ");
ln = -1;
for (i2 = 0; i2 < nou; i2++) {
if (con[i1][i2] > 0) {
if (ln <= 0) {
if (ln < 0)
ln = 0;
else
System.out.print("\n ");
}
System.out.print(" " + (i2+1) + " " + w[i1][i2]);
ln += 1;
if (ln == 4)
ln = 0;
}
}
System.out.print("\n");
}
System.out.print("\n バイアス ");
ln = 0;
for (i1 = 0; i1 < nou-noiu; i1++) {
System.out.print(" " + (i1+1) + " " + theta[i1]);
ln += 1;
if (ln == 4 && i1 != nou-noiu-1) {
ln = 0;
System.out.print("\n ");
}
}
if (ln != 0)
System.out.print("\n");
next = in.readLine();
}
if (p_type < 0 && pr == 1) {
out.print(" 重み\n");
for (i1 = 0; i1 < nou-noiu; i1++) {
out.print(" to " + (i1+1) + " from ");
ln = -1;
for (i2 = 0; i2 < nou; i2++) {
if (con[i1][i2] > 0) {
if (ln <= 0) {
if (ln < 0)
ln = 0;
else
out.print("\n ");
}
out.print(" " + (i2+1) + " " + w[i1][i2]);
ln += 1;
if (ln == 4)
ln = 0;
}
}
out.print("\n");
}
out.print("\n バイアス ");
ln = 0;
for (i1 = 0; i1 < nou-noiu; i1++) {
out.print(" " + (i1+1) + " " + theta[i1]);
ln += 1;
if (ln == 4 && i1 != nou-noiu-1) {
ln = 0;
out.print("\n ");
}
}
if (ln != 0)
out.print("\n");
}
if (p_type < 0 && pr > 0)
out.close();
return No;
}
}
/*******************/
/* クラスWinの定義 */
/*******************/
class Win extends Frame {
byte con[][]; // 接続関係
int nohu[]; // 各層のユニット数(入力層から出力層)
int nolvl; // 層の数
int nou; // ユニット数
int c_size; // 円の大きさ(直径)
int f_size; // フォントサイズ
int width; // 画面の幅
int height; // 画面の高さ
int x[], y[]; // ユニットの位置
/**************************************************/
/* コンストラクタ */
/* name : Windowのタイトル */
/* c_size_i : 円の大きさ(直径) */
/* f_size_i : フォントサイズ */
/* width_i : 画面の幅 */
/* height_i : 画面の高さ */
/* noiu_i : 入力層のユニット数 */
/* nohu_i : 各層のユニット数(入力層を除く) */
/* nolvl_i : 層の数(入力層を除く) */
/* con_i : 接続関係 */
/**************************************************/
Win (String name, int c_size_i, int f_size_i, int width_i, int height_i,
int noiu_i, int nohu_i[], int nolvl_i, byte con_i[][])
{
// Frameクラスのコンストラクタ(Windowのタイトルを引き渡す)
super(name);
// データの設定
int i1, i2;
c_size = c_size_i;
f_size = f_size_i;
width = width_i;
height = height_i;
nou = noiu_i;
for (i1 = 0; i1 <= nolvl_i; i1++)
nou += nohu_i[i1];
nolvl = nolvl_i + 2;
nohu = new int [nolvl];
for (i1 = 0; i1 <= nolvl_i; i1++)
nohu[i1+1] = nohu_i[i1];
nohu[0] = noiu_i;
con = new byte [nou][nou];
for (i1 = 0; i1 < nou; i1++) {
for (i2 = 0; i2 < nou; i2++)
con[i1][i2] = con_i[i1][i2];
}
x = new int [nou];
y = new int [nou];
// Windowの大きさ
setSize(width, height);
// ウィンドウを表示
setVisible(true);
// イベントアダプタ
addWindowListener(new WinEnd());
}
/********/
/* 描画 */
/********/
public void paint (Graphics g)
{
// 初期設定
int y_s = (f_size > 25) ? 25 + f_size : 50;
int y_e = (c_size > 20 ) ? height - c_size - 10 : height - 30;
int c_x, c_y = y_s;
int i1, i2, k = 0;
int x_step, y_step = (y_e - y_s) / (nolvl - 1);
Font f;
// フォントサイズ
if (f_size > 0) {
f = new Font("TimesRoman", Font.PLAIN, f_size);
g.setFont(f);
}
// 各ユニットを描く
for (i1 = nolvl-1; i1 >= 0; i1--) {
x_step = width / nohu[i1];
c_x = x_step / 2;
for (i2 = 0; i2 < nohu[i1]; i2++) {
x[k] = c_x;
y[k] = c_y;
g.fillOval(x[k], y[k], c_size, c_size);
if (f_size > 0)
g.drawString(Integer.toString(k+1), x[k]-f_size/2, y[k]);
c_x += x_step;
k++;
}
c_y += y_step;
}
// 接続関係を描く
k = c_size / 2;
for (i1 = 0; i1 < nou-nohu[0]; i1++) {
for (i2 = i1+1; i2 < nou; i2++ ) {
if (con[i1][i2] != 0)
g.drawLine(x[i1]+k, y[i1]+k, x[i2]+k, y[i2]+k);
}
}
}
/************/
/* 終了処理 */
/************/
class WinEnd extends WindowAdapter
{
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
誤差 0.1 出力 -2 出力ファイル kekka 順番 0 η 0.5 α 0.8 乱数 123 画面表示(円の大きさ,フォントサイズ,幅,高さ) 20 20 400 300
入力ユニット数 2 出力ユニット数 1 関数タイプ 0 隠れ層の数 1 各隠れ層のユニット数(下から) 1 バイアス入力ユニット数 1 ユニット番号:出力ユニットから順に番号付け 入力方法:=-3:固定,=-2:入力後学習,=-1:乱数(default,[-0.1,0.1])) 値:バイアス値(ー2またはー3の時)または一様乱数の範囲(下限,上限) 1 -1 -0.1 0.1 接続方法の数 2 ユニット番号:ユニットk1からk2を,k3からk4に接続 接続方法:=0:接続なし,=1:乱数,=2:重み入力後学習,=3:重み固定 値:重み(2または3の時)または一様乱数の範囲(1の時:下限,上限) 3 4 1 2 1 -0.1 0.1 2 2 1 1 1 -0.1 0.1
パターンの数 4 入力ユニット数 2 出力ユニット数 1 入力1 0 0 出力1 0 入力2 0 1 出力2 1 入力3 1 0 出力3 1 入力4 1 1 出力4 0
回数 500 誤って認識したパターン数 4 回数 1000 誤って認識したパターン数 4 回数 1500 誤って認識したパターン数 4 回数 2000 誤って認識したパターン数 4 回数 2500 誤って認識したパターン数 4 回数 3000 誤って認識したパターン数 3 回数 3500 誤って認識したパターン数 0
入力パターン 1 0.00 0.00
出力パターン(理想) 0.000
(実際) 0.060
入力パターン 2 0.00 1.00
出力パターン(理想) 1.000
(実際) 0.911
・・・・・・
重み
to 1 from 2 -10.700 3 -4.675 4 -4.675
to 2 from 3 -6.825 4 -6.827
バイアス 1 7.139 2 2.501