kouxichao / crnn

Word recognition using ncnn
29 stars 10 forks source link

用python训练的rcnn模型转化为ncnn后param网络结构与示例不同 #2

Closed yotoamoy closed 5 years ago

yotoamoy commented 5 years ago

我们用同样的rcnn网络训练出来的模型,经过ncnn转换后,生成的param文件内容与示例差别很大,主要是后面的LSTM层被分解成很多层。直接使用自己转换的模型,用ncnn调用加载模型失败,提示很多类似can‘t find blob_name_by_index的错误。 文中提到的“param需要自己对照更改”是什么意思?请教一下大神

kouxichao commented 5 years ago

把.param文件的split后面的一大串删掉(lstm展开的),换上bilstm层,偶尔的手动更改也蛮简单的。应该也可以简单的改一下转换代码,直接转换完成的

yotoamoy commented 5 years ago

您好!我们的rcnn模型跟您的是一样的,模型包含中文和英文字符,字符总数6384。模型经过您提供的ncnn转换之后,将最后lstm展开层替换成跟您一样的,只改了输出层数量(由37改为6384)。使用时参照您给的英文以及中文模型使用方法结果均不对,而且不同图片输入的结果是一样的(用您自带的英文模型使用没有问题,可惜您没有提供中文模型)。很是困惑,想知道中文模型和英文模型使用上为何会有差别,我们的模型问题可能在哪里?以下是我们模型最后的修改: BiLSTM output0 1 1 Permute_0 output0 0=1 1=1 2=256 3=524288 4=262144 FullyConnected fullyconnected0 1 1 output0 fullyconnected0 0=256 1=1 2=131072 Permute Permute_1 1 1 fullyconnected0 Permute_1 0=2 BiLSTM output0 1 1 Permute_1 output1 0=1 1=1 2=256 3=262144 4=262144 FullyConnected fullyconnected0 1 1 output1 preds 0=6384 1=1 2=18944

kouxichao commented 5 years ago

中文模型稍后会上传(包含初始lstm展开的模型,也可以使用) 并不是中文英文使用上有差别,而是因为是从不同框架转过来的,中文是mxnet,英文是pytorch,这两个框架权重的存储顺序不一样,所以要区别对待。 你不能只更改输出值37到6384,fullyconnected 的权重数也要相应的更改,如果模型一样的话, 应该是 FullyConnected fullyconnected0 1 1 output1 preds 0=6384 1=1 2=512×6384

还有如果你的bilstm.cpp不是这几天下载的,请更新一下。

yotoamoy commented 5 years ago

