Opencv 4.1.0加载caffe crnn模型中错误纠正

mac2026-08-14  7

1. 概述

最近倒腾了一下Opencv加载caffemodel做inference的事情,使用的模型是使用的crnn文本识别模型(仓库地址:链接),使用的Opencv版本是4.1.0。其中也遇到一些Opencv源码里面的问题,所以这里需要下载Opencv的源码自己使用CMake+VS2015编译(主要是方便问题定义与对应部分的修改…)。

2. 问题描述

对于Opencv中模型加载与输入数据的代码很简单了,这里就不贴了。直接来看看问题吧。问题描述:

OpenCV(4.1.0) Error: Assertion failed (Wh.rows == 4*Wh.cols) in cv::dnn::LSTMLayerImpl::LSTMLayerImpl, file D:\InstallDir\opencv\4.1.0\src\opencv-4.1.0\modules\dnn\src\layers\recurrent_layers.cpp, line 114

在上面已经把问题说得比较清楚了是因为LSTM权值参数的维度不匹配造成的,这里在配置好自己编译的Opencv(Debug版本带pdb文件),F11跟进去看看就知道了。

那么为毛会参数维度有问题呢?首先来看看Caffe中LSTM的权值参数是怎么存储的吧。

deploy = './deploy.prototxt' caffe_model = './snapshot/_iter_100000.caffemodel' net = caffe.Net(deploy, caffe_model, caffe.TEST) lstm_param1 = net.params['lstm1'][0].data lstm_param2 = net.params['lstm1'][1].data lstm_param3 = net.params['lstm1'][2].data print("lstm param1 shape:{}\n lstm param2 shape:{}\n lstm param3 shape:{}".format(lstm_param1.shape, lstm_param2.shape, lstm_param3.shape))

那么打印出来的参数维度如下:

lstm param1 shape:(500, 512) //输入的参数,index:0 lstm param2 shape:(500,) //偏置的参数,index:1 lstm param3 shape:(500, 125) //隐变量的参数,index:2

看到这里就很明白了,就是参数对应不上导致的,那么对应的解决办法就很简单了。

//line:96 public: LSTMLayerImpl(const LayerParams& params) : numTimeStamps(0), numSamples(0) { setParamsFrom(params); //添加下面两行 std::swap(blobs[0], blobs[2]); std::swap(blobs[1], blobs[2]); ......

至此,改动完成。重新编译之后再链接这个新生成的库就好了。

3. 思考

在使用Opencv之前先后使用了caffe cpu、tinydnn+eigen、ncnn(源码,非lib)的inference(什么AVX2之类的代码优化已做)。他们的结果表现如下(下面比较结果作为参考,不同环境与模型结果会有出入):

1)caffe cpu:,其速度是这三者中最快的,但是其打包的是东西实在太多了(MKL可以加速矩阵运算);2)tinydnn:,其速度是三个里面相对来说比较慢的,初步分析是其内部的存储导致;3)ncnn:,其速度在3个里面排行第二个,不过这里没有使用valkan,不知道加上之后速度会提升多少;

这里使用Opencv运算的速度与caffe cpu相差无几,猜测其内部是使用OpenCL做加速,这里又是一个新坑了,值的细细研究了-_-||…

最新回复(0)