From 285c77d6dd22fba207ec9c5fb5a43b3551e1e62a Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Mon, 15 Jun 2020 17:15:37 +0200 Subject: [PATCH 1/5] Imptove relative paths Signed-off-by: Micaela Verucchi Francesco Gatti --- CMakeLists.txt | 1 + tests/darknet/csresnext50-panet-spp.cpp | 4 ++-- tests/darknet/csresnext50-panet-spp_berkeley.cpp | 4 ++-- tests/darknet/yolo2.cpp | 4 ++-- tests/darknet/yolo2_voc.cpp | 4 ++-- tests/darknet/yolo2tiny.cpp | 4 ++-- tests/darknet/yolo3.cpp | 4 ++-- tests/darknet/yolo3_512.cpp | 4 ++-- tests/darknet/yolo3_berkeley.cpp | 4 ++-- tests/darknet/yolo3_coco4.cpp | 4 ++-- tests/darknet/yolo3_flir.cpp | 4 ++-- tests/darknet/yolo3tiny.cpp | 4 ++-- tests/darknet/yolo3tiny_512.cpp | 4 ++-- tests/darknet/yolo4.cpp | 4 ++-- tests/darknet/yolo4_berkeley.cpp | 4 ++-- 15 files changed, 29 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a64372..8c8619d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ if(DEBUG) add_definitions(-DDEBUG) endif() +add_definitions(-DTKDNN_PATH="${CMAKE_CURRENT_SOURCE_DIR}") #------------------------------------------------------------------------------- # CUDA diff --git a/tests/darknet/csresnext50-panet-spp.cpp b/tests/darknet/csresnext50-panet-spp.cpp index 1da95b2..a366e14 100644 --- a/tests/darknet/csresnext50-panet-spp.cpp +++ b/tests/darknet/csresnext50-panet-spp.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer137_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/csresnext50-panet-spp.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/csresnext50-panet-spp.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/Kcs4xBozwY4wFx8/download"); // parse darknet network diff --git a/tests/darknet/csresnext50-panet-spp_berkeley.cpp b/tests/darknet/csresnext50-panet-spp_berkeley.cpp index 47bbfd4..3cd0d52 100644 --- a/tests/darknet/csresnext50-panet-spp_berkeley.cpp +++ b/tests/darknet/csresnext50-panet-spp_berkeley.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer137_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/csresnext50-panet-spp_berkeley.cfg"; - std::string name_path = "../tests/darknet/names/berkeley.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/csresnext50-panet-spp_berkeley.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/berkeley.names"; // FIXME: wrong weights // downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s//download"); diff --git a/tests/darknet/yolo2.cpp b/tests/darknet/yolo2.cpp index 7a46c31..978c137 100644 --- a/tests/darknet/yolo2.cpp +++ b/tests/darknet/yolo2.cpp @@ -13,8 +13,8 @@ int main() { bin_path + "/layers/output.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo2.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo2.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/nf4PJ3k8bxBETwL/download"); // parse darknet network diff --git a/tests/darknet/yolo2_voc.cpp b/tests/darknet/yolo2_voc.cpp index eab215b..94111e6 100644 --- a/tests/darknet/yolo2_voc.cpp +++ b/tests/darknet/yolo2_voc.cpp @@ -13,8 +13,8 @@ int main() { bin_path + "/layers/output.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo2_voc.cfg"; - std::string name_path = "../tests/darknet/names/voc.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo2_voc.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/voc.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/DJC5Fi2pEjfNDP9/download"); // parse darknet network diff --git a/tests/darknet/yolo2tiny.cpp b/tests/darknet/yolo2tiny.cpp index 64faa36..cc12109 100644 --- a/tests/darknet/yolo2tiny.cpp +++ b/tests/darknet/yolo2tiny.cpp @@ -13,8 +13,8 @@ int main() { bin_path + "/layers/output.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo2tiny.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo2tiny.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; // FIXME: wrong weights //downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s//download"); diff --git a/tests/darknet/yolo3.cpp b/tests/darknet/yolo3.cpp index e73d226..d9a684b 100644 --- a/tests/darknet/yolo3.cpp +++ b/tests/darknet/yolo3.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer106_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo3.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/jPXmHyptpLoNdNR/download"); // parse darknet network diff --git a/tests/darknet/yolo3_512.cpp b/tests/darknet/yolo3_512.cpp index a67c3a7..6a5c20e 100644 --- a/tests/darknet/yolo3_512.cpp +++ b/tests/darknet/yolo3_512.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer106_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo3_512.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3_512.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/RGecMeGLD4cXEWL/download"); // parse darknet network diff --git a/tests/darknet/yolo3_berkeley.cpp b/tests/darknet/yolo3_berkeley.cpp index a71fe83..016a8a2 100644 --- a/tests/darknet/yolo3_berkeley.cpp +++ b/tests/darknet/yolo3_berkeley.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer106_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo3_berkeley.cfg"; - std::string name_path = "../tests/darknet/names/berkeley.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3_berkeley.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/berkeley.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/o5cHa4AjTKS64oD/download"); // parse darknet network diff --git a/tests/darknet/yolo3_coco4.cpp b/tests/darknet/yolo3_coco4.cpp index a651430..eaf9bd8 100644 --- a/tests/darknet/yolo3_coco4.cpp +++ b/tests/darknet/yolo3_coco4.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer106_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo3_coco4.cfg"; - std::string name_path = "../tests/darknet/names/coco4.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3_coco4.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco4.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/o27NDzSAartbyc4/download"); // parse darknet network diff --git a/tests/darknet/yolo3_flir.cpp b/tests/darknet/yolo3_flir.cpp index 678f10f..24aac7f 100644 --- a/tests/darknet/yolo3_flir.cpp +++ b/tests/darknet/yolo3_flir.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer106_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo3_flir.cfg"; - std::string name_path = "../tests/darknet/names/flir.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3_flir.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/flir.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/62DECncmF6bMMiH/download"); // parse darknet network diff --git a/tests/darknet/yolo3tiny.cpp b/tests/darknet/yolo3tiny.cpp index 01fc6f9..c33f7a8 100644 --- a/tests/darknet/yolo3tiny.cpp +++ b/tests/darknet/yolo3tiny.cpp @@ -14,8 +14,8 @@ int main() { bin_path + "/debug/layer23_out.bin", }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo3tiny.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3tiny.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/LMcSHtWaLeps8yN/download"); // parse darknet network diff --git a/tests/darknet/yolo3tiny_512.cpp b/tests/darknet/yolo3tiny_512.cpp index 8153b0d..ce4ce86 100644 --- a/tests/darknet/yolo3tiny_512.cpp +++ b/tests/darknet/yolo3tiny_512.cpp @@ -14,8 +14,8 @@ int main() { bin_path + "/debug/layer23_out.bin", }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo3tiny_512.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3tiny_512.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/8Zt6bHwHADqP4JC/download"); // parse darknet network diff --git a/tests/darknet/yolo4.cpp b/tests/darknet/yolo4.cpp index 80b12ce..65ac6ee 100644 --- a/tests/darknet/yolo4.cpp +++ b/tests/darknet/yolo4.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer161_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo4.cfg"; - std::string name_path = "../tests/darknet/names/coco.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo4.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/d97CFzYqCPCp5Hg/download"); // parse darknet network diff --git a/tests/darknet/yolo4_berkeley.cpp b/tests/darknet/yolo4_berkeley.cpp index 8642eb1..89e9f04 100644 --- a/tests/darknet/yolo4_berkeley.cpp +++ b/tests/darknet/yolo4_berkeley.cpp @@ -15,8 +15,8 @@ int main() { bin_path + "/debug/layer161_out.bin" }; std::string wgs_path = bin_path + "/layers"; - std::string cfg_path = "../tests/darknet/cfg/yolo4_berkeley.cfg"; - std::string name_path = "../tests/darknet/names/berkeley.names"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo4_berkeley.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/berkeley.names"; downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/nkWFa5fgb4NTdnB/download"); // parse darknet network From 3d3a2427c9d17e6bc7ac83b56486568b1adba180 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Tue, 16 Jun 2020 12:36:45 +0200 Subject: [PATCH 2/5] viz yolo3 --- include/tkDNN/DarknetParser.h | 2 +- include/tkDNN/NetworkViz.h | 12 ++++++ include/tkDNN/utils.h | 4 ++ src/NetworkViz.cpp | 69 +++++++++++++++++++++++++++++++++++ tests/darknet/viz_yolo3.cpp | 54 +++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 include/tkDNN/NetworkViz.h create mode 100644 src/NetworkViz.cpp create mode 100644 tests/darknet/viz_yolo3.cpp diff --git a/include/tkDNN/DarknetParser.h b/include/tkDNN/DarknetParser.h index cbeed48..cd7fa48 100644 --- a/include/tkDNN/DarknetParser.h +++ b/include/tkDNN/DarknetParser.h @@ -1,6 +1,6 @@ #pragma once #include -#include "tkdnn.h" +#include "tkDNN/tkdnn.h" namespace tk { namespace dnn { diff --git a/include/tkDNN/NetworkViz.h b/include/tkDNN/NetworkViz.h new file mode 100644 index 0000000..c8b1bea --- /dev/null +++ b/include/tkDNN/NetworkViz.h @@ -0,0 +1,12 @@ +#pragma once +#include +#include +#include "tkdnn.h" + +namespace tk { namespace dnn { + +cv::Mat vizFloat2colorMap(cv::Mat map); +cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim); +cv::Mat vizLayer2Mat(tk::dnn::Network *net, int layer, int imgdim = 1000); + +}} diff --git a/include/tkDNN/utils.h b/include/tkDNN/utils.h index aa73e9e..538a3f3 100644 --- a/include/tkDNN/utils.h +++ b/include/tkDNN/utils.h @@ -118,4 +118,8 @@ void matrixMulAdd( cublasHandle_t handle, dnnType* srcData, dnnType* dstData, void getMemUsage(double& vm_usage_kb, double& resident_set_kb); void printCudaMemUsage(); void removePathAndExtension(const std::string &full_string, std::string &name); +static inline bool isCudaPointer(void *data) { + cudaPointerAttributes attr; + return cudaPointerGetAttributes(&attr, data) == 0; +} #endif //UTILS_H diff --git a/src/NetworkViz.cpp b/src/NetworkViz.cpp new file mode 100644 index 0000000..6ac274c --- /dev/null +++ b/src/NetworkViz.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include "tkDNN/NetworkViz.h" + +namespace tk { namespace dnn { + +cv::Mat vizFloat2colorMap(cv::Mat map) { + + double min; + double max; + cv::minMaxIdx(map, &min, &max); + cv::Mat adjMap; + // expand your range to 0..255. Similar to histEq(); + map.convertTo(adjMap,CV_8UC1, 255 / (max-min), -min); + //return adjMap; + + + cv::Mat falseColorsMap; + applyColorMap(adjMap, falseColorsMap, cv::COLORMAP_HOT); + return falseColorsMap; +} + +cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim) { + dnnType *data = nullptr; + + // copy to CPU + if(isCudaPointer(dataInput)) { + data = new dnnType[dim.tot()]; + checkCuda( cudaMemcpy(data, dataInput, dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); + } else { + data = dataInput; + } + + int gridDim = ceil(sqrt(dim.c)); + cv::Size gridSize(dim.w*gridDim, dim.h*gridDim); + cv::Mat grid = cv::Mat(gridSize, CV_8UC3, cv::Scalar(0)); + + for(int i=0; i= net->num_layers) + FatalError("Could not viz layer\n"); + return vizData2Mat(net->layers[layer]->dstData, net->layers[layer]->output_dim, imgdim); + + //cv::imwrite("viz/layer" + std::to_string(layer) + ".png", viz); + //cv::imshow("layer", viz); + //cv::waitKey(0); +} + +}} \ No newline at end of file diff --git a/tests/darknet/viz_yolo3.cpp b/tests/darknet/viz_yolo3.cpp new file mode 100644 index 0000000..374f7dd --- /dev/null +++ b/tests/darknet/viz_yolo3.cpp @@ -0,0 +1,54 @@ +#include +#include +#include + +#include "tkdnn.h" +#include "test.h" +#include "DarknetParser.h" +#include "NetworkViz.h" + +int main() { + std::string bin_path = "yolo3"; + std::vector input_bins = { + bin_path + "/layers/input.bin" + }; + std::string wgs_path = bin_path + "/layers"; + std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3.cfg"; + std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; + downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/jPXmHyptpLoNdNR/download"); + + // parse darknet network + tk::dnn::Network *net = tk::dnn::darknetParser(cfg_path, wgs_path, name_path); + net->print(); + + // Load input and infer + dnnType *input_d; + dnnType *input_h; + readBinaryFile(input_bins[0], net->input_dim.tot(), &input_h, &input_d); + tk::dnn::dataDim_t dim = net->input_dim; + + dim.print(); + std::cout<<"infer\n"; + net->infer(dim, input_d); + + // output directory + std::string output_viz = "viz/"; + system( (std::string("mkdir -p ") + output_viz).c_str() ); + + for(int i=0; inum_layers; i++) { + std::string output_png = output_viz + "/layer" + std::to_string(i) + ".png"; + std::cout<<"saving "<releaseLayers(); + delete net; + return 0; +} + + \ No newline at end of file From 1b8f45703f0f42a5a9bd1ca45fdda556345984c2 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Tue, 16 Jun 2020 12:41:48 +0200 Subject: [PATCH 3/5] darknet parser cpp --- include/tkDNN/DarknetParser.h | 272 ++-------------------------------- src/DarknetParser.cpp | 261 ++++++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+), 259 deletions(-) create mode 100644 src/DarknetParser.cpp diff --git a/include/tkDNN/DarknetParser.h b/include/tkDNN/DarknetParser.h index cd7fa48..f36469b 100644 --- a/include/tkDNN/DarknetParser.h +++ b/include/tkDNN/DarknetParser.h @@ -27,267 +27,21 @@ namespace tk { namespace dnn { std::vector layers; std::string activation = "linear"; + friend std::ostream& operator<<(std::ostream& os, const darknetFields_t& f){ + os << f.width << " " << f.height << " " << f.channels << " " << f.batch_normalize<< " " << f.filters << " " << f.activation<< " " << f.scale_xy; + return os; + } }; - std::ostream& operator<<(std::ostream& os, const darknetFields_t& f){ - os << f.width << " " << f.height << " " << f.channels << " " << f.batch_normalize<< " " << f.filters << " " << f.activation<< " " << f.scale_xy; - return os; - } - - std::string darknetParseType(const std::string& line){ - size_t start = line.find("["); - size_t end = line.find("]"); - if( start == std::string::npos || end == std::string::npos) - return ""; - start++; - std::string type = line.substr(start, end-start); - return type; - } - - bool divideNameAndValue(const std::string& line, std::string&name, std::string& value){ - size_t sep = line.find("="); - if(sep == std::string::npos) - return false; - - name = line.substr(0, sep); - value = line.substr(sep+1, line.size() - (sep+1)); - return true; - } - - std::vector fromStringToIntVec(const std::string& line, const char delimiter){ - std::stringstream linestream(line); - std::string value; - std::vector values; - - while(getline(linestream,value,delimiter)) - values.push_back(std::stoi(value)); - return values; - } - - bool darknetParseFields(const std::string& line, darknetFields_t& fields){ - - std::string name,value; - if(!divideNameAndValue(line, name, value)) - return false; - if(name.find("width") != std::string::npos) - fields.width = std::stoi(value); - else if(name.find("height") != std::string::npos) - fields.height = std::stoi(value); - else if(name.find("channels") != std::string::npos) - fields.channels = std::stoi(value); - else if(name.find("batch_normalize") != std::string::npos) - fields.batch_normalize = std::stoi(value); - else if(name.find("filters") != std::string::npos) - fields.filters = std::stoi(value); - else if(name.find("activation") != std::string::npos) - fields.activation = value; - else if(name.find("size") != std::string::npos){ - fields.size_x = std::stoi(value); - fields.size_y = std::stoi(value); - } - else if(name.find("size_x") != std::string::npos) - fields.size_x = std::stoi(value); - else if(name.find("size_y") != std::string::npos) - fields.size_y = std::stoi(value); - else if(name.find("stride") != std::string::npos){ - fields.stride_x = std::stoi(value); - fields.stride_y = std::stoi(value); - } - else if(name.find("stride_x") != std::string::npos) - fields.stride_x = std::stoi(value); - else if(name.find("stride_y") != std::string::npos) - fields.stride_y = std::stoi(value); - else if(name.find("pad") != std::string::npos) - fields.pad = std::stoi(value); - else if(name.find("classes") != std::string::npos) - fields.classes = std::stoi(value); - else if(name.find("num") != std::string::npos) - fields.num = std::stoi(value); - else if(name.find("coords") != std::string::npos) - fields.coords = std::stoi(value); - else if(name.find("groups") != std::string::npos) - fields.groups = std::stoi(value); - else if(name.find("scale_x_y") != std::string::npos) - fields.scale_xy = std::stof(value); - else if(name.find("from") != std::string::npos) - fields.layers.push_back(std::stof(value)); - else if(name.find("mask") != std::string::npos){ - auto vec = fromStringToIntVec(value, ','); - fields.n_mask = vec.size(); - } - else if(name.find("layers") != std::string::npos) - fields.layers = fromStringToIntVec(value, ','); - - else - std::cout<<"Not supported field: "< &netLayers, const std::vector& names) { - if(net == nullptr) - FatalError("Cant add a layer without a Net\n"); - - // padding compute - if(f.pad == 1) { - f.padding_x = f.padding_y = f.size_x /2; - } - //std::cout<<"Add layer: "<= netLayers.size()) FatalError("impossible to shortcut\n"); - //std::cout<<"shortcut to "<getLayerName()<<"\n"; - netLayers.push_back(new tk::dnn::Shortcut(net, netLayers[layerIdx])); - - } else if(f.type == "upsample") { - netLayers.push_back(new tk::dnn::Upsample(net, f.stride_x)); - - } else if(f.type == "route") { - if(f.layers.size() == 0) FatalError("no layers to Route\n"); - std::vector layers; - for(int i=0; i= netLayers.size()) FatalError("impossible to route\n"); - //std::cout<<"Route to "<getLayerName()<<"\n"; - layers.push_back(netLayers[layerIdx]); - } - netLayers.push_back(new tk::dnn::Route(net, layers.data(), layers.size())); - - } else if(f.type == "reorg") { - netLayers.push_back(new tk::dnn::Reorg(net, f.stride_x)); - - } else if(f.type == "region") { - netLayers.push_back(new tk::dnn::Region(net, f.classes, f.coords, f.num)); - - } else if(f.type == "yolo") { - std::string wgs = wgs_path + "/g" + std::to_string(netLayers.size()) + ".bin"; - //printf("%d %d %s %d %f\n", f.classes, f.num/f.n_mask, wgs.c_str(), f.n_mask, f.scale_xy); - tk::dnn::Yolo *l = new tk::dnn::Yolo(net, f.classes, f.num/f.n_mask, wgs, f.n_mask, f.scale_xy); - if(names.size() != f.classes) - FatalError("Mismatch between number of classes and names"); - l->classesNames = names; - netLayers.push_back(l); - - } else{ - FatalError("layer not supported: " + f.type); - } - - // add activation - if(netLayers.size() > 0 && f.activation != "linear") { - tkdnnActivationMode_t act; - if(f.activation == "relu") act = tkdnnActivationMode_t(CUDNN_ACTIVATION_RELU); - else if(f.activation == "leaky") act = tk::dnn::ACTIVATION_LEAKY; - else if(f.activation == "mish") act = tk::dnn::ACTIVATION_MISH; - else { FatalError("activation not supported: " + f.activation); } - netLayers[netLayers.size()-1] = new tk::dnn::Activation(net, act); - }; - } - - std::vector darknetReadNames(const std::string& names_file){ - std::ifstream if_names(names_file); - if(!if_names.is_open()) - FatalError("cloud not open names file: " + names_file); - - std::vector names; - std::string line; - while(std::getline(if_names, line)) - if(line != "") - names.push_back(line); - - if_names.close(); - return names; - } - - tk::dnn::Network* darknetParser(const std::string& cfg_file, const std::string& wgs_path, const std::string& names_file) { - - tk::dnn::Network *net = nullptr; - - // layers without activations to retrive correct id number - std::vector netLayers; - - std::ifstream if_cfg(cfg_file); - if(!if_cfg.is_open()) - FatalError("cloud not open cfg file: " + cfg_file); - - std::vector names = darknetReadNames(names_file); - - darknetFields_t fields; // will be filled with layers fields - std::string line; - while(std::getline(if_cfg, line)) { - // remove comments - std::size_t found = line.find("#"); - if ( found != std::string::npos ) { - line = line.substr(0, found); - } - - // skip empty lines - if(line.size() == 0) - continue; - - std::string type = darknetParseType(line); - if(type.size() > 0) { - // end of filled type - if(fields.type != "") { - if(fields.type == "net") - net = darknetAddNet(fields); - else - darknetAddLayer(net, fields, wgs_path, netLayers, names); - } - - // new type - //std::cout<<"type: "< fromStringToIntVec(const std::string& line, const char delimiter); + bool darknetParseFields(const std::string& line, darknetFields_t& fields); + tk::dnn::Network *darknetAddNet(darknetFields_t &fields); + void darknetAddLayer(tk::dnn::Network *net, darknetFields_t &f, std::string wgs_path, + std::vector &netLayers, const std::vector& names); + std::vector darknetReadNames(const std::string& names_file); + tk::dnn::Network* darknetParser(const std::string& cfg_file, const std::string& wgs_path, const std::string& names_file); }} diff --git a/src/DarknetParser.cpp b/src/DarknetParser.cpp new file mode 100644 index 0000000..5092595 --- /dev/null +++ b/src/DarknetParser.cpp @@ -0,0 +1,261 @@ +#include "tkDNN/DarknetParser.h" + +namespace tk { namespace dnn { + + std::string darknetParseType(const std::string& line){ + size_t start = line.find("["); + size_t end = line.find("]"); + if( start == std::string::npos || end == std::string::npos) + return ""; + start++; + std::string type = line.substr(start, end-start); + return type; + } + + bool divideNameAndValue(const std::string& line, std::string&name, std::string& value){ + size_t sep = line.find("="); + if(sep == std::string::npos) + return false; + + name = line.substr(0, sep); + value = line.substr(sep+1, line.size() - (sep+1)); + return true; + } + + std::vector fromStringToIntVec(const std::string& line, const char delimiter){ + std::stringstream linestream(line); + std::string value; + std::vector values; + + while(getline(linestream,value,delimiter)) + values.push_back(std::stoi(value)); + return values; + } + + bool darknetParseFields(const std::string& line, darknetFields_t& fields){ + + std::string name,value; + if(!divideNameAndValue(line, name, value)) + return false; + if(name.find("width") != std::string::npos) + fields.width = std::stoi(value); + else if(name.find("height") != std::string::npos) + fields.height = std::stoi(value); + else if(name.find("channels") != std::string::npos) + fields.channels = std::stoi(value); + else if(name.find("batch_normalize") != std::string::npos) + fields.batch_normalize = std::stoi(value); + else if(name.find("filters") != std::string::npos) + fields.filters = std::stoi(value); + else if(name.find("activation") != std::string::npos) + fields.activation = value; + else if(name.find("size") != std::string::npos){ + fields.size_x = std::stoi(value); + fields.size_y = std::stoi(value); + } + else if(name.find("size_x") != std::string::npos) + fields.size_x = std::stoi(value); + else if(name.find("size_y") != std::string::npos) + fields.size_y = std::stoi(value); + else if(name.find("stride") != std::string::npos){ + fields.stride_x = std::stoi(value); + fields.stride_y = std::stoi(value); + } + else if(name.find("stride_x") != std::string::npos) + fields.stride_x = std::stoi(value); + else if(name.find("stride_y") != std::string::npos) + fields.stride_y = std::stoi(value); + else if(name.find("pad") != std::string::npos) + fields.pad = std::stoi(value); + else if(name.find("classes") != std::string::npos) + fields.classes = std::stoi(value); + else if(name.find("num") != std::string::npos) + fields.num = std::stoi(value); + else if(name.find("coords") != std::string::npos) + fields.coords = std::stoi(value); + else if(name.find("groups") != std::string::npos) + fields.groups = std::stoi(value); + else if(name.find("scale_x_y") != std::string::npos) + fields.scale_xy = std::stof(value); + else if(name.find("from") != std::string::npos) + fields.layers.push_back(std::stof(value)); + else if(name.find("mask") != std::string::npos){ + auto vec = fromStringToIntVec(value, ','); + fields.n_mask = vec.size(); + } + else if(name.find("layers") != std::string::npos) + fields.layers = fromStringToIntVec(value, ','); + + else + std::cout<<"Not supported field: "< &netLayers, const std::vector& names) { + if(net == nullptr) + FatalError("Cant add a layer without a Net\n"); + + // padding compute + if(f.pad == 1) { + f.padding_x = f.padding_y = f.size_x /2; + } + //std::cout<<"Add layer: "<= netLayers.size()) FatalError("impossible to shortcut\n"); + //std::cout<<"shortcut to "<getLayerName()<<"\n"; + netLayers.push_back(new tk::dnn::Shortcut(net, netLayers[layerIdx])); + + } else if(f.type == "upsample") { + netLayers.push_back(new tk::dnn::Upsample(net, f.stride_x)); + + } else if(f.type == "route") { + if(f.layers.size() == 0) FatalError("no layers to Route\n"); + std::vector layers; + for(int i=0; i= netLayers.size()) FatalError("impossible to route\n"); + //std::cout<<"Route to "<getLayerName()<<"\n"; + layers.push_back(netLayers[layerIdx]); + } + netLayers.push_back(new tk::dnn::Route(net, layers.data(), layers.size())); + + } else if(f.type == "reorg") { + netLayers.push_back(new tk::dnn::Reorg(net, f.stride_x)); + + } else if(f.type == "region") { + netLayers.push_back(new tk::dnn::Region(net, f.classes, f.coords, f.num)); + + } else if(f.type == "yolo") { + std::string wgs = wgs_path + "/g" + std::to_string(netLayers.size()) + ".bin"; + //printf("%d %d %s %d %f\n", f.classes, f.num/f.n_mask, wgs.c_str(), f.n_mask, f.scale_xy); + tk::dnn::Yolo *l = new tk::dnn::Yolo(net, f.classes, f.num/f.n_mask, wgs, f.n_mask, f.scale_xy); + if(names.size() != f.classes) + FatalError("Mismatch between number of classes and names"); + l->classesNames = names; + netLayers.push_back(l); + + } else{ + FatalError("layer not supported: " + f.type); + } + + // add activation + if(netLayers.size() > 0 && f.activation != "linear") { + tkdnnActivationMode_t act; + if(f.activation == "relu") act = tkdnnActivationMode_t(CUDNN_ACTIVATION_RELU); + else if(f.activation == "leaky") act = tk::dnn::ACTIVATION_LEAKY; + else if(f.activation == "mish") act = tk::dnn::ACTIVATION_MISH; + else { FatalError("activation not supported: " + f.activation); } + netLayers[netLayers.size()-1] = new tk::dnn::Activation(net, act); + }; + } + + std::vector darknetReadNames(const std::string& names_file){ + std::ifstream if_names(names_file); + if(!if_names.is_open()) + FatalError("cloud not open names file: " + names_file); + + std::vector names; + std::string line; + while(std::getline(if_names, line)) + if(line != "") + names.push_back(line); + + if_names.close(); + return names; + } + + tk::dnn::Network* darknetParser(const std::string& cfg_file, const std::string& wgs_path, const std::string& names_file) { + + tk::dnn::Network *net = nullptr; + + // layers without activations to retrive correct id number + std::vector netLayers; + + std::ifstream if_cfg(cfg_file); + if(!if_cfg.is_open()) + FatalError("cloud not open cfg file: " + cfg_file); + + std::vector names = darknetReadNames(names_file); + + darknetFields_t fields; // will be filled with layers fields + std::string line; + while(std::getline(if_cfg, line)) { + // remove comments + std::size_t found = line.find("#"); + if ( found != std::string::npos ) { + line = line.substr(0, found); + } + + // skip empty lines + if(line.size() == 0) + continue; + + std::string type = darknetParseType(line); + if(type.size() > 0) { + // end of filled type + if(fields.type != "") { + if(fields.type == "net") + net = darknetAddNet(fields); + else + darknetAddLayer(net, fields, wgs_path, netLayers, names); + } + + // new type + //std::cout<<"type: "< Date: Tue, 16 Jun 2020 12:44:12 +0200 Subject: [PATCH 4/5] dealloc in test.h fix #36 --- include/tkDNN/test.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/tkDNN/test.h b/include/tkDNN/test.h index be3d891..4e238ff 100644 --- a/include/tkDNN/test.h +++ b/include/tkDNN/test.h @@ -1,7 +1,7 @@ #include int testInference(std::vector input_bins, std::vector output_bins, - tk::dnn::Network *net, tk::dnn::NetworkRT *netRT = nullptr) { + tk::dnn::Network *net, tk::dnn::NetworkRT *netRT = nullptr) { std::vector outputs; for(int i=0; inum_layers; i++) { @@ -67,7 +67,11 @@ int testInference(std::vector input_bins, std::vector std::cout<<"CUDNN vs TRT "; ret_cudnn_tensorrt |= checkResult(odim, cudnn_out[i], rt_out[i]) == 0 ? 0 : ERROR_CUDNNvsTENSORRT; } - } - return ret_cudnn | ret_tensorrt | ret_cudnn_tensorrt; - } \ No newline at end of file + delete [] out_h; + checkCuda( cudaFree(out) ); + } + delete [] input_h; + checkCuda( cudaFree(data) ); + return ret_cudnn | ret_tensorrt | ret_cudnn_tensorrt; +} \ No newline at end of file From 1dfc69ba8916f913282c1fb68a117cdc72468f78 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Tue, 16 Jun 2020 13:19:30 +0200 Subject: [PATCH 5/5] viz yolo3 preprocess --- tests/darknet/viz_yolo3.cpp | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/tests/darknet/viz_yolo3.cpp b/tests/darknet/viz_yolo3.cpp index 374f7dd..9e53116 100644 --- a/tests/darknet/viz_yolo3.cpp +++ b/tests/darknet/viz_yolo3.cpp @@ -1,32 +1,49 @@ #include #include #include +#include #include "tkdnn.h" #include "test.h" #include "DarknetParser.h" #include "NetworkViz.h" -int main() { +int main(int argc, char *argv[]) { + if(argc <2) + FatalError("you must provide an input image"); + std::string input_image = argv[1]; std::string bin_path = "yolo3"; - std::vector input_bins = { - bin_path + "/layers/input.bin" - }; std::string wgs_path = bin_path + "/layers"; std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo3.cfg"; std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names"; - downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/jPXmHyptpLoNdNR/download"); + downloadWeightsifDoNotExist(wgs_path, bin_path, "https://cloud.hipert.unimore.it/s/jPXmHyptpLoNdNR/download"); // parse darknet network tk::dnn::Network *net = tk::dnn::darknetParser(cfg_path, wgs_path, name_path); net->print(); - // Load input and infer + // input data dnnType *input_d; - dnnType *input_h; - readBinaryFile(input_bins[0], net->input_dim.tot(), &input_h, &input_d); - tk::dnn::dataDim_t dim = net->input_dim; + checkCuda( cudaMalloc(&input_d, sizeof(dnnType)*net->input_dim.tot())); + + // load image + cv::Mat frame, frameFloat; + frame = cv::imread(input_image); + cv::resize(frame, frame, cv::Size(net->input_dim.w, net->input_dim.h)); + frame.convertTo(frameFloat, CV_32FC3, 1/255.0); + + //split channels + cv::Mat bgr[3]; + cv::split(frameFloat,bgr);//split source + + //write channels + for(int i=0; iinput_dim.c; i++) { + int idx = i*frameFloat.rows*frameFloat.cols; + int ch = net->input_dim.c-1 -i; + checkCuda( cudaMemcpy(input_d + idx, (void*)bgr[ch].data, frameFloat.rows*frameFloat.cols*sizeof(dnnType), cudaMemcpyHostToDevice)); + } + tk::dnn::dataDim_t dim = net->input_dim; dim.print(); std::cout<<"infer\n"; net->infer(dim, input_d); @@ -44,7 +61,6 @@ int main() { //cv::waitKey(0); } - delete [] input_h; checkCuda(cudaFree(input_d)); net->releaseLayers(); delete net;