You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ncnn2int8.cpp 53 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481
  1. // BUG1989 is pleased to support the open source community by supporting ncnn available.
  2. //
  3. // Copyright (C) 2019 BUG1989. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #ifdef _MSC_VER
  15. #define _CRT_SECURE_NO_DEPRECATE
  16. #endif
  17. #include <cstdio>
  18. #include <cstring>
  19. #include <map>
  20. #include <set>
  21. #include <vector>
  22. // ncnn public header
  23. #include "datareader.h"
  24. #include "layer.h"
  25. #include "layer_type.h"
  26. #include "net.h"
  27. // ncnn private header
  28. #include "layer/batchnorm.h"
  29. #include "layer/bias.h"
  30. #include "layer/binaryop.h"
  31. #include "layer/clip.h"
  32. #include "layer/concat.h"
  33. #include "layer/convolution.h"
  34. #include "layer/convolutiondepthwise.h"
  35. #include "layer/crop.h"
  36. #include "layer/deconvolution.h"
  37. #include "layer/deconvolutiondepthwise.h"
  38. #include "layer/detectionoutput.h"
  39. #include "layer/dropout.h"
  40. #include "layer/eltwise.h"
  41. #include "layer/elu.h"
  42. #include "layer/exp.h"
  43. #include "layer/flatten.h"
  44. #include "layer/innerproduct.h"
  45. #include "layer/input.h"
  46. #include "layer/instancenorm.h"
  47. #include "layer/interp.h"
  48. #include "layer/log.h"
  49. #include "layer/lrn.h"
  50. #include "layer/lstm.h"
  51. #include "layer/memorydata.h"
  52. #include "layer/mvn.h"
  53. #include "layer/normalize.h"
  54. #include "layer/padding.h"
  55. #include "layer/permute.h"
  56. #include "layer/pixelshuffle.h"
  57. #include "layer/pooling.h"
  58. #include "layer/power.h"
  59. #include "layer/prelu.h"
  60. #include "layer/priorbox.h"
  61. #include "layer/proposal.h"
  62. #include "layer/psroipooling.h"
  63. #include "layer/quantize.h"
  64. #include "layer/reduction.h"
  65. #include "layer/relu.h"
  66. #include "layer/reorg.h"
  67. #include "layer/requantize.h"
  68. #include "layer/reshape.h"
  69. #include "layer/roialign.h"
  70. #include "layer/roipooling.h"
  71. #include "layer/scale.h"
  72. #include "layer/shufflechannel.h"
  73. #include "layer/slice.h"
  74. #include "layer/softmax.h"
  75. #include "layer/split.h"
  76. #include "layer/threshold.h"
  77. #include "layer/unaryop.h"
  78. #include "layer/yolodetectionoutput.h"
  79. #include "layer/yolov3detectionoutput.h"
  80. class DataReaderFromEmpty : public ncnn::DataReader
  81. {
  82. public:
  83. virtual int scan(const char* format, void* p) const
  84. {
  85. return 0;
  86. }
  87. virtual size_t read(void* /*buf*/, size_t size) const
  88. {
  89. return size;
  90. }
  91. };
  92. static bool read_int8scale_table(const char* filepath, std::map<std::string, ncnn::Mat>& blob_int8scale_table, std::map<std::string, ncnn::Mat>& weight_int8scale_table)
  93. {
  94. blob_int8scale_table.clear();
  95. weight_int8scale_table.clear();
  96. FILE* fp = fopen(filepath, "rb");
  97. if (!fp)
  98. {
  99. fprintf(stderr, "Open %s failed.\n", filepath);
  100. return false;
  101. }
  102. std::string key_str;
  103. std::vector<float> scales;
  104. std::vector<char> line(102400);
  105. char* pch = NULL;
  106. size_t len = 0;
  107. while (NULL != std::fgets(line.data(), static_cast<int>(line.size()), fp))
  108. {
  109. float scale = 1.f;
  110. char key[256];
  111. line[strcspn(line.data(), "\r\n")] = 0;
  112. pch = strtok(line.data(), " ");
  113. if (pch == NULL) break;
  114. bool is_key = true;
  115. while (pch != NULL)
  116. {
  117. if (is_key)
  118. {
  119. sscanf(pch, "%255s", key);
  120. key_str = key;
  121. is_key = false;
  122. }
  123. else
  124. {
  125. sscanf(pch, "%f", &scale);
  126. scales.push_back(scale);
  127. }
  128. pch = strtok(NULL, " ");
  129. }
  130. // XYZ_param_N pattern
  131. if (strstr(key_str.c_str(), "_param_"))
  132. {
  133. weight_int8scale_table[key_str] = ncnn::Mat((int)scales.size(), (void*)scales.data()).clone();
  134. }
  135. else
  136. {
  137. blob_int8scale_table[key_str] = ncnn::Mat((int)scales.size(), (void*)scales.data()).clone();
  138. }
  139. key_str.clear();
  140. scales.clear();
  141. }
  142. fclose(fp);
  143. return true;
  144. }
  145. class NetQuantize : public ncnn::Net
  146. {
  147. public:
  148. NetQuantize();
  149. std::vector<ncnn::Blob>& blobs;
  150. std::vector<ncnn::Layer*>& layers;
  151. // 0=fp32 1=fp16 2=int8
  152. int storage_type;
  153. std::map<std::string, ncnn::Mat> blob_int8scale_table;
  154. std::map<std::string, ncnn::Mat> weight_int8scale_table;
  155. public:
  156. int quantize_convolution();
  157. int quantize_convolutiondepthwise();
  158. int quantize_innerproduct();
  159. int fuse_requantize();
  160. public:
  161. int fprintf_param_int_array(int id, const ncnn::Mat& m, FILE* pp);
  162. int fprintf_param_float_array(int id, const ncnn::Mat& m, FILE* pp);
  163. int fwrite_weight_tag_data(int tag, const ncnn::Mat& data, FILE* bp);
  164. int fwrite_weight_data(const ncnn::Mat& data, FILE* bp);
  165. int save(const char* parampath, const char* binpath);
  166. };
  167. NetQuantize::NetQuantize()
  168. : blobs(mutable_blobs()), layers(mutable_layers())
  169. {
  170. }
  171. int NetQuantize::quantize_convolution()
  172. {
  173. const int layer_count = static_cast<int>(layers.size());
  174. for (int i = 0; i < layer_count; i++)
  175. {
  176. // find convolution layer
  177. if (layers[i]->type != "Convolution")
  178. continue;
  179. // find convolution layer
  180. std::map<std::string, ncnn::Mat>::iterator iter_data = blob_int8scale_table.find(layers[i]->name);
  181. if (iter_data == blob_int8scale_table.end())
  182. continue;
  183. char key[256];
  184. sprintf(key, "%s_param_0", layers[i]->name.c_str());
  185. std::map<std::string, ncnn::Mat>::iterator iter = weight_int8scale_table.find(key);
  186. if (iter == weight_int8scale_table.end())
  187. {
  188. fprintf(stderr, "this layer need to be quantized, but no scale param!\n");
  189. return -1;
  190. }
  191. // Convolution - quantize weight from fp32 to int8
  192. ncnn::Convolution* convolution = (ncnn::Convolution*)layers[i];
  193. ncnn::Mat bottom_blob_int8_scales = iter_data->second;
  194. ncnn::Mat weight_data_int8_scales = iter->second;
  195. fprintf(stderr, "quantize_convolution %s\n", convolution->name.c_str());
  196. {
  197. const int maxk = convolution->kernel_w * convolution->kernel_h;
  198. const int num_input = convolution->weight_data_size / convolution->num_output / maxk;
  199. ncnn::Mat weight_data_r2 = convolution->weight_data.reshape(maxk, num_input, convolution->num_output);
  200. ncnn::Mat weight_data_int8;
  201. ncnn::Option opt_q = opt;
  202. opt_q.blob_allocator = convolution->weight_data.allocator;
  203. opt_q.use_packing_layout = false;
  204. ncnn::quantize_to_int8(weight_data_r2, weight_data_int8, weight_data_int8_scales, opt_q);
  205. if (weight_data_int8.empty())
  206. return -100;
  207. convolution->weight_data = weight_data_int8.reshape(convolution->weight_data_size);
  208. }
  209. convolution->int8_scale_term = 2;
  210. convolution->weight_data_int8_scales = weight_data_int8_scales;
  211. convolution->bottom_blob_int8_scales = bottom_blob_int8_scales;
  212. }
  213. return 0;
  214. }
  215. int NetQuantize::quantize_convolutiondepthwise()
  216. {
  217. const int layer_count = static_cast<int>(layers.size());
  218. for (int i = 0; i < layer_count; i++)
  219. {
  220. // find convoultion layer
  221. if (layers[i]->type != "ConvolutionDepthWise")
  222. continue;
  223. // find convolutiondepthwise layer
  224. std::map<std::string, ncnn::Mat>::iterator iter_data = blob_int8scale_table.find(layers[i]->name);
  225. if (iter_data == blob_int8scale_table.end())
  226. continue;
  227. char key[256];
  228. sprintf(key, "%s_param_0", layers[i]->name.c_str());
  229. std::map<std::string, ncnn::Mat>::iterator iter = weight_int8scale_table.find(key);
  230. if (iter == weight_int8scale_table.end())
  231. {
  232. fprintf(stderr, "this layer need to be quantized, but no scale param!\n");
  233. return -1;
  234. }
  235. // Convolution - quantize weight from fp32 to int8
  236. ncnn::ConvolutionDepthWise* convdw = (ncnn::ConvolutionDepthWise*)layers[i];
  237. ncnn::Mat bottom_blob_int8_scales = iter_data->second;
  238. ncnn::Mat weight_data_int8_scales = iter->second;
  239. fprintf(stderr, "quantize_convolution %s\n", convdw->name.c_str());
  240. {
  241. ncnn::Mat int8_weight_data(convdw->weight_data_size, (size_t)1u);
  242. if (int8_weight_data.empty())
  243. return -100;
  244. const int weight_data_size_g = convdw->weight_data_size / convdw->group;
  245. for (int g = 0; g < convdw->group; g++)
  246. {
  247. ncnn::Option opt_q = opt;
  248. opt_q.blob_allocator = int8_weight_data.allocator;
  249. opt_q.use_packing_layout = false;
  250. const ncnn::Mat weight_data_g = convdw->weight_data.range(weight_data_size_g * g, weight_data_size_g);
  251. ncnn::Mat int8_weight_data_g = int8_weight_data.range(weight_data_size_g * g, weight_data_size_g);
  252. const ncnn::Mat weight_data_int8_scales_g = weight_data_int8_scales.range(g, 1);
  253. ncnn::quantize_to_int8(weight_data_g, int8_weight_data_g, weight_data_int8_scales_g, opt_q);
  254. }
  255. convdw->weight_data = int8_weight_data;
  256. }
  257. convdw->int8_scale_term = 1;
  258. convdw->weight_data_int8_scales = weight_data_int8_scales;
  259. convdw->bottom_blob_int8_scales = bottom_blob_int8_scales;
  260. }
  261. return 0;
  262. }
  263. int NetQuantize::quantize_innerproduct()
  264. {
  265. const int layer_count = static_cast<int>(layers.size());
  266. for (int i = 0; i < layer_count; i++)
  267. {
  268. // find convoultion layer
  269. if (layers[i]->type != "InnerProduct")
  270. continue;
  271. // find InnerProduct layer
  272. std::map<std::string, ncnn::Mat>::iterator iter_data = blob_int8scale_table.find(layers[i]->name);
  273. if (iter_data == blob_int8scale_table.end())
  274. continue;
  275. char key[256];
  276. sprintf(key, "%s_param_0", layers[i]->name.c_str());
  277. std::map<std::string, ncnn::Mat>::iterator iter = weight_int8scale_table.find(key);
  278. if (iter == weight_int8scale_table.end())
  279. {
  280. fprintf(stderr, "this layer need to be quantized, but no scale param!\n");
  281. return -1;
  282. }
  283. // InnerProduct - quantize weight from fp32 to int8
  284. ncnn::InnerProduct* fc = (ncnn::InnerProduct*)layers[i];
  285. ncnn::Mat bottom_blob_int8_scales = iter_data->second;
  286. ncnn::Mat weight_data_int8_scales = iter->second;
  287. fprintf(stderr, "quantize_convolution %s\n", fc->name.c_str());
  288. {
  289. const int num_input = fc->weight_data_size / fc->num_output;
  290. ncnn::Mat weight_data_r2 = fc->weight_data.reshape(num_input, fc->num_output);
  291. ncnn::Mat weight_data_int8;
  292. ncnn::Option opt_q = opt;
  293. opt_q.use_packing_layout = false;
  294. ncnn::quantize_to_int8(weight_data_r2, weight_data_int8, weight_data_int8_scales, opt_q);
  295. if (weight_data_int8.empty())
  296. return -100;
  297. fc->weight_data = weight_data_int8.reshape(fc->weight_data_size);
  298. }
  299. fc->int8_scale_term = 2;
  300. fc->weight_data_int8_scales = weight_data_int8_scales;
  301. fc->bottom_blob_int8_scales = bottom_blob_int8_scales;
  302. }
  303. return 0;
  304. }
  305. int NetQuantize::fuse_requantize()
  306. {
  307. const size_t layer_count = layers.size();
  308. for (size_t i = 0; i < layer_count; i++)
  309. {
  310. if (layers[i]->type != "Convolution" && layers[i]->type != "ConvolutionDepthWise")
  311. continue;
  312. // Convolution/ConvolutionDepthWise - Convolution/ConvolutionDepthWise
  313. int top_blob_index = layers[i]->tops[0];
  314. size_t j = i + 1;
  315. for (; j < layer_count; j++)
  316. {
  317. if (layers[j]->type != "Convolution" && layers[j]->type != "ConvolutionDepthWise")
  318. continue;
  319. if (layers[j]->bottoms.size() != 1)
  320. continue;
  321. if (layers[j]->bottoms[0] == top_blob_index)
  322. break;
  323. }
  324. if (j == layer_count)
  325. continue;
  326. // fuse requantize
  327. fprintf(stderr, "fuse_requantize %s %s\n", layers[i]->name.c_str(), layers[j]->name.c_str());
  328. if (layers[i]->type == "Convolution" && layers[j]->type == "Convolution")
  329. {
  330. ncnn::Convolution* convolution1 = (ncnn::Convolution*)layers[i];
  331. ncnn::Convolution* convolution2 = (ncnn::Convolution*)layers[j];
  332. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  333. continue;
  334. convolution1->int8_scale_term += 100;
  335. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  336. }
  337. if (layers[i]->type == "Convolution" && layers[j]->type == "ConvolutionDepthWise")
  338. {
  339. ncnn::Convolution* convolution1 = (ncnn::Convolution*)layers[i];
  340. ncnn::ConvolutionDepthWise* convolution2 = (ncnn::ConvolutionDepthWise*)layers[j];
  341. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  342. continue;
  343. convolution1->int8_scale_term += 100;
  344. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  345. }
  346. if (layers[i]->type == "ConvolutionDepthWise" && layers[j]->type == "Convolution")
  347. {
  348. ncnn::ConvolutionDepthWise* convolution1 = (ncnn::ConvolutionDepthWise*)layers[i];
  349. ncnn::Convolution* convolution2 = (ncnn::Convolution*)layers[j];
  350. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  351. continue;
  352. convolution1->int8_scale_term += 100;
  353. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  354. }
  355. if (layers[i]->type == "ConvolutionDepthWise" && layers[j]->type == "ConvolutionDepthWise")
  356. {
  357. ncnn::ConvolutionDepthWise* convolution1 = (ncnn::ConvolutionDepthWise*)layers[i];
  358. ncnn::ConvolutionDepthWise* convolution2 = (ncnn::ConvolutionDepthWise*)layers[j];
  359. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  360. continue;
  361. convolution1->int8_scale_term += 100;
  362. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  363. }
  364. }
  365. for (size_t i = 0; i < layer_count; i++)
  366. {
  367. if (layers[i]->type != "Convolution" && layers[i]->type != "ConvolutionDepthWise")
  368. continue;
  369. // Convolution/ConvolutionDepthWise - Split - Convolution/ConvolutionDepthWise
  370. int top_blob_index = layers[i]->tops[0];
  371. size_t j = i + 1;
  372. for (; j < layer_count; j++)
  373. {
  374. if (layers[j]->type != "Split")
  375. continue;
  376. if (layers[j]->bottoms.size() != 1)
  377. continue;
  378. if (layers[j]->bottoms[0] == top_blob_index)
  379. break;
  380. }
  381. if (j == layer_count)
  382. continue;
  383. ncnn::Split* split = (ncnn::Split*)layers[j];
  384. bool all_conv = true;
  385. for (size_t p = 0; p < split->tops.size(); p++)
  386. {
  387. int split_top_blob_index = split->tops[p];
  388. size_t k = j + 1;
  389. for (; k < layer_count; k++)
  390. {
  391. if (layers[k]->type != "Convolution" && layers[k]->type != "ConvolutionDepthWise")
  392. continue;
  393. if (layers[k]->bottoms.size() != 1)
  394. continue;
  395. if (layers[k]->bottoms[0] == split_top_blob_index)
  396. break;
  397. }
  398. if (k == layer_count)
  399. {
  400. all_conv = false;
  401. break;
  402. }
  403. if (layers[k]->type == "Convolution")
  404. {
  405. ncnn::Convolution* convolution = (ncnn::Convolution*)layers[k];
  406. if (convolution->weight_data.elemsize != 1u)
  407. {
  408. all_conv = false;
  409. break;
  410. }
  411. }
  412. if (layers[k]->type == "ConvolutionDepthWise")
  413. {
  414. ncnn::ConvolutionDepthWise* convolution = (ncnn::ConvolutionDepthWise*)layers[k];
  415. if (convolution->weight_data.elemsize != 1u)
  416. {
  417. all_conv = false;
  418. break;
  419. }
  420. }
  421. }
  422. if (!all_conv)
  423. continue;
  424. j = blobs[split->tops[0]].consumer;
  425. // fuse requantize
  426. fprintf(stderr, "fuse_requantize %s %s\n", layers[i]->name.c_str(), split->name.c_str());
  427. if (layers[i]->type == "Convolution" && layers[j]->type == "Convolution")
  428. {
  429. ncnn::Convolution* convolution1 = (ncnn::Convolution*)layers[i];
  430. ncnn::Convolution* convolution2 = (ncnn::Convolution*)layers[j];
  431. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  432. continue;
  433. convolution1->int8_scale_term += 100;
  434. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  435. }
  436. if (layers[i]->type == "Convolution" && layers[j]->type == "ConvolutionDepthWise")
  437. {
  438. ncnn::Convolution* convolution1 = (ncnn::Convolution*)layers[i];
  439. ncnn::ConvolutionDepthWise* convolution2 = (ncnn::ConvolutionDepthWise*)layers[j];
  440. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  441. continue;
  442. convolution1->int8_scale_term += 100;
  443. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  444. }
  445. if (layers[i]->type == "ConvolutionDepthWise" && layers[j]->type == "Convolution")
  446. {
  447. ncnn::ConvolutionDepthWise* convolution1 = (ncnn::ConvolutionDepthWise*)layers[i];
  448. ncnn::Convolution* convolution2 = (ncnn::Convolution*)layers[j];
  449. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  450. continue;
  451. convolution1->int8_scale_term += 100;
  452. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  453. }
  454. if (layers[i]->type == "ConvolutionDepthWise" && layers[j]->type == "ConvolutionDepthWise")
  455. {
  456. ncnn::ConvolutionDepthWise* convolution1 = (ncnn::ConvolutionDepthWise*)layers[i];
  457. ncnn::ConvolutionDepthWise* convolution2 = (ncnn::ConvolutionDepthWise*)layers[j];
  458. if (convolution1->weight_data.elemsize != 1u || convolution2->weight_data.elemsize != 1u)
  459. continue;
  460. convolution1->int8_scale_term += 100;
  461. convolution1->top_blob_int8_scales = convolution2->bottom_blob_int8_scales;
  462. }
  463. }
  464. return 0;
  465. }
  466. int NetQuantize::fprintf_param_int_array(int id, const ncnn::Mat& m, FILE* pp)
  467. {
  468. const int count = m.w;
  469. const int* ptr = m;
  470. fprintf(pp, " -%d=%d", 23300 + id, count);
  471. for (int i = 0; i < count; i++)
  472. {
  473. fprintf(pp, ",%d", ptr[i]);
  474. }
  475. return 0;
  476. }
  477. int NetQuantize::fprintf_param_float_array(int id, const ncnn::Mat& m, FILE* pp)
  478. {
  479. const int count = m.w;
  480. const float* ptr = m;
  481. fprintf(pp, " -%d=%d", 23300 + id, count);
  482. for (int i = 0; i < count; i++)
  483. {
  484. fprintf(pp, ",%f", ptr[i]);
  485. }
  486. return 0;
  487. }
  488. static inline size_t alignSize(size_t sz, int n)
  489. {
  490. return (sz + n - 1) & -n;
  491. }
  492. int NetQuantize::fwrite_weight_tag_data(int tag, const ncnn::Mat& data, FILE* bp)
  493. {
  494. int p0 = ftell(bp);
  495. ncnn::Mat data_flattened = data.reshape(data.w * data.h * data.c);
  496. if (data.elemsize == 1)
  497. tag = 0x000D4B38; // int8 magic
  498. fwrite(&tag, sizeof(int), 1, bp);
  499. fwrite(data_flattened.data, data_flattened.elemsize, data_flattened.w, bp);
  500. // padding to 32bit align
  501. int nwrite = ftell(bp) - p0;
  502. int nalign = static_cast<int>(alignSize(nwrite, 4));
  503. unsigned char padding[4] = {0x00, 0x00, 0x00, 0x00};
  504. fwrite(padding, sizeof(unsigned char), nalign - nwrite, bp);
  505. return 0;
  506. }
  507. int NetQuantize::fwrite_weight_data(const ncnn::Mat& data, FILE* bp)
  508. {
  509. int p0 = ftell(bp);
  510. ncnn::Mat data_flattened = data.reshape(data.w * data.h * data.c);
  511. fwrite(data_flattened.data, data_flattened.elemsize, data_flattened.w, bp);
  512. // padding to 32bit align
  513. int nwrite = ftell(bp) - p0;
  514. int nalign = static_cast<int>(alignSize(nwrite, 4));
  515. unsigned char padding[4] = {0x00, 0x00, 0x00, 0x00};
  516. fwrite(padding, sizeof(unsigned char), nalign - nwrite, bp);
  517. return 0;
  518. }
  519. int NetQuantize::save(const char* parampath, const char* binpath)
  520. {
  521. FILE* pp = fopen(parampath, "wb");
  522. FILE* bp = fopen(binpath, "wb");
  523. fprintf(pp, "7767517\n");
  524. const int layer_count = static_cast<int>(layers.size());
  525. int layer_count_fused = 0;
  526. std::set<std::string> blob_names;
  527. for (int i = 0; i < layer_count; i++)
  528. {
  529. const ncnn::Layer* layer = layers[i];
  530. if (layer->type == "ncnnfused")
  531. continue;
  532. layer_count_fused++;
  533. int bottom_count = static_cast<int>(layer->bottoms.size());
  534. for (int j = 0; j < bottom_count; j++)
  535. {
  536. int bottom_blob_index = layer->bottoms[j];
  537. blob_names.insert(blobs[bottom_blob_index].name);
  538. }
  539. int top_count = static_cast<int>(layer->tops.size());
  540. for (int j = 0; j < top_count; j++)
  541. {
  542. int top_blob_index = layer->tops[j];
  543. blob_names.insert(blobs[top_blob_index].name);
  544. }
  545. }
  546. int blob_count_fused = static_cast<int>(blob_names.size());
  547. fprintf(pp, "%d %d\n", layer_count_fused, blob_count_fused);
  548. for (int i = 0; i < layer_count; i++)
  549. {
  550. const ncnn::Layer* layer = layers[i];
  551. if (layer->type == "ncnnfused")
  552. continue;
  553. int bottom_count = static_cast<int>(layer->bottoms.size());
  554. int top_count = static_cast<int>(layer->tops.size());
  555. fprintf(pp, "%-24s %-24s %d %d", layer->type.c_str(), layer->name.c_str(), bottom_count, top_count);
  556. for (int j = 0; j < bottom_count; j++)
  557. {
  558. int bottom_blob_index = layer->bottoms[j];
  559. fprintf(pp, " %s", blobs[bottom_blob_index].name.c_str());
  560. }
  561. for (int j = 0; j < top_count; j++)
  562. {
  563. int top_blob_index = layer->tops[j];
  564. fprintf(pp, " %s", blobs[top_blob_index].name.c_str());
  565. }
  566. ncnn::Layer* layer_default = ncnn::create_layer(layer->typeindex);
  567. ncnn::ParamDict pd;
  568. layer_default->load_param(pd);
  569. #define fprintf_param_value(format, phase) \
  570. { \
  571. if (op->phase != op_default->phase) fprintf(pp, format, op->phase); \
  572. }
  573. if (layer->type == "BatchNorm")
  574. {
  575. ncnn::BatchNorm* op = (ncnn::BatchNorm*)layer;
  576. ncnn::BatchNorm* op_default = (ncnn::BatchNorm*)layer_default;
  577. fprintf_param_value(" 0=%d", channels)
  578. fprintf_param_value(" 1=%f", eps)
  579. fwrite_weight_data(op->slope_data, bp);
  580. fwrite_weight_data(op->mean_data, bp);
  581. fwrite_weight_data(op->var_data, bp);
  582. fwrite_weight_data(op->bias_data, bp);
  583. }
  584. else if (layer->type == "Bias")
  585. {
  586. ncnn::Bias* op = (ncnn::Bias*)layer;
  587. ncnn::Bias* op_default = (ncnn::Bias*)layer_default;
  588. fprintf_param_value(" 0=%d", bias_data_size)
  589. fwrite_weight_data(op->bias_data, bp);
  590. }
  591. else if (layer->type == "BinaryOp")
  592. {
  593. ncnn::BinaryOp* op = (ncnn::BinaryOp*)layer;
  594. ncnn::BinaryOp* op_default = (ncnn::BinaryOp*)layer_default;
  595. fprintf_param_value(" 0=%d", op_type)
  596. fprintf_param_value(" 1=%d", with_scalar)
  597. fprintf_param_value(" 2=%f", b)
  598. }
  599. else if (layer->type == "Clip")
  600. {
  601. ncnn::Clip* op = (ncnn::Clip*)layer;
  602. ncnn::Clip* op_default = (ncnn::Clip*)layer_default;
  603. fprintf_param_value(" 0=%f", min)
  604. fprintf_param_value(" 1=%f", max)
  605. }
  606. else if (layer->type == "Concat")
  607. {
  608. ncnn::Concat* op = (ncnn::Concat*)layer;
  609. ncnn::Concat* op_default = (ncnn::Concat*)layer_default;
  610. fprintf_param_value(" 0=%d", axis)
  611. }
  612. else if (layer->type == "Convolution")
  613. {
  614. ncnn::Convolution* op = (ncnn::Convolution*)layer;
  615. ncnn::Convolution* op_default = (ncnn::Convolution*)layer_default;
  616. fprintf_param_value(" 0=%d", num_output)
  617. fprintf_param_value(" 1=%d", kernel_w)
  618. {
  619. if (op->kernel_h != op->kernel_w) fprintf(pp, " 11=%d", op->kernel_h);
  620. }
  621. fprintf_param_value(" 2=%d", dilation_w)
  622. {
  623. if (op->dilation_h != op->dilation_w) fprintf(pp, " 12=%d", op->dilation_h);
  624. }
  625. fprintf_param_value(" 3=%d", stride_w)
  626. {
  627. if (op->stride_h != op->stride_w) fprintf(pp, " 13=%d", op->stride_h);
  628. }
  629. fprintf_param_value(" 4=%d", pad_left)
  630. {
  631. if (op->pad_top != op->pad_left) fprintf(pp, " 14=%d", op->pad_top);
  632. }
  633. {
  634. if (op->pad_right != op->pad_left) fprintf(pp, " 15=%d", op->pad_right);
  635. }
  636. {
  637. if (op->pad_bottom != op->pad_top) fprintf(pp, " 16=%d", op->pad_bottom);
  638. }
  639. fprintf_param_value(" 5=%d", bias_term)
  640. fprintf_param_value(" 6=%d", weight_data_size)
  641. fprintf_param_value(" 8=%d", int8_scale_term)
  642. fprintf_param_value(" 9=%d", activation_type)
  643. {
  644. if (!op->activation_params.empty()) fprintf_param_float_array(10, op->activation_params, pp);
  645. }
  646. fwrite_weight_tag_data(0, op->weight_data, bp);
  647. fwrite_weight_data(op->bias_data, bp);
  648. // write int8_scale data
  649. if (op->int8_scale_term)
  650. {
  651. fwrite_weight_data(op->weight_data_int8_scales, bp);
  652. fwrite_weight_data(op->bottom_blob_int8_scales, bp);
  653. fwrite_weight_data(op->top_blob_int8_scales, bp);
  654. }
  655. }
  656. else if (layer->type == "ConvolutionDepthWise")
  657. {
  658. ncnn::ConvolutionDepthWise* op = (ncnn::ConvolutionDepthWise*)layer;
  659. ncnn::ConvolutionDepthWise* op_default = (ncnn::ConvolutionDepthWise*)layer_default;
  660. fprintf_param_value(" 0=%d", num_output)
  661. fprintf_param_value(" 1=%d", kernel_w)
  662. {
  663. if (op->kernel_h != op->kernel_w) fprintf(pp, " 11=%d", op->kernel_h);
  664. }
  665. fprintf_param_value(" 2=%d", dilation_w)
  666. {
  667. if (op->dilation_h != op->dilation_w) fprintf(pp, " 12=%d", op->dilation_h);
  668. }
  669. fprintf_param_value(" 3=%d", stride_w)
  670. {
  671. if (op->stride_h != op->stride_w) fprintf(pp, " 13=%d", op->stride_h);
  672. }
  673. fprintf_param_value(" 4=%d", pad_left)
  674. {
  675. if (op->pad_top != op->pad_left) fprintf(pp, " 14=%d", op->pad_top);
  676. }
  677. {
  678. if (op->pad_right != op->pad_left) fprintf(pp, " 15=%d", op->pad_right);
  679. }
  680. {
  681. if (op->pad_bottom != op->pad_top) fprintf(pp, " 16=%d", op->pad_bottom);
  682. }
  683. fprintf_param_value(" 5=%d", bias_term)
  684. fprintf_param_value(" 6=%d", weight_data_size)
  685. fprintf_param_value(" 7=%d", group)
  686. fprintf_param_value(" 8=%d", int8_scale_term)
  687. fprintf_param_value(" 9=%d", activation_type)
  688. {
  689. if (!op->activation_params.empty()) fprintf_param_float_array(10, op->activation_params, pp);
  690. }
  691. fwrite_weight_tag_data(0, op->weight_data, bp);
  692. fwrite_weight_data(op->bias_data, bp);
  693. // write int8_scale data
  694. if (op->int8_scale_term)
  695. {
  696. fwrite_weight_data(op->weight_data_int8_scales, bp);
  697. fwrite_weight_data(op->bottom_blob_int8_scales, bp);
  698. fwrite_weight_data(op->top_blob_int8_scales, bp);
  699. }
  700. }
  701. else if (layer->type == "Crop")
  702. {
  703. ncnn::Crop* op = (ncnn::Crop*)layer;
  704. ncnn::Crop* op_default = (ncnn::Crop*)layer_default;
  705. fprintf_param_value(" 0=%d", woffset)
  706. fprintf_param_value(" 1=%d", hoffset)
  707. fprintf_param_value(" 2=%d", coffset)
  708. fprintf_param_value(" 3=%d", outw)
  709. fprintf_param_value(" 4=%d", outh)
  710. fprintf_param_value(" 5=%d", outc)
  711. fprintf_param_value(" 6=%d", woffset2)
  712. fprintf_param_value(" 7=%d", hoffset2)
  713. fprintf_param_value(" 8=%d", coffset2)
  714. {
  715. if (!op->starts.empty()) fprintf_param_int_array(9, op->starts, pp);
  716. }
  717. {
  718. if (!op->ends.empty()) fprintf_param_int_array(10, op->ends, pp);
  719. }
  720. {
  721. if (!op->axes.empty()) fprintf_param_int_array(11, op->axes, pp);
  722. }
  723. }
  724. else if (layer->type == "Deconvolution")
  725. {
  726. ncnn::Deconvolution* op = (ncnn::Deconvolution*)layer;
  727. ncnn::Deconvolution* op_default = (ncnn::Deconvolution*)layer_default;
  728. fprintf_param_value(" 0=%d", num_output)
  729. fprintf_param_value(" 1=%d", kernel_w)
  730. {
  731. if (op->kernel_h != op->kernel_w) fprintf(pp, " 11=%d", op->kernel_h);
  732. }
  733. fprintf_param_value(" 2=%d", dilation_w)
  734. {
  735. if (op->dilation_h != op->dilation_w) fprintf(pp, " 12=%d", op->dilation_h);
  736. }
  737. fprintf_param_value(" 3=%d", stride_w)
  738. {
  739. if (op->stride_h != op->stride_w) fprintf(pp, " 13=%d", op->stride_h);
  740. }
  741. fprintf_param_value(" 4=%d", pad_left)
  742. {
  743. if (op->pad_top != op->pad_left) fprintf(pp, " 14=%d", op->pad_top);
  744. }
  745. {
  746. if (op->pad_right != op->pad_left) fprintf(pp, " 15=%d", op->pad_right);
  747. }
  748. {
  749. if (op->pad_bottom != op->pad_top) fprintf(pp, " 16=%d", op->pad_bottom);
  750. }
  751. fprintf_param_value(" 5=%d", bias_term)
  752. fprintf_param_value(" 6=%d", weight_data_size)
  753. fprintf_param_value(" 9=%d", activation_type)
  754. {
  755. if (!op->activation_params.empty()) fprintf_param_float_array(10, op->activation_params, pp);
  756. }
  757. fwrite_weight_tag_data(0, op->weight_data, bp);
  758. fwrite_weight_data(op->bias_data, bp);
  759. }
  760. else if (layer->type == "DeconvolutionDepthWise")
  761. {
  762. ncnn::DeconvolutionDepthWise* op = (ncnn::DeconvolutionDepthWise*)layer;
  763. ncnn::DeconvolutionDepthWise* op_default = (ncnn::DeconvolutionDepthWise*)layer_default;
  764. fprintf_param_value(" 0=%d", num_output)
  765. fprintf_param_value(" 1=%d", kernel_w)
  766. {
  767. if (op->kernel_h != op->kernel_w) fprintf(pp, " 11=%d", op->kernel_h);
  768. }
  769. fprintf_param_value(" 2=%d", dilation_w)
  770. {
  771. if (op->dilation_h != op->dilation_w) fprintf(pp, " 12=%d", op->dilation_h);
  772. }
  773. fprintf_param_value(" 3=%d", stride_w)
  774. {
  775. if (op->stride_h != op->stride_w) fprintf(pp, " 13=%d", op->stride_h);
  776. }
  777. fprintf_param_value(" 4=%d", pad_left)
  778. {
  779. if (op->pad_top != op->pad_left) fprintf(pp, " 14=%d", op->pad_top);
  780. }
  781. {
  782. if (op->pad_right != op->pad_left) fprintf(pp, " 15=%d", op->pad_right);
  783. }
  784. {
  785. if (op->pad_bottom != op->pad_top) fprintf(pp, " 16=%d", op->pad_bottom);
  786. }
  787. fprintf_param_value(" 5=%d", bias_term)
  788. fprintf_param_value(" 6=%d", weight_data_size)
  789. fprintf_param_value(" 7=%d", group)
  790. fprintf_param_value(" 9=%d", activation_type)
  791. {
  792. if (!op->activation_params.empty()) fprintf_param_float_array(10, op->activation_params, pp);
  793. }
  794. fwrite_weight_tag_data(0, op->weight_data, bp);
  795. fwrite_weight_data(op->bias_data, bp);
  796. }
  797. else if (layer->type == "DetectionOutput")
  798. {
  799. ncnn::DetectionOutput* op = (ncnn::DetectionOutput*)layer;
  800. ncnn::DetectionOutput* op_default = (ncnn::DetectionOutput*)layer_default;
  801. fprintf_param_value(" 0=%d", num_class)
  802. fprintf_param_value(" 1=%f", nms_threshold)
  803. fprintf_param_value(" 2=%d", nms_top_k)
  804. fprintf_param_value(" 3=%d", keep_top_k)
  805. fprintf_param_value(" 4=%f", confidence_threshold)
  806. fprintf_param_value(" 5=%f", variances[0])
  807. fprintf_param_value(" 6=%f", variances[1])
  808. fprintf_param_value(" 7=%f", variances[2])
  809. fprintf_param_value(" 8=%f", variances[3])
  810. }
  811. else if (layer->type == "Dropout")
  812. {
  813. ncnn::Dropout* op = (ncnn::Dropout*)layer;
  814. ncnn::Dropout* op_default = (ncnn::Dropout*)layer_default;
  815. fprintf_param_value(" 0=%f", scale)
  816. }
  817. else if (layer->type == "Eltwise")
  818. {
  819. ncnn::Eltwise* op = (ncnn::Eltwise*)layer;
  820. ncnn::Eltwise* op_default = (ncnn::Eltwise*)layer_default;
  821. fprintf_param_value(" 0=%d", op_type)
  822. {
  823. if (!op->coeffs.empty()) fprintf_param_float_array(1, op->coeffs, pp);
  824. }
  825. }
  826. else if (layer->type == "ELU")
  827. {
  828. ncnn::ELU* op = (ncnn::ELU*)layer;
  829. ncnn::ELU* op_default = (ncnn::ELU*)layer_default;
  830. fprintf_param_value(" 0=%f", alpha)
  831. }
  832. else if (layer->type == "Exp")
  833. {
  834. ncnn::Exp* op = (ncnn::Exp*)layer;
  835. ncnn::Exp* op_default = (ncnn::Exp*)layer_default;
  836. fprintf_param_value(" 0=%f", base)
  837. fprintf_param_value(" 1=%f", scale)
  838. fprintf_param_value(" 2=%f", shift)
  839. }
  840. else if (layer->type == "InnerProduct")
  841. {
  842. ncnn::InnerProduct* op = (ncnn::InnerProduct*)layer;
  843. ncnn::InnerProduct* op_default = (ncnn::InnerProduct*)layer_default;
  844. fprintf_param_value(" 0=%d", num_output)
  845. fprintf_param_value(" 1=%d", bias_term)
  846. fprintf_param_value(" 2=%d", weight_data_size)
  847. fprintf_param_value(" 8=%d", int8_scale_term)
  848. fprintf_param_value(" 9=%d", activation_type)
  849. {
  850. if (!op->activation_params.empty()) fprintf_param_float_array(10, op->activation_params, pp);
  851. }
  852. fwrite_weight_tag_data(0, op->weight_data, bp);
  853. fwrite_weight_data(op->bias_data, bp);
  854. // write int8_scale data
  855. if (op->int8_scale_term)
  856. {
  857. fwrite_weight_data(op->weight_data_int8_scales, bp);
  858. fwrite_weight_data(op->bottom_blob_int8_scales, bp);
  859. }
  860. }
  861. else if (layer->type == "Input")
  862. {
  863. ncnn::Input* op = (ncnn::Input*)layer;
  864. ncnn::Input* op_default = (ncnn::Input*)layer_default;
  865. fprintf_param_value(" 0=%d", w)
  866. fprintf_param_value(" 1=%d", h)
  867. fprintf_param_value(" 2=%d", c)
  868. }
  869. else if (layer->type == "InstanceNorm")
  870. {
  871. ncnn::InstanceNorm* op = (ncnn::InstanceNorm*)layer;
  872. ncnn::InstanceNorm* op_default = (ncnn::InstanceNorm*)layer_default;
  873. fprintf_param_value(" 0=%d", channels)
  874. fprintf_param_value(" 1=%f", eps)
  875. }
  876. else if (layer->type == "Interp")
  877. {
  878. ncnn::Interp* op = (ncnn::Interp*)layer;
  879. ncnn::Interp* op_default = (ncnn::Interp*)layer_default;
  880. fprintf_param_value(" 0=%d", resize_type)
  881. fprintf_param_value(" 1=%f", height_scale)
  882. fprintf_param_value(" 2=%f", width_scale)
  883. fprintf_param_value(" 3=%d", output_height)
  884. fprintf_param_value(" 4=%d", output_width)
  885. }
  886. else if (layer->type == "Log")
  887. {
  888. ncnn::Log* op = (ncnn::Log*)layer;
  889. ncnn::Log* op_default = (ncnn::Log*)layer_default;
  890. fprintf_param_value(" 0=%f", base)
  891. fprintf_param_value(" 1=%f", scale)
  892. fprintf_param_value(" 2=%f", shift)
  893. }
  894. else if (layer->type == "LRN")
  895. {
  896. ncnn::LRN* op = (ncnn::LRN*)layer;
  897. ncnn::LRN* op_default = (ncnn::LRN*)layer_default;
  898. fprintf_param_value(" 0=%d", region_type)
  899. fprintf_param_value(" 1=%d", local_size)
  900. fprintf_param_value(" 2=%f", alpha)
  901. fprintf_param_value(" 3=%f", beta)
  902. fprintf_param_value(" 4=%f", bias)
  903. }
  904. else if (layer->type == "LSTM")
  905. {
  906. ncnn::LSTM* op = (ncnn::LSTM*)layer;
  907. ncnn::LSTM* op_default = (ncnn::LSTM*)layer_default;
  908. fprintf_param_value(" 0=%d", num_output)
  909. fprintf_param_value(" 1=%d", weight_data_size)
  910. fprintf_param_value(" 2=%d", direction)
  911. fwrite_weight_tag_data(0, op->weight_xc_data, bp);
  912. fwrite_weight_tag_data(0, op->bias_c_data, bp);
  913. fwrite_weight_tag_data(0, op->weight_hc_data, bp);
  914. }
  915. else if (layer->type == "MemoryData")
  916. {
  917. ncnn::MemoryData* op = (ncnn::MemoryData*)layer;
  918. ncnn::MemoryData* op_default = (ncnn::MemoryData*)layer_default;
  919. fprintf_param_value(" 0=%d", w)
  920. fprintf_param_value(" 1=%d", h)
  921. fprintf_param_value(" 2=%d", c)
  922. fwrite_weight_data(op->data, bp);
  923. }
  924. else if (layer->type == "MVN")
  925. {
  926. ncnn::MVN* op = (ncnn::MVN*)layer;
  927. ncnn::MVN* op_default = (ncnn::MVN*)layer_default;
  928. fprintf_param_value(" 0=%d", normalize_variance)
  929. fprintf_param_value(" 1=%d", across_channels)
  930. fprintf_param_value(" 2=%f", eps)
  931. }
  932. else if (layer->type == "Normalize")
  933. {
  934. ncnn::Normalize* op = (ncnn::Normalize*)layer;
  935. ncnn::Normalize* op_default = (ncnn::Normalize*)layer_default;
  936. fprintf_param_value(" 0=%d", across_spatial)
  937. fprintf_param_value(" 1=%d", channel_shared)
  938. fprintf_param_value(" 2=%f", eps)
  939. fprintf_param_value(" 3=%d", scale_data_size)
  940. fprintf_param_value(" 4=%d", across_channel)
  941. fwrite_weight_data(op->scale_data, bp);
  942. }
  943. else if (layer->type == "Padding")
  944. {
  945. ncnn::Padding* op = (ncnn::Padding*)layer;
  946. ncnn::Padding* op_default = (ncnn::Padding*)layer_default;
  947. fprintf_param_value(" 0=%d", top)
  948. fprintf_param_value(" 1=%d", bottom)
  949. fprintf_param_value(" 2=%d", left)
  950. fprintf_param_value(" 3=%d", right)
  951. fprintf_param_value(" 4=%d", type)
  952. fprintf_param_value(" 5=%f", value)
  953. }
  954. else if (layer->type == "Permute")
  955. {
  956. ncnn::Permute* op = (ncnn::Permute*)layer;
  957. ncnn::Permute* op_default = (ncnn::Permute*)layer_default;
  958. fprintf_param_value(" 0=%d", order_type)
  959. }
  960. else if (layer->type == "PixelShuffle")
  961. {
  962. ncnn::PixelShuffle* op = (ncnn::PixelShuffle*)layer;
  963. ncnn::PixelShuffle* op_default = (ncnn::PixelShuffle*)layer_default;
  964. fprintf_param_value(" 0=%d", upscale_factor)
  965. }
  966. else if (layer->type == "Pooling")
  967. {
  968. ncnn::Pooling* op = (ncnn::Pooling*)layer;
  969. ncnn::Pooling* op_default = (ncnn::Pooling*)layer_default;
  970. fprintf_param_value(" 0=%d", pooling_type)
  971. fprintf_param_value(" 1=%d", kernel_w)
  972. {
  973. if (op->kernel_h != op->kernel_w) fprintf(pp, " 11=%d", op->kernel_h);
  974. }
  975. fprintf_param_value(" 2=%d", stride_w)
  976. {
  977. if (op->stride_h != op->stride_w) fprintf(pp, " 12=%d", op->stride_h);
  978. }
  979. fprintf_param_value(" 3=%d", pad_left)
  980. {
  981. if (op->pad_top != op->pad_left) fprintf(pp, " 13=%d", op->pad_top);
  982. }
  983. {
  984. if (op->pad_right != op->pad_left) fprintf(pp, " 14=%d", op->pad_right);
  985. }
  986. {
  987. if (op->pad_bottom != op->pad_top) fprintf(pp, " 15=%d", op->pad_bottom);
  988. }
  989. fprintf_param_value(" 4=%d", global_pooling)
  990. fprintf_param_value(" 5=%d", pad_mode)
  991. fprintf_param_value(" 6=%d", avgpool_count_include_pad)
  992. fprintf_param_value(" 7=%d", adaptive_pooling)
  993. fprintf_param_value(" 8=%d", out_w)
  994. {
  995. if (op->out_h != op->out_w) fprintf(pp, " 18=%d", op->out_h);
  996. }
  997. }
  998. else if (layer->type == "Power")
  999. {
  1000. ncnn::Power* op = (ncnn::Power*)layer;
  1001. ncnn::Power* op_default = (ncnn::Power*)layer_default;
  1002. fprintf_param_value(" 0=%f", power)
  1003. fprintf_param_value(" 1=%f", scale)
  1004. fprintf_param_value(" 2=%f", shift)
  1005. }
  1006. else if (layer->type == "PReLU")
  1007. {
  1008. ncnn::PReLU* op = (ncnn::PReLU*)layer;
  1009. ncnn::PReLU* op_default = (ncnn::PReLU*)layer_default;
  1010. fprintf_param_value(" 0=%d", num_slope)
  1011. fwrite_weight_data(op->slope_data, bp);
  1012. }
  1013. else if (layer->type == "PriorBox")
  1014. {
  1015. ncnn::PriorBox* op = (ncnn::PriorBox*)layer;
  1016. ncnn::PriorBox* op_default = (ncnn::PriorBox*)layer_default;
  1017. {
  1018. if (!op->min_sizes.empty()) fprintf_param_float_array(0, op->min_sizes, pp);
  1019. }
  1020. {
  1021. if (!op->max_sizes.empty()) fprintf_param_float_array(1, op->max_sizes, pp);
  1022. }
  1023. {
  1024. if (!op->aspect_ratios.empty()) fprintf_param_float_array(2, op->aspect_ratios, pp);
  1025. }
  1026. fprintf_param_value(" 3=%f", variances[0])
  1027. fprintf_param_value(" 4=%f", variances[1])
  1028. fprintf_param_value(" 5=%f", variances[2])
  1029. fprintf_param_value(" 6=%f", variances[3])
  1030. fprintf_param_value(" 7=%d", flip)
  1031. fprintf_param_value(" 8=%d", clip)
  1032. fprintf_param_value(" 9=%d", image_width)
  1033. fprintf_param_value(" 10=%d", image_height)
  1034. fprintf_param_value(" 11=%f", step_width)
  1035. fprintf_param_value(" 12=%f", step_height)
  1036. fprintf_param_value(" 13=%f", offset)
  1037. }
  1038. else if (layer->type == "Proposal")
  1039. {
  1040. ncnn::Proposal* op = (ncnn::Proposal*)layer;
  1041. ncnn::Proposal* op_default = (ncnn::Proposal*)layer_default;
  1042. fprintf_param_value(" 0=%d", feat_stride)
  1043. fprintf_param_value(" 1=%d", base_size)
  1044. fprintf_param_value(" 2=%d", pre_nms_topN)
  1045. fprintf_param_value(" 3=%d", after_nms_topN)
  1046. fprintf_param_value(" 4=%f", nms_thresh)
  1047. fprintf_param_value(" 5=%d", min_size)
  1048. }
  1049. else if (layer->type == "PSROIPooling")
  1050. {
  1051. ncnn::PSROIPooling* op = (ncnn::PSROIPooling*)layer;
  1052. ncnn::PSROIPooling* op_default = (ncnn::PSROIPooling*)layer_default;
  1053. fprintf_param_value(" 0=%d", pooled_width)
  1054. fprintf_param_value(" 1=%d", pooled_height)
  1055. fprintf_param_value(" 2=%f", spatial_scale)
  1056. fprintf_param_value(" 3=%d", output_dim)
  1057. }
  1058. else if (layer->type == "Quantize")
  1059. {
  1060. ncnn::Quantize* op = (ncnn::Quantize*)layer;
  1061. ncnn::Quantize* op_default = (ncnn::Quantize*)layer_default;
  1062. fprintf_param_value(" 0=%d", scale_data_size)
  1063. fwrite_weight_data(op->scale_data, bp);
  1064. }
  1065. else if (layer->type == "Reduction")
  1066. {
  1067. ncnn::Reduction* op = (ncnn::Reduction*)layer;
  1068. ncnn::Reduction* op_default = (ncnn::Reduction*)layer_default;
  1069. fprintf_param_value(" 0=%d", operation)
  1070. fprintf_param_value(" 1=%d", reduce_all)
  1071. fprintf_param_value(" 2=%f", coeff)
  1072. {
  1073. if (!op->axes.empty()) fprintf_param_int_array(3, op->axes, pp);
  1074. }
  1075. fprintf_param_value(" 4=%d", keepdims)
  1076. }
  1077. else if (layer->type == "ReLU")
  1078. {
  1079. ncnn::ReLU* op = (ncnn::ReLU*)layer;
  1080. ncnn::ReLU* op_default = (ncnn::ReLU*)layer_default;
  1081. fprintf_param_value(" 0=%f", slope)
  1082. }
  1083. else if (layer->type == "Reorg")
  1084. {
  1085. ncnn::Reorg* op = (ncnn::Reorg*)layer;
  1086. ncnn::Reorg* op_default = (ncnn::Reorg*)layer_default;
  1087. fprintf_param_value(" 0=%d", stride)
  1088. }
  1089. else if (layer->type == "Requantize")
  1090. {
  1091. ncnn::Requantize* op = (ncnn::Requantize*)layer;
  1092. ncnn::Requantize* op_default = (ncnn::Requantize*)layer_default;
  1093. fprintf_param_value(" 0=%d", scale_in_data_size)
  1094. fprintf_param_value(" 1=%d", scale_out_data_size)
  1095. fprintf_param_value(" 2=%d", bias_data_size)
  1096. fprintf_param_value(" 3=%d", activation_type)
  1097. {
  1098. if (!op->activation_params.empty()) fprintf_param_float_array(4, op->activation_params, pp);
  1099. }
  1100. fwrite_weight_data(op->scale_in_data, bp);
  1101. fwrite_weight_data(op->scale_out_data, bp);
  1102. fwrite_weight_data(op->bias_data, bp);
  1103. }
  1104. else if (layer->type == "Reshape")
  1105. {
  1106. ncnn::Reshape* op = (ncnn::Reshape*)layer;
  1107. ncnn::Reshape* op_default = (ncnn::Reshape*)layer_default;
  1108. fprintf_param_value(" 0=%d", w)
  1109. fprintf_param_value(" 1=%d", h)
  1110. fprintf_param_value(" 2=%d", c)
  1111. fprintf_param_value(" 3=%d", permute)
  1112. }
  1113. else if (layer->type == "ROIAlign")
  1114. {
  1115. ncnn::ROIAlign* op = (ncnn::ROIAlign*)layer;
  1116. ncnn::ROIAlign* op_default = (ncnn::ROIAlign*)layer_default;
  1117. fprintf_param_value(" 0=%d", pooled_width)
  1118. fprintf_param_value(" 1=%d", pooled_height)
  1119. fprintf_param_value(" 2=%f", spatial_scale)
  1120. fprintf_param_value(" 3=%d", sampling_ratio)
  1121. fprintf_param_value(" 4=%d", aligned)
  1122. fprintf_param_value(" 5=%d", version)
  1123. }
  1124. else if (layer->type == "ROIPooling")
  1125. {
  1126. ncnn::ROIPooling* op = (ncnn::ROIPooling*)layer;
  1127. ncnn::ROIPooling* op_default = (ncnn::ROIPooling*)layer_default;
  1128. fprintf_param_value(" 0=%d", pooled_width)
  1129. fprintf_param_value(" 1=%d", pooled_height)
  1130. fprintf_param_value(" 2=%f", spatial_scale)
  1131. }
  1132. else if (layer->type == "Scale")
  1133. {
  1134. ncnn::Scale* op = (ncnn::Scale*)layer;
  1135. ncnn::Scale* op_default = (ncnn::Scale*)layer_default;
  1136. fprintf_param_value(" 0=%d", scale_data_size)
  1137. fprintf_param_value(" 1=%d", bias_term)
  1138. fwrite_weight_data(op->scale_data, bp);
  1139. fwrite_weight_data(op->bias_data, bp);
  1140. }
  1141. else if (layer->type == "ShuffleChannel")
  1142. {
  1143. ncnn::ShuffleChannel* op = (ncnn::ShuffleChannel*)layer;
  1144. ncnn::ShuffleChannel* op_default = (ncnn::ShuffleChannel*)layer_default;
  1145. fprintf_param_value(" 0=%d", group)
  1146. }
  1147. else if (layer->type == "Slice")
  1148. {
  1149. ncnn::Slice* op = (ncnn::Slice*)layer;
  1150. ncnn::Slice* op_default = (ncnn::Slice*)layer_default;
  1151. {
  1152. if (!op->slices.empty()) fprintf_param_int_array(0, op->slices, pp);
  1153. }
  1154. fprintf_param_value(" 1=%d", axis)
  1155. }
  1156. else if (layer->type == "Softmax")
  1157. {
  1158. ncnn::Softmax* op = (ncnn::Softmax*)layer;
  1159. ncnn::Softmax* op_default = (ncnn::Softmax*)layer_default;
  1160. fprintf_param_value(" 0=%d", axis)
  1161. // HACK
  1162. if (op->axis != 0)
  1163. {
  1164. int fixbug0 = 1;
  1165. fprintf(pp, " 1=%d", fixbug0);
  1166. }
  1167. }
  1168. else if (layer->type == "Threshold")
  1169. {
  1170. ncnn::Threshold* op = (ncnn::Threshold*)layer;
  1171. ncnn::Threshold* op_default = (ncnn::Threshold*)layer_default;
  1172. fprintf_param_value(" 0=%f", threshold)
  1173. }
  1174. else if (layer->type == "UnaryOp")
  1175. {
  1176. ncnn::UnaryOp* op = (ncnn::UnaryOp*)layer;
  1177. ncnn::UnaryOp* op_default = (ncnn::UnaryOp*)layer_default;
  1178. fprintf_param_value(" 0=%d", op_type)
  1179. }
  1180. else if (layer->type == "YoloDetectionOutput")
  1181. {
  1182. ncnn::YoloDetectionOutput* op = (ncnn::YoloDetectionOutput*)layer;
  1183. ncnn::YoloDetectionOutput* op_default = (ncnn::YoloDetectionOutput*)layer_default;
  1184. fprintf_param_value(" 0=%d", num_class)
  1185. fprintf_param_value(" 1=%d", num_box)
  1186. fprintf_param_value(" 2=%f", confidence_threshold)
  1187. fprintf_param_value(" 3=%f", nms_threshold)
  1188. {
  1189. if (!op->biases.empty()) fprintf_param_float_array(4, op->biases, pp);
  1190. }
  1191. }
  1192. else if (layer->type == "Yolov3DetectionOutput")
  1193. {
  1194. ncnn::Yolov3DetectionOutput* op = (ncnn::Yolov3DetectionOutput*)layer;
  1195. ncnn::Yolov3DetectionOutput* op_default = (ncnn::Yolov3DetectionOutput*)layer_default;
  1196. fprintf_param_value(" 0=%d", num_class)
  1197. fprintf_param_value(" 1=%d", num_box)
  1198. fprintf_param_value(" 2=%f", confidence_threshold)
  1199. fprintf_param_value(" 3=%f", nms_threshold)
  1200. {
  1201. if (!op->biases.empty()) fprintf_param_float_array(4, op->biases, pp);
  1202. }
  1203. {
  1204. if (!op->mask.empty()) fprintf_param_int_array(5, op->mask, pp);
  1205. }
  1206. {
  1207. if (!op->anchors_scale.empty()) fprintf_param_float_array(6, op->anchors_scale, pp);
  1208. }
  1209. }
  1210. #undef fprintf_param_value
  1211. fprintf(pp, "\n");
  1212. delete layer_default;
  1213. }
  1214. fclose(pp);
  1215. fclose(bp);
  1216. return 0;
  1217. }
  1218. int main(int argc, char** argv)
  1219. {
  1220. if (argc != 6)
  1221. {
  1222. fprintf(stderr, "usage: %s [inparam] [inbin] [outparam] [outbin] [calibration table]\n", argv[0]);
  1223. return -1;
  1224. }
  1225. const char* inparam = argv[1];
  1226. const char* inbin = argv[2];
  1227. const char* outparam = argv[3];
  1228. const char* outbin = argv[4];
  1229. const char* int8scale_table_path = argv[5];
  1230. NetQuantize quantizer;
  1231. // parse the calibration scale table
  1232. if (int8scale_table_path)
  1233. {
  1234. bool s2 = read_int8scale_table(int8scale_table_path, quantizer.blob_int8scale_table, quantizer.weight_int8scale_table);
  1235. if (!s2)
  1236. {
  1237. fprintf(stderr, "read_int8scale_table failed\n");
  1238. return -1;
  1239. }
  1240. }
  1241. quantizer.load_param(inparam);
  1242. if (strcmp(inbin, "null") == 0)
  1243. {
  1244. DataReaderFromEmpty dr;
  1245. quantizer.load_model(dr);
  1246. }
  1247. else
  1248. quantizer.load_model(inbin);
  1249. quantizer.quantize_convolution();
  1250. quantizer.quantize_convolutiondepthwise();
  1251. quantizer.quantize_innerproduct();
  1252. quantizer.fuse_requantize();
  1253. quantizer.save(outparam, outbin);
  1254. return 0;
  1255. }