神经网络的文件,二进制方式读取

   是一次惨痛的教训,再写神经网络时,就很疑惑。

   为什么有时运算会出错,大量检查算法,因为它是不经常的错误,所以没留意。

   rb与r,w与bw最好配对,因为w写fwrite会在每个0A前加0D(换行,回车)(window平台)

   r是在自动转0A,但用rb就不同了。

  所以每一次调文件,训练结果总是怪怪的。

更新了~~~~

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<iostream>
using namespace std;

class Cell
{
public:
    int insig_row, out_columu; double v;
    double* out;
    double** w;
    double* insig;
    double* back_e;
    Cell()
    {
        v = 1;
        printf("cell success\n");
    }
    void initCell(int out_columu, int insig_row)
    {
        int i, j;
        this->out_columu = out_columu;
        this->insig_row = insig_row;
        this->out = new double[out_columu];
        this->w = new double* [insig_row];
        for (i = 0; i < insig_row; i++)
            this->w[i] = new double[out_columu];
        srand(time(NULL));
        for (i = 0; i < insig_row; i++)
            for (j = 0; j < out_columu; j++)
                this->w[i][j] = ((double)rand() / ((RAND_MAX - 1) / 2)) - 1;
        this->insig = new double[insig_row];
        this->back_e = new double[out_columu];
        printf("initCell success\n");
        //printf("insig_row:%d     out_columu:%d\n", this->insig_row,this->out_columu);
    }
    void Loadcell(double* w, int out_columu, int insig_row)
    {
        this->out_columu = out_columu;
        this->insig_row = insig_row;
        this->out = new double[out_columu];
        this->w = new double* [insig_row];
        for (int i = 0; i < insig_row; i++)
            this->w[i] = new double[out_columu];
        for (int i = 0; i < insig_row; i++)
            for (int j = 0; j < out_columu; j++)
                this->w[i][j] = w[j+i* out_columu];
        this->insig = new double[insig_row];
        this->back_e = new double[out_columu];
        printf("LoadCell success\n");
    }

    ~Cell()
    {
        delete this->out;
        for (int i = 0; i < insig_row; i++)
        {
            delete (this->w[i]);
        }
        delete w;
        delete this->insig;
        delete this->back_e;
        printf("Cell delete ok!\n");
    }
    double sig(double x)
    {
        return 1 / (1 + exp(-x));
    }
    double* forward(double* out, int outlength)
    {
        if (outlength < out_columu)
        {
            printf("缺少输入\n");
            return 0;
        }
        int i, j; double sum = 0;
        for (j = 0; j < insig_row; j++)
        {
            sum = 0;
            for (i = 0; i < out_columu && i < outlength; i++)
            {
                this->out[i] = out[i];
                sum += this->out[i] * w[j][i];
            }
            insig[j] = sig(sum);
            //insig[j] = sum;
        }
        return insig;
    }
    double* backward(double* e, int elength)
    {
        if (elength < insig_row)
        {
            printf("缺少误差输入\n");
            return 0;
        }
        int i, j, k; double sum = 0;
        for (i = 0; i < out_columu; i++)
        {
            sum = 0;
            for (j = 0; j < insig_row; j++)
                sum += insig[j] * (1 - insig[j]) * w[j][i];
            back_e[i] = sum;
        }
        for (j = 0; j < insig_row; j++)
            for (i = 0; i < out_columu; i++)
                w[j][i] = w[j][i] + e[j] * insig[j] * (1 - insig[j]) * out[i] * v;
        //w[j][i] = w[j][i] + e[j] *out[i];
        return back_e;
    }
    void adjust_v(double* e, int elength)
    {
        double sum = 0;
        for (int i = 0; i < elength; i++)
            sum += fabs(e[i]);        this->v = sin((3.1415926 / 2) * (sum / elength));
        printf(" 学习率:   %lf  sum: %lf\n", v, sum);
    }
    void print(void)
    {
        int i, j;
        printf("矩阵:\n");
        for (i = 0; i < insig_row; i++)
        {
            for (j = 0; j < out_columu; j++)
                printf("%+9.8lf ", this->w[i][j]);
            printf("\n");
        }
        printf("out_columu:%d   insig_row:%d\n",out_columu, insig_row);
    }
};
void printeroror(double* e, int elength)
{
    double sum = 0;
    printf("误差:");
    for (int i = 0; i < elength; i++)
    {
        printf("%-9.6lf ", e[i]);
        //sum += e[i];
    }
    //printf("总误差:%lf", sum);
    printf("\n");
}
void printout(double* out, int i)
{
    printf("输出:");
    for (int i = 0; i < 3; i++)
    {
        printf("%-9.4lf ", out[i]);
    }
    printf("\n");
}


