Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1923052
  • 博文数量: 261
  • 博客积分: 8073
  • 博客等级: 中将
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-10 15:23
文章分类

全部博文(261)

文章存档

2013年(1)

2012年(1)

2011年(50)

2010年(34)

2009年(4)

2008年(17)

2007年(55)

2006年(99)

分类:

2007-04-14 08:17:20

神经网络程序之二:Bolzimann Machine
 
存在一些问题:实际概率运算过程后总是稳定在1111状态,可能事流程理解的问题

#include
#include
#include
#include
#include
#include "utility.h"

#define MAXNERVE 10 //最大神经元数
#define MAXSTATE 1024
#define E0  0.2356

int quick = 1; 
double W[MAXNERVE][MAXNERVE]; //权值
double w[MAXNERVE]; //阈值
int output[MAXNERVE]; //输出 0/1
double H[MAXNERVE]; //神经元内部状态
double counter[MAXSTATE];  //状态计数/每种状态的实际概率
double *P;  //每种状态的理论概率
double *E; //每种状态的能量


int NUM_NERVE; //实际神经元数量
int NUM_STATE; //状态数量
double INITIAL_TMP; //初始温度
double FINAL_TMP; //最终温度

char *paramfile = "1.PARAM"; //参数文件
char *resultfile = "1.RESULT";

void load_param(); //从文件加载参数(神经元数量、初始温度、最终温度)
void initialize(); //初始化
void init_weight();  //初始化权值、阈值
void compute_energy(); //计算各个状态能量
void compute_P(); //计算理论概率
void process();  //处理过程
double compute_Hi(int i); //求神经元i的内部状态
void print_all(); //打印输出
void display_theory(FILE *fp); //显示不同状态的能量和理论概率
void dtob(int *o, int o_num, int i); //十进制转二进制
int btod(int *o, int o_num); //二进制转十进制
/********************************************************************
      程序入口
********************************************************************/
int main(int argc, char **args)
{
 if(argc == 3){
  paramfile = args[1];
  quick = args[2][0] - '0';
 }
 load_param();
 initialize();
 process();
 print_all();
 return(1);
}

/********************************************************************
   从文件加载参数(神经元数量、初始温度、最终温度)
********************************************************************/
void load_param()
{
 FILE *fp = fopen(paramfile, "r");
 if(fp == NULL){
  printf("\n不能打开参数文件: %s\n", paramfile);
  exit(0);
 }
 fscanf(fp, "%d", &NUM_NERVE);
 fscanf(fp, "%lf", &INITIAL_TMP);
 fscanf(fp, "%lf", &FINAL_TMP);
 fclose(fp);
 if(NUM_NERVE > MAXNERVE){
  printf("\n神经元最大不能超过10个\n");
  exit(0);
 }
}

/********************************************************************
      初始化
********************************************************************/
void initialize()
{
 NUM_STATE = 2 << (NUM_NERVE-1);
 if((P = (double *)malloc(sizeof(double) * NUM_STATE)) == NULL){
  printf("\n分配理论概率失败\n");
  exit(0);
 }
 if((E = (double *)malloc(sizeof(double) * NUM_STATE)) == NULL){
  printf("\n分配能量失败\n");
  exit(0);
 }
 init_weight();
 compute_P();
}
/********************************************************************
      初始化权值、阈值
********************************************************************/
void init_weight()
{
 int i, j;
 for(i = 0;i < NUM_NERVE;i++){
  for(j = 0;j < i + 1;j++)
   W[i][j] = W[j][i] = gen_random();
  w[i] = gen_random();
 }
 for(i = 0;i < NUM_STATE;i++){
  counter[i] = 0;
 }
}

