結果が分かりやすいように記憶パターンを小さめで固定して試しています。最初に結合重みwを求めたあとに未知パターンとしてノイズを与えたものでユニットを初期化して想起を行うものなんですが、どうしても更新とエネルギー関数の計算部分がよくわからず変な値が入ってしまいます。コメントアウトした部分が試したもので、Update_State(w, state) と energy = Calculate_Energy_Function(w, state)の部分がうまくいきません。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
//定数の設定
#define UNIT 4 /* ニューロンのユニット数 */
#define PATTERN 2 /* 記憶パターンの数 */
#define NOISE 10 /* 付加するノイズの数の上限 */
#define LEARNING_TIMES 1e4 /* 学習回数 (終了条件) */
//関数のプロトタイプ宣言
void Generate_Pattern(int pattern[][UNIT]);
void Set_Weight_Value(int pattern[][UNIT], int w[][UNIT]);
void Set_Initial_State(int pattern[][UNIT], int state[]);
void Update_State(int w[][UNIT], int state[]);
double Calculate_Energy_Function(int w[][UNIT], int state[]);
void Display_Pattern(int state[]);
void Display_Pattern2(int state[]);
void Display_Pattern3(int state[]);
void show_state(int state[UNIT]);
void call(int w[UNIT][UNIT]);
void noise(int pattern[UNIT][UNIT], int state[UNIT]);
int main()
{
int pattern[PATTERN][UNIT]; /* 記憶パターン */
int state[UNIT]; /* ネットワ-クの状態 */
int w[UNIT][UNIT]; /* 結合重み */
double energy; /* エネルギ-関数値 */
int iteration;
/* 記憶パターンの生成 (分かりやすいように今は固定)*/
Generate_Pattern(pattern);
/* 重みの設定 */
Set_Weight_Value(pattern, w);
//結合荷重Wの表示
call(w);
/* 乱数の初期化 */
srand((unsigned int)time(NULL));
/* 初期状態の設定 */
Set_Initial_State(pattern, state);
/* 初期状態の表示 */
Display_Pattern(state);
//状態の表示
show_state(state);
//未知パターンで初期化
noise(pattern, state);
/* 未知パターンの表示 */
Display_Pattern(state);
//状態の表示
show_state(state);
/* 学習の開始 */
//想起部分の計算?
for (iteration = 0; iteration < LEARNING_TIMES; iteration++) {
/* 更新の実行 */
Update_State(w, state);
/* エネルギー関数値の計算 */
energy = Calculate_Energy_Function(w, state);
}
/* 途中結果の表示 */
Display_Pattern2(state);
show_state(state);
/* 結果の表示 */
//Display_Pattern3(state);
//show_state(state);
return 0;
}
//いまは固定パターンの生成
void Generate_Pattern(int pattern[PATTERN][UNIT])
{
pattern[0][0] = 1;
pattern[0][1] = 1;
pattern[0][2] = -1;
pattern[0][3] = -1;
pattern[1][0] = -1;
pattern[1][1] = 1;
pattern[1][2] = -1;
pattern[1][3] = 1;
}
/*
* 重みの設定
*
* int pattern : 記憶パターン
* double w : 結合重み
*/
void Set_Weight_Value(int pattern[PATTERN][UNIT], int w[UNIT][UNIT])
{
int i, j, n;
for (i = 0; i < UNIT; i++) {
for (j = 0; j < UNIT; j++) {
w[i][j] = 0;
if (i != j) {
for (n = 0; n < PATTERN; n++) {
w[i][j] += pattern[n][i] * pattern[n][j];
}
}
}
}
}
void call(int w[UNIT][UNIT])
{
int i, j;
for (i = 0; i < UNIT; i++){
for (j = 0; j < UNIT; j++){
if (j % 4 == 0) {
printf("\n");
}
printf("%d ", w[i][j]);
}
}
printf("\n結合重み↑\n");
}
/* 初期状態の設定
* int pattern : 記憶パターン
* int state : ネットワ-クの初期状態
*/
void Set_Initial_State(int pattern[PATTERN][UNIT], int state[UNIT])
{
int p;
int i;
/* 想起するパターンの選定 */
p = rand() % PATTERN;
if (p < 0 || p > PATTERN - 1) {
printf("選択した記憶パターンが範囲外です。\n");
exit(-1);
}
for (i = 0; i < UNIT; i++) {
state[i] = pattern[p][i];
}
printf("\n想起対象 パターン%d", p + 1);
}
//ユニットの初期化
void noise(int pattern[PATTERN][UNIT], int state[UNIT])
{
int i, j;
for (i = 0; i < NOISE; i++) {
j = rand() % UNIT;
if (state[j] == -1) {
state[j] = 1;
}
else {
state[j] = -1;
}
}
printf("\nユニットを未知パターンで初期化");
}
/*
* 状態の更新
* int w : 結合重み
* int state : ネットワ-クの状態
*/
void Update_State(int w[UNIT][UNIT], int state[UNIT])
{
int i, j, n;
int out;
for (i = 0; i < UNIT; i++) {
for (j = 0; j < UNIT; j++) {
for (n = 0; n < UNIT; n++){
//エネルギーが収束したとき終了?
//printf("\n%d * %d \n",w[i][j],state[j]);
//state[j] = w[i][j] + state[j];
}
}
}
}
/*
* エネルギー関数値の計算
*
* doubel w : 結合重み
* int state : ネットワ-クの状態
*/
double Calculate_Energy_Function(int w[UNIT][UNIT], int state[UNIT])
{/*
int i, j;
double energy = 0;
for (i = 0; i < UNIT; i++){
for (j = 0; j < UNIT; j++){
energy = -0.5*(w[i][j]*(state[i]*state[j]));
}
}
return (energy);*/
}
/*
* パターンの表示
*
* int state : ネットワ-クの状態
*/
void Display_Pattern(int state[UNIT])
{
int i;
printf("\n");
if (state[0] == 1)
printf("■");
else
printf("□");
for (i = 1; i < UNIT; i++) {
if (i % 10 == 0) {
printf("\n");
}
if (state[i] == 1)
printf("■");
else
printf("□");
}
printf("\n");
}
void Display_Pattern2(int state[UNIT])
{
int i;
printf("\nユニットの内部状態");
printf("\n");
if (state[0] == 1)
printf("■");
else
printf("□");
for (i = 1; i < UNIT; i++) {
if (i % 10 == 0) {
printf("\n");
}
if (state[i] == 1)
printf("■");
else
printf("□");
}
printf("\n");
}
void Display_Pattern3(int state[UNIT])
{
int i;
printf("\n想起結果");
printf("\n");
if (state[0] == 1)
printf("■");
else
printf("□");
for (i = 1; i < UNIT; i++) {
if (i % 10 == 0) {
printf("\n");
}
if (state[i] == 1)
printf("■");
else
printf("□");
}
printf("\n");
}
void show_state(int state[UNIT])
{
int i;
for (i = 0; i < UNIT; i++){
printf("%d ", state[i]);
}
printf("\n");
}