| 情報学部 | 菅沼ホーム | 目次 | 索引 |
/****************************/
/* 競合学習 */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include "MT.h"
/***************************/
/* Competitionクラスの定義 */
/***************************/
class Competition {
long max; // 最大学習回数
long n; // 訓練例の数
long o; // 出力セルの数
long p; // 入力セルの数
long **E; // 訓練例
double **W; // 重み
double sig; // 重み修正係数
public:
Competition(long, long, long, long, long, double);
~Competition();
void Input(char *);
void Learn(int, char *name = "");
};
/******************/
/* コンストラクタ */
/******************/
Competition::Competition(long max_i, long n_i, long o_i, long p_i, long seed, double sig_i)
{
long i1;
/*
設定
*/
sig = sig_i;
max = max_i;
n = n_i;
o = o_i;
p = p_i;
init_genrand(seed);
/*
領域の確保
*/
E = new long * [n];
for (i1 = 0; i1 < n; i1++)
E[i1] = new long [p];
W = new double * [o];
for (i1 = 0; i1 < o; i1++)
W[i1] = new double [p];
}
/****************/
/* デストラクタ */
/****************/
Competition::~Competition()
{
int i1;
for (i1 = 0; i1 < n; i1++)
delete [] E[i1];
delete [] E;
for (i1 = 0; i1 < o; i1++)
delete [] W[i1];
delete [] W;
}
/**************************/
/* 学習データの読み込み */
/* name : ファイル名 */
/**************************/
void Competition::Input(char *name)
{
long i1, i2;
FILE *st;
st = fopen(name, "r");
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < p; i2++)
fscanf(st, "%ld", &E[i1][i2]);
}
fclose(st);
}
/*********************************/
/* 学習と結果の出力 */
/* pr : =0 : 画面に出力 */
/* =1 : ファイルに出力 */
/* name : 出力ファイル名 */
/*********************************/
void Competition::Learn(int pr, char *name)
{
double mx_v = 0.0, s, sum;
long count, i1, i2, i3, k, mx = 0;
FILE *out;
/*
初期設定
*/
for (i1 = 0; i1 < o; i1++) {
sum = 0.0;
for (i2 = 0; i2 < p; i2++) {
W[i1][i2] = genrand_real3();
sum += W[i1][i2];
}
sum = 1.0 / sum;
for (i2 = 0; i2 < p; i2++)
W[i1][i2] *= sum;
}
/*
学習
*/
for (count = 0; count < max; count++) {
// 訓練例の選択
k = (long)(genrand_real3() * n);
if (k >= n)
k = n - 1;
// 出力の計算
for (i1 = 0; i1 < o; i1++) {
s = 0.0;
for (i2 = 0; i2 < p; i2++)
s += W[i1][i2] * E[k][i2];
if (i1 == 0 || s > mx_v) {
mx = i1;
mx_v = s;
}
}
// 重みの修正
sum = 0.0;
for (i1 = 0; i1 < p; i1++)
sum += E[k][i1];
for (i1 = 0; i1 < p; i1++)
W[mx][i1] += sig * (E[k][i1] / sum - W[mx][i1]);
}
/*
出力
*/
if (pr == 0)
out = stdout;
else
out = fopen(name, "w");
fprintf(out, "分類結果\n");
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < p; i2++)
fprintf(out, "%2ld", E[i1][i2]);
fprintf(out, " Res ");
for (i2 = 0; i2 < o; i2++) {
s = 0.0;
for (i3 = 0; i3 < p; i3++)
s += W[i2][i3] * E[i1][i3];
if (i2 == 0 || s > mx_v) {
mx = i2;
mx_v = s;
}
}
fprintf(out, "%3ld\n", mx+1);
}
}
/****************/
/* main program */
/****************/
int main(int argc, char *argv[])
{
double sig;
long max, n, p, o;
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 %*s %lf",
&max, &p, &o, &n, &sig);
fscanf(st, "%*s %s", name);
fclose(st);
// ネットワークの定義
Competition net(max, n, o, p, seed, sig);
net.Input(name);
// 学習と結果の出力
if (argc == 2)
net.Learn(0);
else
net.Learn(1, argv[2]);
}
else {
printf("***error 入力データファイル名を指定して下さい\n");
exit(1);
}
return 0;
}
/*
------------------------入力ファイル--------------
最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
入力データファイル pat.dat
------------------------pat.dat-------------------
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
//---------------------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
*/
/****************************/
/* 競合学習 */
/* 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
{
double sig;
int max, n, o, p;
String name;
StringTokenizer str;
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.nextToken();
sig = Double.parseDouble(str.nextToken());
str = new StringTokenizer(in.readLine(), " ");
str.nextToken();
name = str.nextToken();
in.close();
// ネットワークの定義
Competition net = new Competition (max, n, o, p, sig);
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);
}
}
}
/***************************/
/* Competitionクラスの定義 */
/***************************/
class Competition {
private int max; // 最大学習回数
private int n; // 訓練例の数
private int o; // 出力セルの数
private int p; // 入力セルの数
private int E[][]; // 訓練例
private double W[][]; // 重み
private double sig; // 重み修正係数
private Random rn; // 乱数
/******************/
/* コンストラクタ */
/******************/
Competition (int max_i, int n_i, int o_i, int p_i, double sig_i)
{
/*
設定
*/
max = max_i;
n = n_i;
o = o_i;
p = p_i;
sig = sig_i;
rn = new Random(); // 乱数の初期設定
/*
領域の確保
*/
E = new int [n][p];
W = new double [o][p];
}
/**************************/
/* 学習データの読み込み */
/* name : ファイル名 */
/**************************/
void input (String name) throws IOException, FileNotFoundException
{
int i1, i2;
StringTokenizer str;
BufferedReader st = new BufferedReader(new FileReader(name));
for (i1 = 0; i1 < n; i1++) {
str = new StringTokenizer(st.readLine(), " ");
for (i2 = 0; i2 < p; i2++)
E[i1][i2] = Integer.parseInt(str.nextToken());
}
st.close();
}
/*********************************/
/* 学習と結果の出力 */
/* pr : =0 : 画面に出力 */
/* =1 : ファイルに出力 */
/* name : 出力ファイル名 */
/*********************************/
void learn(int pr, String name) throws FileNotFoundException
{
double mx_v = 0.0, s, sum;
int count, i1, i2, i3, k, mx = 0;
/*
初期設定
*/
for (i1 = 0; i1 < o; i1++) {
sum = 0.0;
for (i2 = 0; i2 < p; i2++) {
W[i1][i2] = rn.nextDouble();
sum += W[i1][i2];
}
sum = 1.0 / sum;
for (i2 = 0; i2 < p; i2++)
W[i1][i2] *= sum;
}
/*
学習
*/
for (count = 0; count < max; count++) {
// 訓練例の選択
k = (int)(rn.nextDouble() * n);
if (k >= n)
k = n - 1;
// 出力の計算
for (i1 = 0; i1 < o; i1++) {
s = 0.0;
for (i2 = 0; i2 < p; i2++)
s += W[i1][i2] * E[k][i2];
if (i1 == 0 || s > mx_v) {
mx = i1;
mx_v = s;
}
}
// 重みの修正
sum = 0.0;
for (i1 = 0; i1 < p; i1++)
sum += E[k][i1];
for (i1 = 0; i1 < p; i1++)
W[mx][i1] += sig * (E[k][i1] / sum - W[mx][i1]);
}
/*
出力
*/
if (pr == 0) {
System.out.print("分類結果\n");
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < p; i2++)
System.out.print(" " + E[i1][i2]);
System.out.print(" Res ");
for (i2 = 0; i2 < o; i2++) {
s = 0.0;
for (i3 = 0; i3 < p; i3++)
s += W[i2][i3] * E[i1][i3];
if (i2 == 0 || s > mx_v) {
mx = i2;
mx_v = s;
}
}
System.out.println((mx+1));
}
}
else {
PrintStream out = new PrintStream(new FileOutputStream(name));
out.print("分類結果\n");
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < p; i2++)
out.print(" " + E[i1][i2]);
out.print(" Res ");
for (i2 = 0; i2 < o; i2++) {
s = 0.0;
for (i3 = 0; i3 < p; i3++)
s += W[i2][i3] * E[i1][i3];
if (i2 == 0 || s > mx_v) {
mx = i2;
mx_v = s;
}
}
out.println((mx+1));
}
out.close();
}
}
}
/*
------------------------入力ファイル--------------
最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
入力データファイル pat.dat
------------------------pat.dat-------------------
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
*/
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE>競合学習</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);
let sig = parseFloat(document.getElementById("sig").value);
// ネットワークの定義
net = new Competition (max, n, o, p, sig);
net.input(name);
// 学習と結果の出力
net.learn(0, "");
document.getElementById("result").value = res;
}
/***************************/
/* Competitionオブジェクト */
/***************************/
function Competition (max_i, n_i, o_i, p_i, sig_i)
{
//
// 設定
//
this.max = max_i;
this.n = n_i;
this.o = o_i;
this.p = p_i;
this.sig = sig_i;
//
// 領域の確保
//
this.E = new Array(this.n);
for (let i1 = 0; i1 < this.n; i1++)
this.E[i1] = new Array(this.p);
this.W = new Array(this.o);
for (let i1 = 0; i1 < this.o; i1++)
this.W[i1] = new Array(this.p);
}
/************************/
/* 学習データの読み込み */
/************************/
Competition.prototype.input = function()
{
let lines = (document.getElementById("data").value).split('\n');
for (let i1 = 0; i1 < net.n; i1++) {
let str = lines[i1].split(' ').filter(function(e){return e.length > 0;});
for (let i2 = 0; i2 < net.p; i2++)
net.E[i1][i2] = parseInt(str[i2]);
}
}
/********************/
/* 学習と結果の出力 */
/********************/
Competition.prototype.learn = function()
{
let mx_v = 0.0;
let count, mx = 0;
//
// 初期設定
//
for (let i1 = 0; i1 < net.o; i1++) {
let sum = 0.0;
for (let i2 = 0; i2 < net.p; i2++) {
net.W[i1][i2] = Math.random();
sum += net.W[i1][i2];
}
sum = 1.0 / sum;
for (let i2 = 0; i2 < net.p; i2++)
net.W[i1][i2] *= sum;
}
//
// 学習
//
for (count = 0; count < max; count++) {
// 訓練例の選択
let k = Math.floor(Math.random() * net.n);
if (k >= net.n)
k = net.n - 1;
// 出力の計算
for (let i1 = 0; i1 < net.o; i1++) {
let s = 0.0;
for (let i2 = 0; i2 < net.p; i2++)
s += net.W[i1][i2] * net.E[k][i2];
if (i1 == 0 || s > mx_v) {
mx = i1;
mx_v = s;
}
}
// 重みの修正
let sum = 0.0;
for (let i1 = 0; i1 < net.p; i1++)
sum += net.E[k][i1];
for (let i1 = 0; i1 < net.p; i1++)
net.W[mx][i1] += net.sig * (net.E[k][i1] / sum - net.W[mx][i1]);
}
//
// 出力
//
res += "分類結果\n";
for (let i1 = 0; i1 < net.n; i1++) {
for (let i2 = 0; i2 < net.p; i2++)
res += (" " + net.E[i1][i2]);
res += (" Res ");
for (let i2 = 0; i2 < net.o; i2++) {
let s = 0.0;
for (let i3 = 0; i3 < net.p; i3++)
s += net.W[i2][i3] * net.E[i1][i3];
if (i2 == 0 || s > mx_v) {
mx = i2;
mx_v = s;
}
}
res += ((mx+1) + "\n");
}
}
</SCRIPT>
</HEAD>
<BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;">
<H2><B>競合学習</B></H2>
最大試行回数:<INPUT ID="max" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="1000">
入力セル数:<INPUT ID="p" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="9">
出力セル数:<INPUT ID="o" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="3">
訓練例数:<INPUT ID="n" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="9">
係数(0~1):<INPUT ID="sig" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="0.1">
<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">
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
</TEXTAREA>
</DIV>
</DIV>
</BODY>
</HTML>
<?php
/****************************/
/* 競合学習 */
/* coded by Y.Suganuma */
/****************************/
/***************************/
/* Competitionクラスの定義 */
/***************************/
class Competition {
private $max; // 最大学習回数
private $n; // 訓練例の数
private $o; // 出力セルの数
private $p; // 入力セルの数
private $E; // 訓練例
private $W; // 重み
private $sig; // 重み修正係数
/******************/
/* コンストラクタ */
/******************/
function Competition($max_i, $n_i, $o_i, $p_i, $sig_i)
{
/*
設定
*/
$this->sig = $sig_i;
$this->max = $max_i;
$this->n = $n_i;
$this->o = $o_i;
$this->p = $p_i;
mt_srand();
/*
領域の確保
*/
$this->E = array($this->n);
for ($i1 = 0; $i1 < $this->n; $i1++)
$this->E[$i1] = array($this->p);
$this->W = array($this->o);
for ($i1 = 0; $i1 < $this->o; $i1++)
$this->W[$i1] = array($this->p);
}
/**************************/
/* 学習データの読み込み */
/* name : ファイル名 */
/**************************/
function Input($name)
{
$st = fopen($name, "rb");
for ($i1 = 0; $i1 < $this->n; $i1++) {
$str = trim(fgets($st));
$this->E[$i1][0] = intval(strtok($str, " "));
for ($i2 = 1; $i2 < $this->p; $i2++)
$this->E[$i1][$i2] = intval(strtok(" "));
}
fclose($st);
}
/*********************************/
/* 学習と結果の出力 */
/* pr : =0 : 画面に出力 */
/* =1 : ファイルに出力 */
/* name : 出力ファイル名 */
/*********************************/
function Learn($pr, $name = "STDOUT")
{
$mx = 0;
$mx_v = 0.0;
/*
初期設定
*/
for ($i1 = 0; $i1 < $this->o; $i1++) {
$sum = 0.0;
for ($i2 = 0; $i2 < $this->p; $i2++) {
$this->W[$i1][$i2] = mt_rand() / mt_getrandmax();
$sum += $this->W[$i1][$i2];
}
$sum = 1.0 / $sum;
for ($i2 = 0; $i2 < $this->p; $i2++)
$this->W[$i1][$i2] *= $sum;
}
/*
学習
*/
for ($count = 0; $count < $this->max; $count++) {
// 訓練例の選択
$k = intval(mt_rand() / mt_getrandmax() * $this->n);
if ($k >= $this->n)
$k = $this->n - 1;
// 出力の計算
for ($i1 = 0; $i1 < $this->o; $i1++) {
$s = 0.0;
for ($i2 = 0; $i2 < $this->p; $i2++)
$s += $this->W[$i1][$i2] * $this->E[$k][$i2];
if ($i1 == 0 || $s > $mx_v) {
$mx = $i1;
$mx_v = $s;
}
}
// 重みの修正
$sum = 0.0;
for ($i1 = 0; $i1 < $this->p; $i1++)
$sum += $this->E[$k][$i1];
for ($i1 = 0; $i1 < $this->p; $i1++)
$this->W[$mx][$i1] += $this->sig * ($this->E[$k][$i1] / $sum - $this->W[$mx][$i1]);
}
/*
出力
*/
if ($pr == 0)
$out = STDOUT;
else
$out = fopen($name, "w");
fwrite($out, "分類結果\n");
for ($i1 = 0; $i1 < $this->n; $i1++) {
$str = "";
for ($i2 = 0; $i2 < $this->p; $i2++)
$str = $str." ".$this->E[$i1][$i2];
$str = $str." Res ";
for ($i2 = 0; $i2 < $this->o; $i2++) {
$s = 0.0;
for ($i3 = 0; $i3 < $this->p; $i3++)
$s += $this->W[$i2][$i3] * $this->E[$i1][$i3];
if ($i2 == 0 || $s > $mx_v) {
$mx = $i2;
$mx_v = $s;
}
}
fwrite($out, $str.($mx+1)."\n");
}
}
}
/****************/
/* main program */
/****************/
if (count($argv) > 1) {
// 基本データの入力
$st = fopen($argv[1], "r");
fscanf($st, "%*s %ld %*s %ld %*s %ld %*s %ld %*s %lf", $max, $p, $o, $n, $sig);
fscanf($st, "%*s %s", $name);
fclose($st);
// ネットワークの定義
$net = new Competition($max, $n, $o, $p, $sig);
$net->Input($name);
// 学習と結果の出力
if (count($argv) == 2)
$net->Learn(0);
else
$net->Learn(1, $argv[2]);
}
else
exit("***error 入力データファイル名を指定して下さい\n");
/*
------------------------入力ファイル--------------
最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
入力データファイル pat.dat
------------------------pat.dat-------------------
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
*/
?>
##########################
# 競合学習
# coded by Y.Suganuma
##########################
#############################
# Competitionクラスの定義
# coded by Y.Suganuma
#############################
class Competition
#########################
# コンストラクタ
# max : 最大学習回数
# n : 訓練例の数
# o : 出力セルの数
# p : 入力セルの数
# sig : 重み修正係数
#########################
def initialize(max_i, n_i, o_i, p_i, sig_i)
# 設定
@_max = max_i
@_n = n_i
@_o = o_i
@_p = p_i
@_sig = sig_i
# 領域の確保
@_e = Array.new(@_n) # 訓練例
for i1 in 0 ...@_n
@_e[i1] = Array.new(@_p)
end
@_w = Array.new(@_o) # 重み
for i1 in 0 ...@_o
@_w[i1] = Array.new(@_p)
end
end
#*************************/
# 学習データの読み込み */
# name : ファイル名 */
#*************************/
def Input(name)
f = open(name, "r")
for i1 in 0 ... @_n
s = f.gets().split(" ")
for i2 in 0 ... @_p
@_e[i1][i2] = Integer(s[i2])
end
end
f.close()
end
#################################
# 学習と結果の出力
# pr : =0 : 画面に出力
# =1 : ファイルに出力
# name : 出力ファイル名
#################################
def Learn(pr, name="")
# 初期設定
mx_v = 0.0
mx = 0
for i1 in 0 ... @_o
sum = 0.0
for i2 in 0 ... @_p
@_w[i1][i2] = rand(0)
sum += @_w[i1][i2]
end
sum = 1.0 / sum
for i2 in 0 ... @_p
@_w[i1][i2] *= sum
end
end
# 学習
for count in 0 ... @_max
# 訓練例の選択
k = Integer(rand(0) * @_n)
if k >= @_n
k = @_n - 1
end
# 出力の計算
for i1 in 0 ... @_o
s = 0.0
for i2 in 0 ... @_p
s += @_w[i1][i2] * @_e[k][i2]
end
if i1 == 0 or s > mx_v
mx = i1
mx_v = s
end
end
# 重みの修正
sum = 0.0
for i1 in 0 ... @_p
sum += @_e[k][i1]
end
for i1 in 0 ... @_p
@_w[mx][i1] += @_sig * (@_e[k][i1] / sum - @_w[mx][i1])
end
end
# 出力
if pr == 0
out = $stdout
else
out = open(name, "w")
end
out.print("分類結果\n")
for i1 in 0 ... @_n
for i2 in 0 ... @_p
out.print(" " + String(@_e[i1][i2]))
end
out.print(" Res ")
for i2 in 0 ... @_o
s = 0.0
for i3 in 0 ... @_p
s += @_w[i2][i3] * @_e[i1][i3]
end
if i2 == 0 or s > mx_v
mx = i2
mx_v = s
end
end
out.print(" " + String(mx+1) + "\n")
end
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])
sig = Float(s[9])
s = gets().split(" ")
name = s[1]
# ネットワークの定義
srand()
net = Competition.new(max, n, o, p, sig)
net.Input(name)
# 学習と結果の出力
if ARGV[0] == nil
net.Learn(0)
else
net.Learn(1, ARGV[0])
end
else
print("***error 入力ファイル名を指定して下さい\n")
end
=begin
------------------------入力ファイル--------------
最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
入力データファイル pat.dat
------------------------pat.dat-------------------
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
=end
# -*- coding: UTF-8 -*-
import numpy as np
import sys
from math import *
from random import *
#############################
# Competitionクラスの定義
# coded by Y.Suganuma
#############################
class Competition :
#########################
# コンストラクタ
# max : 最大学習回数
# n : 訓練例の数
# o : 出力セルの数
# p : 入力セルの数
# sig : 重み修正係数
#########################
def __init__(self, max_i, n_i, o_i, p_i, sig_i) :
# 設定
self.max = max_i
self.n = n_i
self.o = o_i
self.p = p_i
self.sig = sig_i
# 領域の確保
self.E = np.empty((self.n, self.p), np.int) # 訓練例
self.W = np.empty((self.o, self.p), np.float) # 重み
#*************************/
# 学習データの読み込み */
# name : ファイル名 */
#*************************/
def Input(self, name) :
f = open(name, "r")
for i1 in range(0, self.n) :
s = f.readline().split()
for i2 in range(0, self.p) :
self.E[i1][i2] = int(s[i2])
f.close()
#################################
# 学習と結果の出力
# pr : =0 : 画面に出力
# =1 : ファイルに出力
# name : 出力ファイル名
#################################
def Learn(self, pr, name="") :
# 初期設定
mx_v = 0.0
mx = 0
for i1 in range(0, self.o) :
sum = 0.0
for i2 in range(0, self.p) :
self.W[i1][i2] = random()
sum += self.W[i1][i2]
sum = 1.0 / sum
for i2 in range(0, self.p) :
self.W[i1][i2] *= sum
# 学習
for count in range(0, self.max) :
# 訓練例の選択
k = int(random() * self.n)
if k >= self.n :
k = self.n - 1
# 出力の計算
for i1 in range(0, self.o) :
s = 0.0
for i2 in range(0, self.p) :
s += self.W[i1][i2] * self.E[k][i2]
if i1 == 0 or s > mx_v :
mx = i1
mx_v = s
# 重みの修正
sum = 0.0
for i1 in range(0, self.p) :
sum += self.E[k][i1]
for i1 in range(0, self.p) :
self.W[mx][i1] += self.sig * (self.E[k][i1] / sum - self.W[mx][i1])
# 出力
if pr == 0 :
out = sys.stdout
else :
out = open(name, "w")
out.write("分類結果\n")
for i1 in range(0, self.n) :
for i2 in range(0, self.p) :
out.write(" " + str(self.E[i1][i2]))
out.write(" Res ")
for i2 in range(0, self.o) :
s = 0.0
for i3 in range(0, self.p) :
s += self.W[i2][i3] * self.E[i1][i3]
if i2 == 0 or s > mx_v :
mx = i2
mx_v = s
out.write(" " + str(mx+1) + "\n")
##########################
# 競合学習
# 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])
sig = float(s[9])
s = f.readline().split()
name = s[1]
f.close()
# ネットワークの定義
seed()
net = Competition(max, n, o, p, sig)
net.Input(name)
# 学習と結果の出力
if len(sys.argv) == 2 :
net.Learn(0)
else :
net.Learn(1, sys.argv[2])
else :
print("***error 入力ファイル名を指定して下さい")
"""
------------------------入力ファイル--------------
最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
入力データファイル pat.dat
------------------------pat.dat-------------------
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
"""
/****************************/
/* 競合学習 */
/* 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]);
double sig = double.Parse(str[9]);
str = lines[1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
String name = str[1];
// ネットワークの定義
Competition net = new Competition (max, n, o, p, sig);
net.input(name);
// 学習と結果の出力
if (args.Length == 1)
net.learn(0, "");
else
net.learn(1, args[1]);
}
// エラー
else {
Console.WriteLine("***error 入力データファイル名を指定して下さい");
Environment.Exit(1);
}
}
}
/***************************/
/* Competitionクラスの定義 */
/***************************/
class Competition {
int max; // 最大学習回数
int n; // 訓練例の数
int o; // 出力セルの数
int p; // 入力セルの数
int[][] E; // 訓練例
double[][] W; // 重み
double sig; // 重み修正係数
Random rn; // 乱数
/******************/
/* コンストラクタ */
/******************/
public Competition (int max_i, int n_i, int o_i, int p_i, double sig_i)
{
//
// 設定
//
max = max_i;
n = n_i;
o = o_i;
p = p_i;
sig = sig_i;
rn = new Random(); // 乱数の初期設定
//
// 領域の確保
//
E = new int [n][];
for (int i1 = 0; i1 < n; i1++)
E[i1] = new int [p];
W = new double [o][];
for (int i1 = 0; i1 < o; i1++)
W[i1] = new double [p];
}
/**************************/
/* 学習データの読み込み */
/* 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[i1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
for (int i2 = 0; i2 < p; i2++)
E[i1][i2] = int.Parse(str[i2]);
}
}
/*********************************/
/* 学習と結果の出力 */
/* pr : =0 : 画面に出力 */
/* =1 : ファイルに出力 */
/* name : 出力ファイル名 */
/*********************************/
public void learn(int pr, String name)
{
double mx_v = 0.0;
int count, mx = 0;
//
// 初期設定
//
for (int i1 = 0; i1 < o; i1++) {
double sum = 0.0;
for (int i2 = 0; i2 < p; i2++) {
W[i1][i2] = rn.NextDouble();
sum += W[i1][i2];
}
sum = 1.0 / sum;
for (int i2 = 0; i2 < p; i2++)
W[i1][i2] *= sum;
}
//
// 学習
//
for (count = 0; count < max; count++) {
// 訓練例の選択
int k = (int)(rn.NextDouble() * n);
if (k >= n)
k = n - 1;
// 出力の計算
for (int i1 = 0; i1 < o; i1++) {
double s = 0.0;
for (int i2 = 0; i2 < p; i2++)
s += W[i1][i2] * E[k][i2];
if (i1 == 0 || s > mx_v) {
mx = i1;
mx_v = s;
}
}
// 重みの修正
double sum = 0.0;
for (int i1 = 0; i1 < p; i1++)
sum += E[k][i1];
for (int i1 = 0; i1 < p; i1++)
W[mx][i1] += sig * (E[k][i1] / sum - W[mx][i1]);
}
//
// 出力
//
if (pr == 0) {
Console.WriteLine("分類結果");
for (int i1 = 0; i1 < n; i1++) {
for (int i2 = 0; i2 < p; i2++)
Console.Write(" " + E[i1][i2]);
Console.Write(" Res ");
for (int i2 = 0; i2 < o; i2++) {
double s = 0.0;
for (int i3 = 0; i3 < p; i3++)
s += W[i2][i3] * E[i1][i3];
if (i2 == 0 || s > mx_v) {
mx = i2;
mx_v = s;
}
}
Console.WriteLine((mx+1));
}
}
else {
StreamWriter OUT = new StreamWriter(name, true);
OUT.WriteLine("分類結果");
for (int i1 = 0; i1 < n; i1++) {
for (int i2 = 0; i2 < p; i2++)
OUT.Write(" " + E[i1][i2]);
OUT.Write(" Res ");
for (int i2 = 0; i2 < o; i2++) {
double s = 0.0;
for (int i3 = 0; i3 < p; i3++)
s += W[i2][i3] * E[i1][i3];
if (i2 == 0 || s > mx_v) {
mx = i2;
mx_v = s;
}
}
OUT.WriteLine((mx+1));
}
OUT.Close();
}
}
}
/*
------------------------入力ファイル--------------
最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
入力データファイル pat.dat
------------------------pat.dat-------------------
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
*/
'**************************'
' 競合学習 '
' 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))
Dim sig As Double = Double.Parse(str(9))
str = MS.Split(inp.ReadLine().Trim())
Dim name As String = str(1)
inp.Close()
' ネットワークの定義
Dim net As Competition = new Competition (max, n, o, p, sig)
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
'*************************'
' Competitionクラスの定義 '
'*************************'
Class Competition
Private max As Integer ' 最大学習回数
Private n As Integer ' 訓練例の数
Private o As Integer ' 出力セルの数
Private p As Integer ' 入力セルの数
Private E(,) As Integer ' 訓練例
Private W(,) As Double ' 重み
Private sig As Double ' 重み修正係数
Private rn As Random ' 乱数
'****************'
' コンストラクタ '
'****************'
Public Sub New(max_i As Integer, n_i As Integer, o_i As Integer, p_i As Integer, sig_i As Double)
'
' 設定
'
max = max_i
n = n_i
o = o_i
p = p_i
sig = sig_i
rn = new Random() ' 乱数の初期設定
'
' 領域の確保
'
ReDim E(n,p)
ReDim W(o,p)
End Sub
'************************'
' 学習データの読み込み '
' name : ファイル名 '
'************************'
Public Sub input (name As String)
Dim inp As StreamReader = New StreamReader(name)
Dim MS As Regex = New Regex("\s+")
For i1 As Integer = 0 To n-1
Dim str() As String = MS.Split(inp.ReadLine().Trim())
For i2 As Integer = 0 To p-1
E(i1,i2) = Integer.Parse(str(i2))
Next
Next
inp.Close()
End Sub
'*******************************'
' 学習と結果の出力 '
' pr : =0 : 画面に出力 '
' =1 : ファイルに出力 '
' name : 出力ファイル名 '
'*******************************'
Public Sub learn(pr As Integer, name As String)
Dim count As Integer
Dim mx As Integer = 0
Dim mx_v As Double = 0.0
'
' 初期設定
'
For i1 As Integer = 0 To o-1
Dim sum As Double = 0.0
For i2 As Integer = 0 To p-1
W(i1,i2) = rn.NextDouble()
sum += W(i1,i2)
Next
sum = 1.0 / sum
For i2 As Integer = 0 To p-1
W(i1,i2) *= sum
Next
Next
'
' 学習
'
For count = 0 To max-1
' 訓練例の選択
Dim k As Integer = Math.Floor(rn.NextDouble() * n)
If k >= n
k = n - 1
End If
' 出力の計算
For i1 As Integer = 0 To o-1
Dim s As Double = 0.0
For i2 As Integer = 0 To p-1
s += W(i1,i2) * E(k,i2)
Next
If i1 = 0 or s > mx_v
mx = i1
mx_v = s
End If
Next
' 重みの修正
Dim sum As Double = 0.0
For i1 As Integer = 0 To p-1
sum += E(k,i1)
Next
For i1 As Integer = 0 To p-1
W(mx,i1) += sig * (E(k,i1) / sum - W(mx,i1))
Next
Next
'
' 出力
'
If pr = 0
Console.WriteLine("分類結果")
For i1 As Integer = 0 To n-1
For i2 As Integer = 0 To p-1
Console.Write(" " & E(i1,i2))
Next
Console.Write(" Res ")
For i2 As Integer = 0 To o-1
Dim s As Double = 0.0
For i3 As Integer = 0 To p-1
s += W(i2,i3) * E(i1,i3)
Next
If i2 = 0 or s > mx_v
mx = i2
mx_v = s
End If
Next
Console.WriteLine((mx+1))
Next
Else
Dim OUT As StreamWriter = new StreamWriter(name)
OUT.WriteLine("分類結果")
For i1 As Integer = 0 To n-1
For i2 As Integer = 0 To p-1
OUT.Write(" " & E(i1,i2))
Next
OUT.Write(" Res ")
For i2 As Integer = 0 To o-1
Dim s As Double = 0.0
For i3 As Integer = 0 To p-1
s += W(i2,i3) * E(i1,i3)
Next
If i2 = 0 or s > mx_v
mx = i2
mx_v = s
End If
Next
OUT.WriteLine((mx+1))
Next
OUT.Close()
End If
End Sub
End Class
End Module
/*
------------------------入力ファイル--------------
最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
入力データファイル pat.dat
------------------------pat.dat-------------------
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0 0
0 0 0 1 0 1 0 0 0
0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0
*/
| 情報学部 | 菅沼ホーム | 目次 | 索引 |