I have a 3-layed neural network, and I'm getting a seg fault. I know that means I'm writing to the wrong memory space. In this scenario I would guess it is because I am running out of space.
The thing is I have calloc
ed all of my large store items, so I thought that would resolve this issue.
gdb is freezing at the line
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] ;
the code looks like:
/*******************************************************************************
* 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] = #
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 ;
}
/*******************************************************************************/
I'm compiling with: gcc nn.c -O -lm -o nn -mmacosx-version-min=10.11
and it compiles fine.
Any idea what's going on here?