class network
{
public:
      Cell* cells;
      int times = 50000, * layers = NULL, num;
      double* e;
      double* input;
      double* output;
      void createnetwork()
      {
          int  mid, i;
          printf("输入层数:");
          scanf("%d", &num);
          printf("输入次数:");
          scanf("%d", &this->times);
          layers = new int[num + 1];
          cells = new Cell[num - 1];
          printf("输入每层的输出数:");
          for (int i = 0; i < num; i++)
              scanf("%d", &layers[i]);
          for (int j = 0, i = 0; j < num - 1; j++, i++)
          {
              cells[i].initCell(layers[j], layers[j + 1]);
          }
          layers[num] = 0;
          printf("layers[]:");/*layers信息*/
          for (i = 0; i < num; i++)
          {
              printf("%d ", layers[i]);
          }
          printf("\n");
      }
      void clear()
      {
          delete layers;
          delete[]cells;
          delete e;
          printf("network delete ok!\n");
      }
      void Trainnetwork(double* input, double* target)
      {
          double* cellin, *cell_e; int i;
          e = new double[layers[num-1]];
          cellin = input;
          for (int k = 0; k < times; k++)
          {
              for (i = 0; i < num-1; i++)
              {
                  cellin = cells[i].forward(cellin, layers[i]);
                  //printout(cellin,layers[i]);
              }
              for (i = 0; i < layers[num-1]; i++)
              {
                  e[i] = target[i] - cellin[i];
              }
              printeroror(e, layers[num-1]);
              cell_e = e;
              for (i = num-1-1; i >= 0; i--)
              {
                  cell_e = cells[i].backward(cell_e, layers[i+1]);
              }
          }
      }

      void savenetwork()
      {
          char name[30] = { '\0' }; 
          printf("savenetwork输入文件名:\n");
          scanf("%s", &name);
          strcat(name, ".network");
          FILE* netfile = fopen(name, "wb");
          fseek(netfile, 0, SEEK_SET);
          fwrite(layers,sizeof(int)*(num+1), 1, netfile);
          for (int i = 0; i < num - 1; i++)
          {    
              for(int j=0;j< cells[i].insig_row;j++)
                 fwrite(cells[i].w[j], sizeof(double) , cells[i].out_columu, netfile);
          }
          fclose(netfile);
      }
      void readnekwork()
      {
          char name[30] = { '\0' }; int c = 1, * p = &c; num = 0;
          double* read_w;
          printf("readnekwork输入文件名:\n");
          scanf("%s", &name);
          strcat(name, ".network");
          FILE* netfile = fopen(name, "rb");
          printf("OK!!!!\n");
          if (!netfile)
          {
              printf("文件不存在!\n");
              return;
          }
          fseek(netfile, 0, SEEK_SET);
          layers = new int[10000];
          while (*p != 0)
          {
              fread(p, sizeof(int), 1, netfile);
              layers[num++] = *p;
              if (num > 9990)
              {
                  printf("文件层数过大\n");
                  return;
              }

          }
          printf("read layers:");
          for (int k = 0; k < num; k++)
              printf("%d ", layers[k]);
          printf("\n");
          cells = new Cell[num - 1];
          read_w = new double[1000000];
          for (int j = 0, i = 0; j < num - 1; j++, i++)
          {

              fread(read_w, sizeof(double) * layers[j] * layers[j + 1],1, netfile);
              printf("read read_w:");
              for (int k = 0; k < layers[j] * layers[j + 1]; k++)
                  printf("%lf ", read_w[k]);
              printf("\n");
              cells[i].Loadcell(read_w, layers[j], layers[j + 1]);
          } 
          delete read_w;
      }


      void printcells()
      {
          for (int i = 0; i < num - 1; i++)
          {
              cells[i].print();
          }
      }
};

int main()
{
   network net; double input[3] = { 0.9,0.3,0.4 }, target[3] = { 0.5,0.5,0.5 };
  net.createnetwork();
  net.printcells();
  net.Trainnetwork(input, target);
  net.printcells();
   net.savenetwork();
  net.readnekwork();
  net.printcells();
  net.clear();

    return 0;
}

已经完成存储,训练了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值