NCNN(2)--网络结构文件.param解析

本文详细介绍LeNet模型结构,包括输入层、卷积层、池化层、全连接层及激活函数,展示了从Caffe到ncnn的转换过程,解析了ncnn参数文件的每一部分,适合深度学习初学者理解经典模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeNet模型为例

由Caffe的lenet_deploy.prototxt文件转换得到

name: "LeNet"
layer {
  name: "data"
  type: "Input"
  top: "data"
  input_param { shape: { dim: 1 dim: 1 dim: 28 dim: 28 } }
}
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 20
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 50
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "ip1"
  type: "InnerProduct"
  bottom: "pool2"
  top: "ip1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 500
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "ip1"
  top: "ip1"
}
layer {
  name: "ip2"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "prob"
  type: "Softmax"
  bottom: "ip2"
  top: "prob"
}

param文件:

7767517
9 9
Input            data             0 1 data 0=28 1=28 2=1
Convolution      conv1            1 1 data conv1 0=20 1=5 2=1 3=1 4=0 5=1 6=500
Pooling          pool1            1 1 conv1 pool1 0=0 1=2 2=2 3=0 4=0
Convolution      conv2            1 1 pool1 conv2 0=50 1=5 2=1 3=1 4=0 5=1 6=25000
Pooling          pool2            1 1 conv2 pool2 0=0 1=2 2=2 3=0 4=0
InnerProduct     ip1              1 1 pool2 ip1 0=500 1=1 2=400000
ReLU             relu1            1 1 ip1 ip1_relu1
InnerProduct     ip2              1 1 ip1_relu1 ip2 0=10 1=1 2=5000
Softmax          prob             1 1 ip2 prob 0=0

第一行:版本信息
数值为此param文件的版本
ncnn相关源码说明:

int magic = 0; 
fscanf(fp, "%d", &magic); 
if (magic != 7767517) 
{ 
	fprintf(stderr, "param is too old, please regenerate\n"); 
	return -1; 
} 

第二行:层与数据交换结构数量
第一个数字:层(layer)的数量
第二个数字:数据交换结构(blob)的数量
ncnn相关源码说明:

// parse 
int layer_count = 0; 
int blob_count = 0; 
fscanf(fp, "%d %d", &layer_count, &blob_count);

第三行及以下:相关层的具体信息
input层比较特殊一点
前4个值的含义固定:
(1)层类型
(2)层名称
(3)输入数据结构数量(bottom blob)
(4)输出数据结构数量(top blob)
后面跟有三个不同类型的值,严格按照顺序排序

(1) 网络输入层名(一个层可能有多个输入,则有多个网络输入层名)
(2) 网络输出层名(一个层可能有多个输出,则有多个网络输出层名)
(3)特殊参数(可能没有): 一种是k=v的类型;另一种是k=len,v1,v2,v3….(数组类型)。该层在ncnn中是存放到paramDict结构中,不同类型层,各种参数意义不一样。

以第一个卷积层为例

层类型:Convolution
层名称:conv1
输入数据结构数量:1
输出数据结构数量(top blob):1
网络输入层名:data
网络输出层名:conv1
特殊参数1:0=20,num_output: 20
特殊参数2:1=5,kernel_size: 5
特殊参数3:2=1,stride: 1
特殊参数4:3=1
特殊参数5:4=0
特殊参数6:5=1
特殊参数7:6=500,该层的参数量,5*5*1*20=500

### 关于 nihui 开发的 ncnn-android-yolov5 项目 nihui 的 `ncnn-android-yolov5` 是一个基于 NCNN 推理框架的 Android 平台上的目标检测示例项目[^1]。该项目实现了 YOLOv5 模型在移动设备上的部署,旨在提供一种简单而高效的方式来展示如何将深度学习模型应用于实际场景。 以下是关于此项目的详细介绍: #### 1. **项目概述** 该 GitHub 仓库提供了完整的源码以及详细的文档说明,帮助开发者快速理解并集成 YOLOv5 到他们的 Android 应用程序中。通过使用 NCNN 这一高性能推理库,项目能够显著提升移动端的目标检测速度和效率。 #### 2. **主要功能模块** - **YOLOv5 模型支持**: 支持多种版本的 YOLOv5 模型加载与预测。 - **NCNN 后端加速**: 借助腾讯开源的 NCNN 深度学习推理框架完成模型计算操作。 - **跨平台兼容性**: 提供针对 ARM 架构进行了高度优化后的二进制文件以便适配大多数安卓手机硬件条件。 #### 3. **开发环境准备** 为了成功编译运行本项目, 用户需具备如下软硬件配置: - 安装最新版 Android Studio 及其配套 NDK 工具链. - 下载对应 ABI 版本 (armeabi-v7a 或 arm64-v8a) 的预训练权重参数. 具体设置流程可以参照官方给出的相关指导链接或者查阅其他相似案例资料来补充完善个人工作区布局结构[^3]. #### 4. **核心代码解析** 下面是一段典型的 C++ JNI 函数定义片段用于处理来自 Java 层面调用请求: ```cpp extern "C" JNIEXPORT void JNICALL Java_com_example_ncnn_1android_1yolov5_MainActivity_detect(JNIEnv *env, jobject thiz, jlong matAddrRgba) { cv::Mat &rgba = *(cv::Mat *)matAddrRgba; // Convert image to BGR format required by model input cv::cvtColor(rgba, bgr, CV_RGBA2BGR); // Initialize net once per thread static ncnn::Net yolov5; if (!yolov5.loaded()) { yolov5.load_param("yolov5s.param"); yolov5.load_model("yolov5s.bin"); } ncnn::Extractor ex = yolov5.create_extractor(); ex.set_num_threads(4); const float mean_vals[3] = {0.f, 0.f, 0.f}; const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; ncnn::Mat in = ncnn::Mat::from_pixels_resize( bgr.data, ncnn::Mat::PIXEL_BGR, bgr.cols, bgr.rows, INPUT_WIDTH, INPUT_HEIGHT); in.substract_mean_normalize(mean_vals, norm_vals); ex.input("images", in); std::vector<Object> objects; detect_yolo(ex, objects); } ``` 上述代码展示了如何利用 OpenCV 将原始图片转换成适合输入给定神经网络的形式,并最终提取特征向量传递至后续逻辑单元继续加工分析过程. #### 5. **常见问题解答** 如果遇到某些特定错误提示比如找不到 so 动态库路径等问题,则可能是因为未正确指定本地依赖项位置关系所致;此时建议重新审视 build.gradle 文件中的 externalNativeBuild 节点内容是否匹配当前系统的实际情况调整相应字段值即可解决此类状况[^5]. ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值