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.

add-custom-layer.zh.md 2.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. 这里举个例子添加 Relu6,即 std::min(6, std::max(0, val))
  2. ```
  3. Input input 0 1 input
  4. Convolution conv2d 1 1 input conv2d 0=32 1=1 2=1 3=1 4=0 5=0 6=768
  5. Relu6 relu6 1 1 conv2d relu6
  6. Pooling maxpool 1 1 relu6 maxpool 0=0 1=3 2=2 3=-233 4=0
  7. ```
  8. ## method 1 -- 注册自定义层
  9. ```cpp
  10. #include "layer.h"
  11. class Relu6 : public ncnn::Layer
  12. {
  13. public:
  14. Relu6()
  15. {
  16. one_blob_only = true;
  17. support_inplace = true;
  18. }
  19. virtual int forward_inplace(Mat& bottom_top_blob, const Option& opt) const
  20. {
  21. int w = bottom_top_blob.w;
  22. int h = bottom_top_blob.h;
  23. int channels = bottom_top_blob.c;
  24. int size = w * h;
  25. #pragma omp parallel for num_threads(opt.num_threads)
  26. for (int q=0; q<channels; q++)
  27. {
  28. float* outptr = bottom_top_blob.channel(q);
  29. for (int i=0; i<size; i++)
  30. {
  31. outptr[i] = std::min(6, std::max(0, outptr[i]));
  32. }
  33. }
  34. return 0;
  35. }
  36. };
  37. DEFINE_LAYER_CREATOR(Relu6)
  38. ```
  39. ```cpp
  40. ncnn::Net net;
  41. net.register_custom_layer("Relu6", Relu6_layer_creator);
  42. net.load_param("model.param");
  43. net.load_model("model.bin");
  44. ncnn::Extractor ex = net.create_extractor();
  45. ex.input("input", inputmat);
  46. ex.extract("maxpool", maxpoolmat);
  47. ```
  48. ## method 2 -- 处理中间 blob
  49. ```cpp
  50. ncnn::Net net;
  51. net.load_param("model.param");
  52. net.load_model("model.bin");
  53. ncnn::Extractor ex = net.create_extractor();
  54. ex.input("input", inputmat);
  55. ex.extract("conv2d", conv2dmat);
  56. // relu6
  57. ncnn::Mat relu6mat = conv2dmat.clone();
  58. {
  59. int w = relu6mat.w;
  60. int h = relu6mat.h;
  61. int channels = relu6mat.c;
  62. int size = w * h;
  63. #pragma omp parallel for
  64. for (int q=0; q<channels; q++)
  65. {
  66. float* outptr = relu6mat.channel(q);
  67. for (int i=0; i<size; i++)
  68. {
  69. outptr[i] = std::min(6, std::max(0, outptr[i]));
  70. }
  71. }
  72. }
  73. ex.input("relu6", relu6mat);
  74. ex.extract("maxpool", maxpoolmat);
  75. ```
  76. ## method 3 -- 直接修改 ncnn
  77. 实现 src/layer/relu6.h
  78. 实现 src/layer/relu6.cpp
  79. 修改 src/CMakeLists.txt
  80. ```cmake
  81. ncnn_add_layer(UnaryOp)
  82. ncnn_add_layer(ConvolutionDepthWise)
  83. ncnn_add_layer(Padding)
  84. ncnn_add_layer(Relu6)
  85. ```