[英]C pointer to array not assigning value
我正在研究一个神经网络,所以我有非常大的数据结构。 因此,我使用指向堆中数组的指针。 我有一个总是赋值为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 等于 0。 我错过了什么?
更新
每个请求:
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 ;
}
/*******************************************************************************/
temp1
和temp2
是int
s.....
根据经验,将变量声明为它们使用的最内层范围。
这个问题让我有点困惑,因为我看不出什么是真正的错误。 我有两个想法要检查:
我认为temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
是正确的,但是 - 只是为了笑 - 尝试添加另一组括号: temp1 = (*(Input + game + 0 + i)) * (*(WeightIH + i + j)) ;
可能是在该行之前的某个地方出现内存损坏(尽管我看不到在哪里)。 MM 是对的,尽管您的所有索引可能都是错误的。 考虑如何构建二维数组,以及您尝试访问的元素 - 例如*(WeightIH + i + j)
未访问 'line' i, row 'j' - 您需要将行索引与col 长度(或者*(WeightIH + i*NumHidden + j)
,只要你喜欢,只要一致): *(WeightIH + i*NumHidden + j)
。 考虑到 i = 1 的行不是从索引 1+0 开始,而是在 j 的所有 NumHidden 元素都完成之后,所以它从索引 NumHidden+0 开始,等等。解决这个问题,如果问题消失,请尝试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.