| 情報学部 | 菅沼ホーム | 目次 | 索引 |
/****************************/
/* 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
*/
| 情報学部 | 菅沼ホーム | 目次 | 索引 |