parent
761b037126
commit
6fd67d44b0
12 changed files with 420 additions and 62 deletions
@ -0,0 +1,33 @@ |
|||||||
|
#ifndef __OPENCV_DNN_TEST_NPY_BLOB_HPP__ |
||||||
|
#define __OPENCV_DNN_TEST_NPY_BLOB_HPP__ |
||||||
|
#include "test_precomp.hpp" |
||||||
|
|
||||||
|
#ifdef __GNUC__ |
||||||
|
# pragma GCC diagnostic ignored "-Wunused-parameter" |
||||||
|
# pragma GCC diagnostic push |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "cnpy.h" |
||||||
|
|
||||||
|
#ifdef __GNUC__ |
||||||
|
# pragma GCC diagnostic pop |
||||||
|
#endif |
||||||
|
|
||||||
|
inline cv::dnn::Blob blobFromNPY(const cv::String &path) |
||||||
|
{ |
||||||
|
cnpy::NpyArray npyBlob = cnpy::npy_load(path.c_str()); |
||||||
|
|
||||||
|
cv::dnn::Blob blob; |
||||||
|
blob.fill((int)npyBlob.shape.size(), (int*)&npyBlob.shape[0], CV_32F, npyBlob.data); |
||||||
|
|
||||||
|
npyBlob.destruct(); |
||||||
|
return blob; |
||||||
|
} |
||||||
|
|
||||||
|
inline void saveBlobToNPY(cv::dnn::Blob &blob, const cv::String &path) |
||||||
|
{ |
||||||
|
cv::Vec4i shape = blob.shape(); |
||||||
|
cnpy::npy_save(path.c_str(), blob.ptr<float>(), (unsigned*)&shape[0], 4); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,75 @@ |
|||||||
|
#include "test_precomp.hpp" |
||||||
|
#include "npy_blob.hpp" |
||||||
|
|
||||||
|
namespace cvtest |
||||||
|
{ |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
using namespace testing; |
||||||
|
using namespace cv; |
||||||
|
using namespace cv::dnn; |
||||||
|
|
||||||
|
static std::string getOpenCVExtraDir() |
||||||
|
{ |
||||||
|
return cvtest::TS::ptr()->get_data_path(); |
||||||
|
} |
||||||
|
|
||||||
|
template<typename TStr> |
||||||
|
static std::string getTestFile(TStr filename) |
||||||
|
{ |
||||||
|
return (getOpenCVExtraDir() + "/dnn/") + filename; |
||||||
|
} |
||||||
|
|
||||||
|
inline void normAssert(InputArray ref, InputArray get, const char *comment = "") |
||||||
|
{ |
||||||
|
double normL1 = cvtest::norm(ref, get, NORM_L1)/ ref.getMat().total(); |
||||||
|
EXPECT_LE(normL1, 0.0001) << comment; |
||||||
|
|
||||||
|
double normInf = cvtest::norm(ref, get, NORM_INF); |
||||||
|
EXPECT_LE(normInf, 0.001) << comment; |
||||||
|
} |
||||||
|
|
||||||
|
inline void normAssert(Blob ref, Blob test, const char *comment = "") |
||||||
|
{ |
||||||
|
normAssert(ref.getMatRef(), test.getMatRef(), comment); |
||||||
|
} |
||||||
|
|
||||||
|
TEST(Reproducibility_AlexNet, Accuracy) |
||||||
|
{ |
||||||
|
Net net; |
||||||
|
{ |
||||||
|
Ptr<Importer> importer = createCaffeImporter(getTestFile("bvlc_alexnet.prototxt"), getTestFile("bvlc_alexnet.caffemodel")); |
||||||
|
ASSERT_TRUE(importer != NULL); |
||||||
|
importer->populateNet(net); |
||||||
|
} |
||||||
|
|
||||||
|
std::vector<Mat> inpMats(2); |
||||||
|
inpMats[0] = imread(getTestFile("alexnet_0.png")); |
||||||
|
inpMats[1] = imread(getTestFile("alexnet_1.png")); |
||||||
|
ASSERT_TRUE(!inpMats[0].empty() && !inpMats[1].empty()); |
||||||
|
|
||||||
|
inpMats[0].convertTo(inpMats[0], CV_32F); |
||||||
|
Blob inp(inpMats[0]); |
||||||
|
|
||||||
|
net.setBlob("data", inp); |
||||||
|
|
||||||
|
net.forward("conv1"); |
||||||
|
normAssert(blobFromNPY(getTestFile("alexnet_conv1.npy")), net.getBlob("conv1"), "conv1"); |
||||||
|
//saveBlobToNPY(convBlob, getTestFile("alexnet_conv1_my.npy"));
|
||||||
|
|
||||||
|
net.forward("relu1"); |
||||||
|
normAssert(blobFromNPY(getTestFile("alexnet_relu1.npy")), net.getBlob("relu1"), "relu1"); |
||||||
|
|
||||||
|
net.forward("norm1"); |
||||||
|
normAssert(blobFromNPY(getTestFile("alexnet_norm1.npy")), net.getBlob("norm1"), "norm1"); |
||||||
|
|
||||||
|
net.forward(); |
||||||
|
Blob out = net.getBlob("prob"); |
||||||
|
Blob ref = blobFromNPY(getTestFile("alexnet.npy")); |
||||||
|
std::cout << out.shape() << " vs " << ref.shape() << std::endl; |
||||||
|
Mat mOut(1, 1000, CV_32F, ref.rawPtr()); |
||||||
|
Mat mRef(1, 1000, CV_32F, ref.rawPtr()); |
||||||
|
normAssert(mOut, mRef); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,276 @@ |
|||||||
|
name: "AlexNet" |
||||||
|
input: "data" |
||||||
|
input_dim: 10 |
||||||
|
input_dim: 3 |
||||||
|
input_dim: 227 |
||||||
|
input_dim: 227 |
||||||
|
layer { |
||||||
|
name: "conv1" |
||||||
|
type: "Convolution" |
||||||
|
bottom: "data" |
||||||
|
top: "conv1" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
convolution_param { |
||||||
|
num_output: 96 |
||||||
|
kernel_size: 11 |
||||||
|
stride: 4 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "relu1" |
||||||
|
type: "ReLU" |
||||||
|
bottom: "conv1" |
||||||
|
top: "relu1" |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "norm1" |
||||||
|
type: "LRN" |
||||||
|
bottom: "relu1" |
||||||
|
top: "norm1" |
||||||
|
lrn_param { |
||||||
|
local_size: 5 |
||||||
|
alpha: 0.0001 |
||||||
|
beta: 0.75 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "pool1" |
||||||
|
type: "Pooling" |
||||||
|
bottom: "norm1" |
||||||
|
top: "pool1" |
||||||
|
pooling_param { |
||||||
|
pool: MAX |
||||||
|
kernel_size: 3 |
||||||
|
stride: 2 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "conv2" |
||||||
|
type: "Convolution" |
||||||
|
bottom: "pool1" |
||||||
|
top: "conv2" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
convolution_param { |
||||||
|
num_output: 256 |
||||||
|
pad: 2 |
||||||
|
kernel_size: 5 |
||||||
|
group: 2 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "relu2" |
||||||
|
type: "ReLU" |
||||||
|
bottom: "conv2" |
||||||
|
top: "conv2" |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "norm2" |
||||||
|
type: "LRN" |
||||||
|
bottom: "conv2" |
||||||
|
top: "norm2" |
||||||
|
lrn_param { |
||||||
|
local_size: 5 |
||||||
|
alpha: 0.0001 |
||||||
|
beta: 0.75 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "pool2" |
||||||
|
type: "Pooling" |
||||||
|
bottom: "norm2" |
||||||
|
top: "pool2" |
||||||
|
pooling_param { |
||||||
|
pool: MAX |
||||||
|
kernel_size: 3 |
||||||
|
stride: 2 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "conv3" |
||||||
|
type: "Convolution" |
||||||
|
bottom: "pool2" |
||||||
|
top: "conv3" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
convolution_param { |
||||||
|
num_output: 384 |
||||||
|
pad: 1 |
||||||
|
kernel_size: 3 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "relu3" |
||||||
|
type: "ReLU" |
||||||
|
bottom: "conv3" |
||||||
|
top: "conv3" |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "conv4" |
||||||
|
type: "Convolution" |
||||||
|
bottom: "conv3" |
||||||
|
top: "conv4" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
convolution_param { |
||||||
|
num_output: 384 |
||||||
|
pad: 1 |
||||||
|
kernel_size: 3 |
||||||
|
group: 2 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "relu4" |
||||||
|
type: "ReLU" |
||||||
|
bottom: "conv4" |
||||||
|
top: "conv4" |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "conv5" |
||||||
|
type: "Convolution" |
||||||
|
bottom: "conv4" |
||||||
|
top: "conv5" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
convolution_param { |
||||||
|
num_output: 256 |
||||||
|
pad: 1 |
||||||
|
kernel_size: 3 |
||||||
|
group: 2 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "relu5" |
||||||
|
type: "ReLU" |
||||||
|
bottom: "conv5" |
||||||
|
top: "conv5" |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "pool5" |
||||||
|
type: "Pooling" |
||||||
|
bottom: "conv5" |
||||||
|
top: "pool5" |
||||||
|
pooling_param { |
||||||
|
pool: MAX |
||||||
|
kernel_size: 3 |
||||||
|
stride: 2 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "fc6" |
||||||
|
type: "InnerProduct" |
||||||
|
bottom: "pool5" |
||||||
|
top: "fc6_0" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
inner_product_param { |
||||||
|
num_output: 4096 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "relu6" |
||||||
|
type: "ReLU" |
||||||
|
bottom: "fc6_0" |
||||||
|
top: "fc6_1" |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "drop6" |
||||||
|
type: "Dropout" |
||||||
|
bottom: "fc6_1" |
||||||
|
top: "fc6_2" |
||||||
|
dropout_param { |
||||||
|
dropout_ratio: 0.5 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "fc7" |
||||||
|
type: "InnerProduct" |
||||||
|
bottom: "fc6_2" |
||||||
|
top: "fc7_0" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
inner_product_param { |
||||||
|
num_output: 4096 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "relu7" |
||||||
|
type: "ReLU" |
||||||
|
bottom: "fc7_0" |
||||||
|
top: "fc7_1" |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "drop7" |
||||||
|
type: "Dropout" |
||||||
|
bottom: "fc7_1" |
||||||
|
top: "fc7_2" |
||||||
|
dropout_param { |
||||||
|
dropout_ratio: 0.5 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "fc8" |
||||||
|
type: "InnerProduct" |
||||||
|
bottom: "fc7_2" |
||||||
|
top: "fc8" |
||||||
|
param { |
||||||
|
lr_mult: 1 |
||||||
|
decay_mult: 1 |
||||||
|
} |
||||||
|
param { |
||||||
|
lr_mult: 2 |
||||||
|
decay_mult: 0 |
||||||
|
} |
||||||
|
inner_product_param { |
||||||
|
num_output: 1000 |
||||||
|
} |
||||||
|
} |
||||||
|
layer { |
||||||
|
name: "prob" |
||||||
|
type: "Softmax" |
||||||
|
bottom: "fc8" |
||||||
|
top: "prob" |
||||||
|
} |
Loading…
Reference in new issue