感谢您的答复!最后一层参数前面已经改成您说的这样了。打印了最后几层的输出值,已发现不同输入图片,输出的值差距很小(有不同,就是小数点后五位左右不一样),到最后一层的输出索引值不同图片就一样了,不知网络中间还有哪里需要修改的参数。全部网络如下: 7767517 31 100 Input data 0 1 data 0=1 1=32 2=100 Convolution ConvNd_1 1 1 data ConvNd_1 0=64 1=3 2=1 3=1 4=1 5=1 6=576 ReLU Threshold_1 1 1 ConvNd_1 Threshold_1 0=0.000000 Pooling MaxPool2d_1 1 1 Threshold_1 MaxPool2d_1 0=0 1=2 2=2 3=0 4=0 Convolution ConvNd_2 1 1 MaxPool2d_1 ConvNd_2 0=128 1=3 2=1 3=1 4=1 5=1 6=73728 ReLU Threshold_2 1 1 ConvNd_2 Threshold_2 0=0.000000 Pooling MaxPool2d_2 1 1 Threshold_2 MaxPool2d_2 0=0 1=2 2=2 3=0 4=0 Convolution ConvNd_3 1 1 MaxPool2d_2 ConvNd_3 0=256 1=3 2=1 3=1 4=1 5=1 6=294912 BatchNorm BatchNorm_1 1 1 ConvNd_3 BatchNorm_1 0=256 Scale BatchNorm_1_scale 1 1 BatchNorm_1 BatchNorm_1_scale 0=256 1=1 ReLU Threshold_3 1 1 BatchNorm_1_scale Threshold_3 0=0.000000 Convolution ConvNd_4 1 1 Threshold_3 ConvNd_4 0=256 1=3 2=1 3=1 4=1 5=1 6=589824 ReLU Threshold_4 1 1 ConvNd_4 Threshold_4 0=0.000000 Pooling MaxPool2d_3 1 1 Threshold_4 MaxPool2d_3 0=0 1=2 2=1 3=1 4=0 12=2 13=0 Convolution ConvNd_5 1 1 MaxPool2d_3 ConvNd_5 0=512 1=3 2=1 3=1 4=1 5=1 6=1179648 BatchNorm BatchNorm_2 1 1 ConvNd_5 BatchNorm_2 0=512 Scale BatchNorm_2_scale 1 1 BatchNorm_2 BatchNorm_2_scale 0=512 1=1 ReLU Threshold_5 1 1 BatchNorm_2_scale Threshold_5 0=0.000000 Convolution ConvNd_6 1 1 Threshold_5 ConvNd_6 0=512 1=3 2=1 3=1 4=1 5=1 6=2359296 ReLU Threshold_6 1 1 ConvNd_6 Threshold_6 0=0.000000 Pooling MaxPool2d_4 1 1 Threshold_6 MaxPool2d_4 0=0 1=2 2=1 3=1 4=0 12=2 13=0 Convolution ConvNd_7 1 1 MaxPool2d_4 ConvNd_7 0=512 1=2 2=1 3=1 4=0 5=1 6=1048576 BatchNorm BatchNorm_3 1 1 ConvNd_7 BatchNorm_3 0=512 Scale BatchNorm_3_scale 1 1 BatchNorm_3 BatchNorm_3_scale 0=512 1=1 ReLU Threshold_7 1 1 BatchNorm_3_scale Threshold_7 0=0.000000 Permute Permute_1 1 1 Threshold_7 Permute_0 0=5 BiLSTM output0 1 1 Permute_0 output0 0=1 1=1 2=256 3=524288 4=262144 FullyConnected fullyconnected0 1 1 output0 fullyconnected0 0=256 1=1 2=131072 Permute Permute_1 1 1 fullyconnected0 Permute_1 0=2 BiLSTM output0 1 1 Permute_1 output1 0=1 1=1 2=256 3=262144 4=262144 FullyConnected fullyconnected0 1 1 output1 preds 0=6384 1=1 2=3268608

kouxichao commented 5 years ago

这样看不太出来,你最好拿原来模型的输出,和这个做个对比,具体你的模型怎么样我也不太清楚,所以没法给你很好的建议,如果你训练的时候输入的图片也是100×32,只是输出改了的话,应该没有啥问题的。

yotoamoy commented 5 years ago

谢谢您!请教一下,我们的模型是用python36训练的,转换的时候用您这个环境,是python27的,不知道跟这个python版本有关系,现在定位是转出来的模型有问题,有些层输出维度跟原始的会不一样,当然输出值也不一样。 还有,中文模型路径在哪里?谢谢

kouxichao commented 5 years ago

中文查看https://github.com/kouxichao/ncnn的README.md模型下载 转换模型有问题的话,如果是bin模型有问题可以简单改一下转换文件的innerproduct层根据lstm的sequence长度把重复的权重滤掉(也可以写一个lstm的转换层)。如果是param可以参照原来的输出改一下。

yotoamoy commented 5 years ago

您好!非常感谢,中文模型已下载。实在抱歉!中文模型用cnn_chinese工程使用输出的值为空,如下: const char* imagepath = "1.jpg";

cv::Mat m = cv::imread(imagepath, 0);
// cv::cvtColor(m,m,cv::COLOR_RGB2GRAY);
if (m.empty())
{
    fprintf(stderr, "cv::imread %s failed\n", imagepath);
    return -1;
}

ncnn::Mat prob_chinese, prob_english;
recognition_chinese(m, prob_chinese);
recognition_chinese_lstm(m, prob_english);

prob_chinese, prob_english输出均为空。

kouxichao commented 5 years ago

你给的信息太少,应该不会的,这个都是跑过的,你是用https://github.com/kouxichao/ncnn完整编译的吗?bilstm文件是以前下载的吧,因为ncnn更新了接口,所以会输出空,你更新一下对应的层文件就好

yotoamoy commented 5 years ago

经过一番努力,自己的模型ncnn加载起来了,感谢大神的付出。 cpu版本是可以正常使用了,但是gpu版本取最后一层的值出现崩溃,确切来说是取Permute_1发生崩溃。不知是否遇到过?

kouxichao commented 5 years ago

gpu? ncnn有gpu代码? 这个我没遇到过,应该是维度操作的问题,可以debug选项编译一下,看哪里出错了

yotoamoy commented 5 years ago

有的,用cmake编译gpu,ncnn有gpu的开关。