/********************************************************************
      计算理论概率
********************************************************************/
void compute_P()
{
 int i;
 double tmp = 0;
 compute_energy();
 for(i = 0;i < NUM_STATE;i++){
  tmp += exp(-E[i]/INITIAL_TMP);
 }
 for(i = 0;i < NUM_STATE;i++){
  P[i] = exp(-E[i]/INITIAL_TMP)/tmp;
 }  

}
/********************************************************************
      计算各个状态能量
********************************************************************/
void compute_energy()
{
 int i, j, k;
 double tmp1 = 0, tmp2 = 0;
 for(k = 0;k < NUM_STATE;k++){
  tmp1 = 0;
  tmp2 = 0;
  dtob(output, NUM_NERVE, k);
  for(i = 0;i < NUM_NERVE;i++){
   for(j = 0;j < NUM_NERVE;j++){
    if(j == i)
     continue;
    tmp1 += W[i][j]*output[i]*output[j];
   }
   tmp1 -= w[i]*output[i];
  }
  E[k] = -0.5*tmp1;
 }
}
/********************************************************************
      处理过程
********************************************************************/
void process()
{
 double temperature = INITIAL_TMP, tmp;
 int i, rand_nerve, t = 0;
 dtob(output, NUM_NERVE, random(NUM_STATE));
 while(temperature > FINAL_TMP){
  rand_nerve = random(NUM_NERVE);
  H[rand_nerve] = compute_Hi(rand_nerve);
  if(H[rand_nerve] > 0)
   output[rand_nerve] = 1;
  else if(H[rand_nerve] < 0){
   tmp = 1/(1 + exp(-H[rand_nerve]/temperature));
   if(tmp > E0)
    output[rand_nerve] = 1;
  }
  printf("");
  i = btod(output, NUM_NERVE);
  counter[i] += 1;
  if(quick == 1)
   temperature = INITIAL_TMP/(t + 1 + 1);
  else
   temperature = INITIAL_TMP/log(t + 1);
  t++;
  printf("\n第%d次退火,当前温度为%lf\n", t, temperature);
 }
 for(i = 0;i < NUM_STATE;i++){
  printf("counter[%d] = %ld\n", i, counter[i]);
  counter[i] /= t;
 }
}

/********************************************************************
      求神经元i的内部状态
********************************************************************/
double compute_Hi(int i)
{
 int j;
 double tmp = 0;
 for(j = 0;j < NUM_NERVE;j++)
  if(j == i)
   continue;
  tmp += W[i][j]*output[j];
 tmp -= w[i];
 return tmp;
}


/********************************************************************
      打印输出
********************************************************************/
void print_all()
{
 FILE *fp = fopen(resultfile, "w");
 if(fp == NULL){
  printf("\n不能打开结果文件: %s\n", resultfile);
  exit(0);
 }
 printf("\n权值");
 fprintf(fp, "\n权值");
 print_two(fp, (double **)W, NUM_NERVE, NUM_NERVE, MAXNERVE, MAXNERVE);
 printf("\n阈值");
 fprintf(fp, "\n阈值");
 print_one(fp, w, NUM_NERVE);
 display_theory(fp);
 fclose(fp);
}
/********************************************************************
      十进制转二进制
********************************************************************/
void dtob(int *o, int o_num, int i)
{
 int j;
 for(j = 0;j < o_num;j++){
  o[j] = (i >> j) & 0x00000001;
 }
}
/********************************************************************
      二进制转十进制
********************************************************************/
int btod(int *o, int o_num)
{
 int i = 0, j;
 for(j = 0;j < o_num;j++){
  i += (o[j] << j);
 }
 return i;
}
/********************************************************************
      显示不同状态的能量和理论概率
********************************************************************/
void display_theory(FILE *fp)
{
 int k;
 if(fp == NULL){
  printf("\n没有结果文件: %s\n", resultfile);
  return;
 }
 printf("\n不同状态的能量、理论概率、实际概率\n");
 fprintf(fp, "\n不同状态的能量、理论概率、实际概率\n");
 printf("*********************************************************\n");
 fprintf(fp, "*********************************************************\n");
 printf("状态\t  能量  \t理论概率  \t实际概率\n");
 fprintf(fp, "状态\t能量\t理论概率\t实际概率\n");
 for(k = 0;k < NUM_STATE;k++){
  printf("%d\t%lf\t%lf\t%lf\n", k, E[k], P[k], counter[k]);
  fprintf(fp, "%d\t%lf\t%lf\t%lf\n", k, E[k], P[k], counter[k]);
 }
 printf("********************************************************\n");
 fprintf(fp, "********************************************************\n");
}
 

阅读(951) | 评论(0) | 转发(0) |
0

上一篇:HOPFIELD网(c语言)

下一篇:BP网(C语言实现)

给主人留下些什么吧!~~