c - 段错误(核心转储)神经网络

标签 c machine-learning neural-network instructions

我有一个 3 层神经网络,但出现了段错误。我知道这意味着我正在写入错误的内存空间。在这种情况下,我猜这是因为我的空间不足。

问题是我已经calloc了我所有的大型商店元素,所以我认为这可以解决这个问题。

gdb 在线上卡住

   81                 for( j = 0 ; j < NumHidden ; j++ ) {    /* compute hidden unit activations */
   82                     SumH[p][j] = WeightIH[0][j] ;
-> 83                     for( i = 0 ; i < NumInput ; i++ ) {
   84                         temp1 = Input[game][0][i] * WeightIH[i][j] ;

代码如下:

    /*******************************************************************************
*    nn.c   1.0                                       � JOHN BULLINARIA  2004  *
*******************************************************************************/

/*      To compile use "cc nn.c -O -lm -o nn" and then run using "./nn"       */
/*      For explanations see:  http://www.cs.bham.ac.uk/~jxb/NN/nn.html       */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <fcntl.h>

#define NUMPAT 51
#define NUMIN  51
#define NUMHID 20
#define NUMOUT 20

#define rando() ((double)rand()/(RAND_MAX+1))

int main() {
    int    i, j, k, p, np, op, ranpat[NUMPAT+1], epoch, temp1, temp2, game;
    int    NumPattern = NUMPAT, NumInput = NUMIN, NumHidden = NUMHID, NumOutput = NUMOUT;

    double ***Input = calloc(51*40, sizeof(double ***));
    char line[128];
    int varCount = 0;
    double num;

    FILE *csvFile = fopen("ks vs tt.csv", "r");

    if (csvFile){
      char *token;
      while (fgets(line, 1024, csvFile)){
        token = strtok(&line[0], ",");
        while(token){
          num = atof(token);
          Input[varCount] = &num;
          token = strtok(NULL, ",");
          varCount++;
        }
      }
      fclose(csvFile);
    }
    double Target[20] = {10,10,3,-4,11,-2,13,-5,4,3,4,5,-5,25,13,25,3,2,5,17};
    double **SumH = calloc(51*20, sizeof(double **));
    double **WeightIH = calloc(51*20, sizeof(double **));
    double **Hidden = calloc(51*20, sizeof(double **));
    double **SumO= calloc(51*20, sizeof(double **));
    double **WeightHO = calloc(51*20, sizeof(double **));
    double **Output = calloc(51*20, sizeof(double **));
    double *DeltaO = calloc(51*20, sizeof(double *));
    double *SumDOW = calloc(51*20, sizeof(double *));
    double *DeltaH = calloc(51*20, sizeof(double *));
    double **DeltaWeightIH = calloc(51*20, sizeof(double **));
    double **DeltaWeightHO = calloc(51*20, sizeof(double **));
    double Error, eta = 0.5, alpha = 0.9, smallwt = 0.5;

    for( j = 0 ; j < NumHidden ; j++ ) {    /* initialize WeightIH and DeltaWeightIH */
        for( i = 0 ; i < NumInput ; i++ ) {
            DeltaWeightIH[i][j] = 0.0 ;
            WeightIH[i][j] = 2.0 * ( rand() - 0.5 ) * smallwt ;
        }
    }
    for( k = 0 ; k < NumOutput ; k ++ ) {    /* initialize WeightHO and DeltaWeightHO */
        for( j = 0 ; j < NumHidden ; j++ ) {
            DeltaWeightHO[j][k] = 0.0 ;
            WeightHO[j][k] = 2.0 * ( rand() - 0.5 ) * smallwt ;
        }
    }

    for( epoch = 0 ; epoch < 100000 ; epoch++) {    /* iterate weight updates */
        for( p = 1 ; p <= NumPattern ; p++ ) {    /* randomize order of individuals */
            ranpat[p] = p ;
        }
        for( p = 1 ; p <= NumPattern ; p++) {
            np = p + rand() * ( NumPattern + 1 - p ) ;
            op = ranpat[p] ;
            ranpat[p] = ranpat[np] ;
            ranpat[np] = op ;
        }
        Error = 0.0 ;
        for( np = 1 ; np <= NumPattern ; np++ ) {    /* repeat for all the training patterns */
            p = ranpat[np];
            for (game = 0; game < 20; game++){
              for( j = 0 ; j < NumHidden ; j++ ) {    /* compute hidden unit activations */
                  SumH[p][j] = WeightIH[0][j] ;
                  for( i = 0 ; i < NumInput ; i++ ) {
                      temp1 = Input[game][0][i] * WeightIH[i][j] ;
                      temp2 = Input[game][1][i] * WeightIH[i][j] ;
                      SumH[p][j] += temp1 - temp2 ;
                  }
                  Hidden[p][j] = 1.0/(1.0 + exp(-SumH[p][j])) ;
              }
              for( k = 0 ; k < NumOutput ; k++ ) {    /* compute output unit activations and errors */
                  SumO[p][k] = WeightHO[0][k] ;
                  for( j = 0 ; j < NumHidden ; j++ ) {
                      SumO[p][k] += Hidden[p][j] * WeightHO[j][k] ;
                  }
                  Output[p][k] = 1.0/(1.0 + exp(-SumO[p][k])) ;   /* Sigmoidal Outputs */
  /*              Output[p][k] = SumO[p][k];      L
ear Outputs */
                  Error += 0.5 * (Target[k] - Output[p][k]) * (Target[k] - Output[p][k]) ;   /* SSE */
  /*              Error -= ( Target[p][k] * log( Output[p][k] ) + ( 1.0 - Target[p][k] ) * log( 1.0 - Output[p][k] ) ) ;    Cross-Entropy Error */
                  DeltaO[k] = (Target[k] - Output[p][k]) * Output[p][k] * (1.0 - Output[p][k]) ;   /* Sigmoidal Outputs, SSE */
  /*              DeltaO[k] = Target[p][k] - Output[p][k];     Sigmoidal Outputs, Cross-Entropy Error */
  /*              DeltaO[k] = Target[p][k] - Output[p][k];     Linear Outputs, SSE */
              }
              for( j = 0 ; j < NumHidden ; j++ ) {    /* 'back-propagate' errors to hidden layer */
                  SumDOW[j] = 0.0 ;
                  for( k = 0 ; k < NumOutput ; k++ ) {
                      SumDOW[j] += WeightHO[j][k] * DeltaO[k] ;
                  }
                  DeltaH[j] = SumDOW[j] * Hidden[p][j] * (1.0 - Hidden[p][j]) ;
              }
              for( j = 0 ; j < NumHidden ; j++ ) {     /* update weights WeightIH */
                  DeltaWeightIH[0][j] = eta * DeltaH[j] + alpha * DeltaWeightIH[0][j] ;
                  WeightIH[0][j] += DeltaWeightIH[0][j] ;
                  for( i = 0 ; i < NumInput ; i++ ) {
                      DeltaWeightIH[i][j] = eta * Input[game][0][i] * DeltaH[j] + alpha * DeltaWeightIH[i][j];
                      WeightIH[i][j] += DeltaWeightIH[i][j] ;
                  }
              }
              for( k = 0 ; k < NumOutput ; k ++ ) {    /* update weights WeightHO */
                  DeltaWeightHO[0][k] = eta * DeltaO[k] + alpha * DeltaWeightHO[0][k] ;
                  WeightHO[0][k] += DeltaWeightHO[0][k] ;
                  for( j = 0 ; j < NumHidden ; j++ ) {
                      DeltaWeightHO[j][k] = eta * Hidden[p][j] * DeltaO[k] + alpha * DeltaWeightHO[j][k] ;
                      WeightHO[j][k] += DeltaWeightHO[j][k] ;
                  }
              }
            }

        }
        if( epoch%100 == 0 ) fprintf(stdout, "\nEpoch %-5d :   Error = %f", epoch, Error) ;
        if( Error < 0.0004 ) break ;  /* stop learning when 'near enough' */
    }
    int sum = 0;
    double weights[51];
    for (i = 0; i < NumInput; i++){
      for (j = 0; j < NumHidden; j++){
        sum = WeightIH[i][j];
      }
      sum /= 51;
      weights[i] = sum;
    }
    for (i = 0; i < 51; i++){
      printf("weight[%d] = %G\n", i, weights[i]);
    }
    return 1 ;
}

/*******************************************************************************/

我正在编译:gcc nn.c -O -lm -o nn -mmacosx-version-min=10.11并且它编译得很好。

知道这里发生了什么吗?

最佳答案

这一行:

double ***Input = calloc(51*40, sizeof(double ***)); 

正在分配一个指向 double 指针数组的指针数组。

但是,仅分配了数组的第一层。

对于第一次分配中的每个数组,

需要为每个第二级数组进行分配

以及第二级数组中每个第三级数组的分配。

使用 ** 分配和 *** 分配时,代码的多个区域都会显示此问题。

代码正在访问它不拥有的内存。 <<=崩溃的根源>>

以下代码中未解决此(上述)问题:

这是一个实现注释的版本,

但没有解决内存分配问题

但不处理有关无效指针赋值的问题,也不处理有关隐式转换的 3 个问题。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <fcntl.h>
#include <string.h>

#define NUMPAT (51)
#define NUMIN  (51)
#define NUMHID (20)
#define NUMOUT (20)

#define MAX_EPOCH      (100000)
#define ALLOC_51x40    (51*40)
// used larger allocation (above) so next line not used
//#define ALLOC_51x20    (51*20)
#define MAX_LINE_LEN   (128)
#define MAX_TARGET_LEN (20)

#define rando() ((double)rand()/(RAND_MAX+1))


    // removed some unneeded local variables
    // int    NumPattern = NUMPAT, NumInput = NUMIN, NumHidden = NUMHID, NumOutput = NUMOUT;


int main( void )
{
    int i;
    int j;
    int k;
    int p;
    int np;
    int op;
    int ranpat[NUMPAT+1];
    int epoch;
    int temp1;
    int temp2;
    int game;

    double ***Input = NULL;
    if( NULL == (Input = calloc(ALLOC_51x40, sizeof(double ***)) ) )
    { // then calloc failed
        perror( "calloc failed");
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    FILE *csvFile = NULL;
    if( NULL == (csvFile = fopen("ks vs tt.csv", "r") ) )
    { // then fopen failed
        perror( "fopen failed for read of ks vs tt.csv" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    char line[ MAX_LINE_LEN ];
    int varCount = 0;
    double num;
    char *token;

    while ( ALLOC_51x40 < varCount && fgets(line, sizeof(line), csvFile))
    {
        token = strtok(&line[0], ",");

        while(token)
        {
            num = atof(token);
            Input[varCount] = &num;
            token = strtok(NULL, ",");
            varCount++;
        }
    }
    fclose(csvFile);


    double Target[ MAX_TARGET_LEN ] =
    {
        10.0,
        10.0,
        3.0,
        -4.0,
        11.0,
        2.0,
        13.0,
        -5.0,
        4.0,
        3.0,
        4.0,
        5.0,
        -5.0,
        25.0,
        13.0,
        25.0,
        3.0,
        2.0,
        5.0,
        17.0
    };

    double **SumH = NULL;
    if( NULL == (SumH = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for SumH" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double **WeightIH = NULL;
    if( NULL == (WeightIH = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for WeighIH" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double **Hidden = NULL;
    if( NULL == (Hidden = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for Hidden" );
        exit( EXIT_FAILURE);
    }

    // implied else, calloc successful

    double **SumO = NULL;
    if( NULL == (SumO = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for SumO" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double **WeightHO = NULL;
    if( NULL == (WeightHO = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for WeightHo" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double **Output = NULL;
    if( NULL == (Output = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for Output" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double *DeltaO = NULL;
    if( NULL == (DeltaO = calloc(ALLOC_51x40, sizeof(double *)) ) )
    { // then calloc failed
        perror( "calloc failed for DeltaO" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double *SumDOW = NULL;
    if( NULL == (SumDOW = calloc(ALLOC_51x40, sizeof(double *)) ) )
    { // then calloc failed
        perror( "calloc failed for SumDOW" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double *DeltaH = NULL;
    if( NULL == (DeltaH = calloc(ALLOC_51x40, sizeof(double *)) ) )
    { // then calloc failed
        perror( "calloc failed for DeltaH" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double **DeltaWeightIH = NULL;
    if( NULL == (DeltaWeightIH = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for DeltaWeightIH" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double **DeltaWeightHO = NULL;
    if( NULL == (DeltaWeightHO = calloc(ALLOC_51x40, sizeof(double **)) ) )
    { // then calloc failed
        perror( "calloc failed for DeltaWeightHO" );
        exit( EXIT_FAILURE );
    }

    // implied else, calloc successful

    double Error   = 0.0;
    double eta     = 0.5;
    double alpha   = 0.9;
    double smallwt = 0.5;

    for( j = 0 ; j < NUMHID ; j++ )
    {    /* initialize WeightIH and DeltaWeightIH */
        for( i = 0 ; i < NUMIN ; i++ )
        {
            DeltaWeightIH[i][j] = 0.0 ;
            WeightIH[i][j] = 2.0 * ( rand() - 0.5 ) * smallwt ;
        }
    }

    for( k = 0 ; k < NUMOUT ; k ++ )
    {    /* initialize WeightHO and DeltaWeightHO */
        for( j = 0 ; j < NUMHID ; j++ )
        {
            DeltaWeightHO[j][k] = 0.0 ;
            WeightHO[j][k] = 2.0 * ( rand() - 0.5 ) * smallwt ;
        }
    }

    for( epoch = 0 ; epoch < MAX_EPOCH ; epoch++)
    {    /* iterate weight updates */
        for( p = 1 ; p <= NUMPAT ; p++ )
        {    /* randomize order of individuals */
            ranpat[p] = p ;
        }

        for( p = 1 ; p <= NUMPAT ; p++)
        {
            np = p + rand() * ( NUMPAT + 1 - p ) ;
            op = ranpat[p] ;
            ranpat[p] = ranpat[np] ;
            ranpat[np] = op ;
        }

        Error = 0.0 ;
        for( np = 1 ; np <= NUMPAT ; np++ )
        {    /* repeat for all the training patterns */
            p = ranpat[np];

            for (game = 0; game < 20; game++)
            {
              for( j = 0 ; j < NUMHID ; j++ )
              {    /* compute hidden unit activations */
                  SumH[p][j] = WeightIH[0][j] ;
                  for( i = 0 ; i < NUMIN ; i++ )
                  {
                      temp1 = Input[game][0][i] * WeightIH[i][j] ;
                      temp2 = Input[game][1][i] * WeightIH[i][j] ;
                      SumH[p][j] += temp1 - temp2 ;
                  }

                  Hidden[p][j] = 1.0/(1.0 + exp(-SumH[p][j])) ;
              }

              for( k = 0 ; k < NUMOUT ; k++ )
              {    /* compute output unit activations and errors */
                  SumO[p][k] = WeightHO[0][k] ;

                  for( j = 0 ; j < NUMHID ; j++ )
                  {
                      SumO[p][k] += Hidden[p][j] * WeightHO[j][k] ;
                  }

                  Output[p][k] = 1.0/(1.0 + exp(-SumO[p][k])) ;   /* Sigmoidal Outputs */
  /*              Output[p][k] = SumO[p][k];      L
ear Outputs */
                  Error += 0.5 * (Target[k] - Output[p][k]) * (Target[k] - Output[p][k]) ;   /* SSE */
  /*              Error -= ( Target[p][k] * log( Output[p][k] ) + ( 1.0 - Target[p][k] ) * log( 1.0 - Output[p][k] ) ) ;    Cross-Entropy Error */
                  DeltaO[k] = (Target[k] - Output[p][k]) * Output[p][k] * (1.0 - Output[p][k]) ;   /* Sigmoidal Outputs, SSE */
  /*              DeltaO[k] = Target[p][k] - Output[p][k];     Sigmoidal Outputs, Cross-Entropy Error */
  /*              DeltaO[k] = Target[p][k] - Output[p][k];     Linear Outputs, SSE */
              }

              for( j = 0 ; j < NUMHID ; j++ )
              {    /* 'back-propagate' errors to hidden layer */
                  SumDOW[j] = 0.0 ;

                  for( k = 0 ; k < NUMOUT ; k++ )
                  {
                      SumDOW[j] += WeightHO[j][k] * DeltaO[k] ;
                  }

                  DeltaH[j] = SumDOW[j] * Hidden[p][j] * (1.0 - Hidden[p][j]) ;
              }

              for( j = 0 ; j < NUMHID ; j++ )
              {     /* update weights WeightIH */
                  DeltaWeightIH[0][j] = eta * DeltaH[j] + alpha * DeltaWeightIH[0][j] ;
                  WeightIH[0][j] += DeltaWeightIH[0][j] ;

                  for( i = 0 ; i < NUMIN ; i++ )
                  {
                      DeltaWeightIH[i][j] = eta * Input[game][0][i] * DeltaH[j] + alpha * DeltaWeightIH[i][j];
                      WeightIH[i][j] += DeltaWeightIH[i][j] ;
                  }
              }

              for( k = 0 ; k < NUMOUT ; k ++ )
              {    /* update weights WeightHO */
                  DeltaWeightHO[0][k] = eta * DeltaO[k] + alpha * DeltaWeightHO[0][k] ;
                  WeightHO[0][k] += DeltaWeightHO[0][k] ;

                  for( j = 0 ; j < NUMHID ; j++ )
                  {
                      DeltaWeightHO[j][k] = eta * Hidden[p][j] * DeltaO[k] + alpha * DeltaWeightHO[j][k] ;
                      WeightHO[j][k] += DeltaWeightHO[j][k] ;
                  }
              }
            }
        }

        if( epoch%100 == 0 ) fprintf(stdout, "\nEpoch %-5d :   Error = %f", epoch, Error) ;

        if( Error < 0.0004 ) break ;  /* stop learning when 'near enough' */
    }

    int sum = 0;
    double weights[51];

    for (i = 0; i < NUMIN; i++)
    {
      for (j = 0; j < NUMHID; j++)
      {
        sum = WeightIH[i][j];
      }
      sum /= 51;
      weights[i] = sum;
    }

    for (i = 0; i < 51; i++)
    {
      printf("weight[%d] = %G\n", i, weights[i]);
    }
    return 1 ;
}

关于c - 段错误(核心转储)神经网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34757477/

相关文章:

c++ - 我可以将 Thread Sanitizer 用于 OpenMP 程序吗?

c - 具有有限缓冲区的生产者/消费者

tensorflow - 如何在神经网络中添加 "OTHER"类?

python - 如何计算序列的交叉熵损失

c - 如何在c中将一定长度的字符串放入二维数组中

c++ - ELI5如何安装像curl这样的外部库?

python - 来自 scikit-learn 的具有自己的距离函数的 k-NN 算法

python - 为什么这个 Keras Conv2D 层与输入不兼容?

python - LSTM 时间序列 - 奇怪的 val_accuracy,使用哪种归一化方法以及模型拟合后在生产中做什么

c++ - OpenCV 机器学习函数需要 CvFileStorage* 而不是 cv::FileStorage*