我有一个神经网络,我正在尝试在运行debian的远程VM中训练它。训练结束后,我将权重保存在txt文件中,然后将文件下载到我的PC(Ubuntu 14)。问题是我无法读取权重文件(它加载错误的值),即使我可以使用相同的代码在远程机器中读取它。这是我的代码:
阅读:
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);
}
答案 0 :(得分:1)
您的阅读功能应该是
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
适用于float
和double
,但fscanf
},%f
表示float
,因此您的数据以错误的格式读取,最重要的是以float
的形式存储到double
的指针中。使用%lf
会向fscanf
表明您要将其读入double
。
如果你将-Wformat
添加到你的编译行(或更好的-Wall -Werror
),它应该给你一个警告/错误沿着&#34; fscanf参数1期望float,给定double&# 34;你应该注意那个警告并相应地修改你的代码。
要确保输入正常,请使用:
void input_error()
{
fprintf(stderr, "Error reading input");
exit();
}
...
if (fscanf(f, "%lf ", &CNNLayers[i].FeatureMaps[j].bias) != 1)
{
input_error();
}
Edit2:您可能希望删除格式中的空格(换句话说,"%lf
&#34; instead of
&#34;%lf&#34; , as my experience with spaces in
fscanf formats is that they are "not doing what you want, most of the time", and
fscanf`将在实际输入之前根据需要跳过空格,因此您应该在没有空格的情况下获得至少同样好的结果。