无法读取在具有相同代码的不同计算机上写入的文件

Can't read file written in a different machine with the same code

本文关键字:计算机 文件 代码 读取      更新时间:2023-10-16

我有一个神经网络,我正试图在运行debian的远程VM中训练它。训练结束后,我把重量保存在一个txt文件中,然后把这个文件下载到我的电脑(Ubuntu 14)上。问题是我无法读取weights文件(它加载了错误的值),即使我可以在远程机器中使用相同的代码读取它。这是我的代码:

用于阅读:

void CNN::LoadWeights(char *fileName) {
    int i, j, k, m;
    FILE *f;
    if((f = fopen(fileName, "r")) == NULL) return;
    for ( i=1; i<CNNSize; i++ ) {
        for( j=0; j<CNNLayers[i].FMCount; j++ ) {
            fscanf(f, "%f ", &CNNLayers[i].FeatureMaps[j].bias);
            for(k=0; k<CNNLayers[i].prevLayer->FMCount; k++) {
                for(m=0; m < CNNLayers[i].KernelSize * CNNLayers[i].KernelSize; m++) {
                    fscanf(f, "%f ", &CNNLayers[i].FeatureMaps[j].kernel[k][m]);
                }
            }
        }
    }
    fclose(f);
}

用于书写:

void CNN::SaveWeights(char *fileName) {
    int i, j, k, m;
    FILE *f;
    if((f = fopen(fileName, "w")) == NULL) return;
    for ( i=1; i<CNNSize; i++ ) {
        for( j=0; j<CNNLayers[i].FMCount; j++ ) {
            fprintf(f, "%f ", CNNLayers[i].FeatureMaps[j].bias);
            for(k=0; k<CNNLayers[i].prevLayer->FMCount; k++) {
                for(m=0; m < CNNLayers[i].KernelSize * CNNLayers[i].KernelSize; m++) {
                    fprintf(f, "%f ", CNNLayers[i].FeatureMaps[j].kernel[k][m]);
                }
            }
        }
    }
    fclose(f);
}

您的读取函数应该是

        fscanf(f, "%lf ", &CNNLayers[i].FeatureMaps[j].bias);
        for(k=0; k<CNNLayers[i].prevLayer->FMCount; k++) {
            for(m=0; m < CNNLayers[i].KernelSize * CNNLayers[i].KernelSize; m++) {
                fscanf(f, "%lf ", &CNNLayers[i].FeatureMaps[j].kernel[k][m]);
            }
        }

请注意,格式是"%lf",而不是"%f"。在printf中,值会自动从float转换为double,因此%f适用于floatdouble,但在fscanf中,%f意味着float,因此您的数据以错误的格式读取,最重要的是,将数据作为float存储到double的指针中。使用%lf将向fscanf指示您要将其读取为double

如果您将-Wformat添加到编译行(或者更好的是-Wall -Werror),它应该会沿着"fscanf argument 1 expects float,give double"的行向您发出警告/错误,您应该注意这个警告并相应地修复代码。

为了确保您的输入正确工作,请使用:

 void input_error()
 {
     fprintf(stderr, "Error reading input"); 
     exit();
 }
...
  if (fscanf(f, "%lf ", &CNNLayers[i].FeatureMaps[j].bias) != 1)
  {
      input_error();
  }

第2版:您可能需要删除格式中的空格(换句话说,"%lf"instead of"%lf", as my experience with spaces in fscanf formats is that they are "not doing what you want, most of the time", and fscanf`将根据需要在实际输入之前跳过空格,因此您应该在没有空格的情况下至少获得同样好的结果。