我正在研究神经网络,所以我有非常大的数据结构。因此,我正在使用指向堆中数组的指针。我有一个总是分配0
没有任何东西超出范围,一切都是double
代码段如下:
for( j = 0 ; j < NumHidden ; j++ ) { /* compute hidden unit activations */
*(SumH + p + j) = *(WeightIH + 0) ;
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))) ;
}
在gdb中我可以证明这些值是非零的:
117 temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
(gdb) p *Input
$1 = 0.75454545500000003
(gdb) p *WeightIH
$2 = 0.5
(gdb) n
118 temp2 = *(Input + game + 1 + i) * *(WeightIH + i + j) ;
(gdb) p temp1
$3 = 0
...但正如您所看到的,temp1在赋值后等于零。我错过了什么?
更新
按要求:
Breakpoint 1, main () at nn.c:117
117 temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
(gdb) p *(WeightIH + i + j)
$1 = 0.5
(gdb) p *(Input + game + 0 + i)
$2 = 0.75454545500000003
以下是整个代码:
一些伪代码:
将所有输入读入3d数组
定义所有结构(都是正确的,没有超出界限)
循环模式数
循环游戏数量(这是运动模型)
计算激活值
计算输出值
计算错误
回传播
更新权重
/*******************************************************************************
* 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 <string.h>
#include <time.h>
#include <math.h>
#include <fcntl.h>
#define NUMPAT 101
#define NUMIN 24
#define NUMHID 100
#define NUMOUT 55
#define rando() ((double)rand()/(RAND_MAX+1))
int main() {
int i, j, k, p, np, op, ranpat[NUMPAT], epoch, game;
int NumPattern = NUMPAT, NumInput = NUMIN, NumHidden = NUMHID, NumOutput = NUMOUT;
double temp1, temp2;
double *Input = (double *)malloc(NumOutput*2*NumInput*sizeof(double));
char line[128];
double num;
FILE *csvFile = fopen("inputs.csv", "r");
int oned_count = 0;
int twod_count = 0;
int threed_count = 0;
int count = 0;
if (csvFile){
char *token;
while (fgets(line, 1024, csvFile)){
token = strtok(&line[0], ",");
while(token){
num = atof(token);
*(Input + oned_count + twod_count + threed_count) = num;
token = strtok(NULL, ",");
threed_count++;
}
count++;
if ((count % 2) == 0){
oned_count++;
}
twod_count++;
if (twod_count == 2){
twod_count = 0;
}
}
fclose(csvFile);
}
double Target[55] = {-5 ,25, -3, 2 ,5 ,17, 10, 10 ,3 ,-8, 11 ,-2, -5, 17 ,4 ,4 ,2 ,12, 5 ,-11 ,-4, -9 ,13, -1, 5 ,7 ,5 ,4, 8 ,12 ,-13 ,-2, 3 ,34, -19 ,6, 7 ,-9 ,14, 4 ,3 ,-17 ,3, 6 ,-5, -2, -1, -7, 11, -1, 15, -7 ,7 ,19, 1};
double *SumH =(double *)malloc(NumPattern*NumHidden*sizeof(double));
double *WeightIH =(double *)malloc(NumInput*NumHidden*sizeof(double));
double *Hidden =(double *)malloc(NumPattern*NumHidden*sizeof(double));
double *SumO =(double *)malloc(NumPattern*NumOutput*sizeof(double));
double *WeightHO =(double *)malloc(NumHidden*NumOutput*sizeof(double));
double *Output =(double *)malloc(NumPattern*NumOutput*sizeof(double));
double *DeltaWeightIH =(double *)malloc(NumInput*NumHidden*sizeof(double));
double *DeltaWeightHO = (double *)malloc(NumHidden*NumOutput*sizeof(double));
double DeltaO[NumOutput];
double SumDOW[NumHidden];
double DeltaH[NumHidden];
double Error, eta = 0.10, alpha = 0.9;
//double temps[24] = {-0.901337 -0.872058 -0.765912 -0.904485 -1.01524 ,-1.00116, -1.02088, -0.849757, -0.777824, -0.967258 ,-1.02125, -0.773202, -0.622447 ,-0.576088 ,-0.76714, -0.741354 ,-0.669561, -0.606497 ,-0.670834 ,-0.85477, -0.980444, -1.00685, -0.0365572, -0.000114586};
for( j = 0 ; j < NumHidden ; j++ ) { /* initialize WeightIH and DeltaWeightIH */
for( i = 0 ; i < NumInput ; i++ ) {
*(DeltaWeightIH + i + j) = 0;
// *(WeightIH + i) = test_weights[i] ;
*(WeightIH + i + j) = .5 ;
}
}
for( k = 0 ; k < NumOutput ; k ++ ) { /* initialize WeightHO and DeltaWeightHO */
for( j = 0 ; j < NumHidden ; j++ ) {
*(DeltaWeightHO + j + k) = 0.0 ;
*(WeightHO + j + k) = 1;
}
}
for( epoch = 0 ; epoch < 500000 ; epoch++) { /* iterate weight updates */
for( p = 0 ; p < NumPattern ; p++ ) { /* randomize order of individuals */
ranpat[p] = p ;
}
for( p = 0 ; p < NumPattern ; p++) {
np = rand() % NUMPAT ;
op = ranpat[p] ;
ranpat[p] = ranpat[np] ;
ranpat[np] = op ;
}
Error = 0.0 ;
for( np = 0 ; np < NumPattern ; np++ ) { /* repeat for all the training patterns */
p = ranpat[np];
for (game = 0; game < 55; game++){
for( j = 0 ; j < NumHidden ; j++ ) { /* compute hidden unit activations */
*(SumH + p + j) = *(WeightIH + 0) ;
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) = (exp(*(Output + p + k)) - exp(-*(Output + p + k))) / (exp(*(Output + p + k)) + exp(-*(Output + p + k))); //TANH
//*(Output + p + k) = (2.0/(1.0 + exp(-*(SumO + p + k)))) - 1 ; //bipolar sigmoid
//*(Output + p + k) = .5 * (1 + 1.0/(1.0 + exp(-*(SumO + p + k)))) * (1 - 1.0/(1.0 + exp(-*(SumO + p + k)))); //derivative sigmoid
//*(Output + p + k) = .5 * (1 + ((2.0/(1.0 + exp(-*(SumO + p + k)))) - 1)) * (1 - ((2.0/(1.0 + exp(-*(SumO + p + k)))) - 1)); //derivative bioolar sigmoid
/* Output[p][k] = SumO[p][k]; L
ear Outputs */
Error += 0.50 * (Target[game] - *(Output + p + k)) * (Target[game] - *(Output + p + k)) ; /* SSE */
//Error -= ( Target[game] * log( *(Output + p + k) ) + ( 1.0 - Target[k] ) * log( 1.0 - *(Output + p + k) ) ) ;
DeltaO[k] = (Target[game] - *(Output + p + k)) * *(Output + p + k) * (1.0 - *(Output + p + k)) ; /* Sigmoidal Outputs, SSE */
//DeltaO[k] = (exp(Target[game]) - exp(-*(Output + p + k))) / (exp(Target[game]) + exp(-*(Output + p + k)))
//DeltaO[k] = Target[k] - *(Output + p+k);
//DeltaO[k] = Target[game] - *(Output +p + k);
}
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%10 == 0 ){
fprintf(stdout, "\nEpoch %-10d : Error = %f\n", epoch, Error) ;
// fprintf(stdout, "\nEpoch %-10d : weight1 example = %f", epoch, *(WeightIH)) ;
printf("Input weights:\n");
printf("-------------------\n");
for (i = 0; i < 24; i++){
printf("%G\n", *(WeightIH + i + 100));
}
printf("Hidden weights:\n");
printf("-------------------\n");
for (i = 0; i < NumHidden; i++){
printf("%G\n", *(WeightHO + i + 55));
}
//}
if( Error < 0.0004 ) break ; /* stop learning when 'near enough' */
}
return 1 ;
}
/*******************************************************************************/
答案 0 :(得分:1)
temp1
和temp2
是int
s .....
根据经验,将变量声明为它们所使用的最内层范围。
答案 1 :(得分:0)
这个问题让我感到困惑,因为我看不出什么是错的。我有两个想法要检查:
我认为行temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
是正确的,但是 - 只是为了笑 - 尝试添加另一组括号:
temp1 =(*(输入+游戏+ 0 + i))*(*(WeightIH + i + j));
你可能会在那之前的某个地方弄到内存损坏(虽然我不知道在哪里)。 M.M是正确的,因为你所有的索引可能都是错误的。考虑如何构建二维数组,以及您尝试访问哪个元素 - 例如*(WeightIH + i + j)
不访问&#39; line&#39;我,排&#39; j&#39; - 你需要将行索引与col长度相乘(或者相反,但是你喜欢,只是一致):*(WeightIH + i*NumHidden + j)
。考虑到i = 1的行不是从索引1 + 0开始,但是在j的所有NumHidden元素完成之后,所以它从索引NumHidden + 0开始,等等。修复此问题,并尝试问题是否消失。 / p>