---
title: VGG16
canonical_url: "https://www.modelscope.cn/models/AIBSECO/VGG16"
md_url: "https://www.modelscope.cn/models/AIBSECO/VGG16.md"
repository: AIBSECO/VGG16
last_updated: 2025-11-19
pipeline_tag: image-classification
tasks:
  - image-classification
downloads: 2
stars: 0
---

# VGG16

> VGG16 - AIBSECO 在 ModelScope 开源的模型。| item | status | detail | | --------------------------------------- | ------ | ------ | | 方案选择与硬件资源划分 | 1 | | 模型导出 | 1 | | | 导出模型精度一致，提供python验证脚本 | 1 | | cpu处理部分c++工程移植 | 1 | | c++工程精度一致，提供验证脚本 | 1 | | c++工程性能优化 | 0 | |…

- **Repository**: AIBSECO/VGG16
- **Tasks**: image-classification
- **Downloads**: 2
- **Stars**: 0
- **Last updated**: 2025-11-19

Source: https://www.modelscope.cn/models/AIBSECO/VGG16

---

# 方案名

## 1. 摘要

1. 身份编号：fwb0042


2. 类型与序号：VGG16 方案1


3. 进展：

    | item                                    | status | detail |
    | --------------------------------------- | ------ | ------ |
    | 方案选择与硬件资源划分                  | 1      |
    | 模型导出                                | 1      |        |
    | ~导出模型精度一致，提供python验证脚本   | 1      |
    | cpu处理部分c++工程移植                  | 1      |
    | ~c++工程精度一致，提供验证脚本          | 1      |
    | ~c++工程性能优化                        | 0      |
    | icraft编译通过                          | 1      |
    | ~存在量化精度调优工作                   | 0      |
    | ~完成基本pyrtcrt搭建与结果验证          | 0      |
    | ~完成pyrtcrt精度测试与对齐              | 0      |
    | 完成上板耗时测试                        | 0      |
    | ~使用运行时提供的api进行基本性能优化    | 0      |
    | ~存在整体方案各环节优化或优化方案的设计 | 0      |
    | 提出bug数                               | 0      |


## 2. 方案简介

### 2.1  算法流程介绍

#### 模型或算法背景：
    

- VGGNet (Visual Geometry Group Network) 是一系列深度卷积神经网络，由牛津大学的视觉几何组提出。VGG16是其中最著名和最广泛使用的版本。
- 源仓库链接：VGGNet没有唯一的官方开源仓库，但其实现在各大深度学习框架（Caffe, TensorFlow, PyTorch等）中均已成为标准。
- 开发团队：牛津大学视觉几何组 (Karen Simonyan & Andrew Zisserman)
- 发布时间：2014年 (发表于ICLR 2015 Workshop)
- 性能水平：VGGNet在2014年的ImageNet大规模视觉识别挑战赛（ILSVRC）中取得了定位任务第一名和分类任务第二名的优异成绩。其核心贡献在于证明了**通过简单、一致地堆叠更小的卷积核（3x3）来增加网络深度，是提升模型性能的有效途径**。这一“深度为王”的设计哲学，深刻影响了后续所有深度学习网络的设计，如ResNet、Inception等。


VGG系列模型在ImageNet验证集上的性能：

| Model     | Depth  | Parameters (M) |   Top-1 Accuracy    |   Top-5 Accuracy    |
| :-------- | :----: | :------------: | :-----------------: | :-----------------: |
| VGG11     |   11   |      133       |       69.02%        |       88.63%        |
| **VGG16** | **16** |    **138**     |     **71.59%**      |     **90.38%**      |
| VGG19     |   19   |      144       |       72.38%        |       90.87%        |
| GoogLeNet |   22   |      6.8       | 68.7% (Single-crop) | 89.9% (Single-crop) |

*注：VGG的精度是在多尺度、多裁剪测试下取得的，这里为了对比，也列出了单裁剪下的精度。VGG的参数量主要集中在全连接层。*


#### 算法流程梳理
VGG16的结构极其规整、优雅和统一，完全由重复的、简单的构建块组成。其名称中的“16”代表网络中包含16个带权重的层（13个卷积层和3个全连接层）。

数据输入 ——> **Conv Block 1** ——> Pool ——> **Conv Block 2** ——> Pool ——> **Conv Block 3** ——> Pool ——> **Conv Block 4** ——> Pool ——> **Conv Block 5** ——> Pool ——> **FC Layers** ——> Softmax

<img src="./assets/VGG16_struct.png" alt="VGG16模型结构" style="zoom: 80%;" />

VGG16的架构可以清晰地分为两个部分：

**1. 卷积基 (Convolutional Base):**
- **统一的卷积核**：整个网络**只使用3x3大小的卷积核**。这是VGG最核心的设计思想。作者们论证了两个堆叠的3x3卷积层拥有与一个5x5卷积层相同的感受野，而三个堆叠的3x3卷积层则等效于一个7x7卷积层的感受野。使用更小的卷积核堆叠，有两大好处：
    1.  **引入更多非线性**：更多的层数意味着更多的ReLU激活函数，这能增强网络的表达能力。
    2.  **减少参数量**：例如，三个3x3卷积层的参数量（3 * (3*3*C*C) = 27*C^2）远小于一个7x7卷积层的参数量（7*7*C*C = 49*C^2），其中C是通道数。
- **规整的模块化设计**：卷积基由5个卷积块（Conv Block）组成。每个块包含2到3个连续的3x3卷积层，其后紧跟一个2x2的最大池化层（Max Pooling）用于下采样。
- **通道数变化**：随着网络的加深，特征图的尺寸（H, W）通过池化层减半，而通道数（C）则逐块翻倍（64 -> 128 -> 256 -> 512 -> 512），这是一种非常经典的设计模式。

**2. 分类器 (Classifier):**
- **全连接层 (Fully Connected Layers)**：在卷积基之后，特征图被展平（Flatten）为一个长向量，然后送入三个全连接层。前两个全连接层各有4096个神经元，最后一个全连接层的神经元数量为1000，对应ImageNet的1000个类别。
- **巨大的参数量**：VGG16的绝大部分参数（约1.2亿，占总参数量1.38亿的90%）都集中在这三个庞大的全连接层中，这也是其后续被优化的主要方向。

基本组件：
**3x3卷积层**：网络中唯一的卷积操作单元，证明了“小而深”的有效性。
**ReLU激活函数**：在每个卷积层后使用，引入非线性。
**2x2最大池化层**：用于下采样，缩小特征图尺寸。
**全连接层**：用于最终的分类决策。

### 训练技巧

***数据集***
- 模型在 **ImageNet (ILSVRC 2012)** 数据集上进行训练，该数据集是评估大规模图像分类模型性能的基准。

***训练设置***
- **优化器与学习率**：采用带动量的随机梯度下降（SGD）进行优化。学习率初始值较小，并在验证集准确率不再提升时手动进行衰减。
- **权重初始化**：采用了精心设计的随机初始化方法（后来被称为“Xavier/Glorot初始化”），这对于成功训练深层网络至关重要。
- **分阶段训练**：作者们首先训练了一个较浅的网络（如VGG11），然后用其权重来初始化更深网络的对应层，再继续训练。这种方法有助于深层网络的收敛。

### 前后处理

**前处理：**
1.  **图像缩放**：
    - 将输入图像的短边等比例缩放到一个固定尺寸S（称为训练尺度）。
2.  **随机裁剪**：
    - 在训练时，从缩放后的图像中随机裁剪出224x224大小的区域作为模型输入。这是一种有效的数据增强。
3.  **随机水平翻转**：
    - 以50%的概率对裁剪出的图像进行水平翻转。
4.  **均值减法**：
    - 从每个像素的RGB值中减去在整个训练集上计算出的RGB均值。

**后处理 (测试时)：**
1.  **多尺度/多裁剪测试 (Multi-scale/Multi-crop Testing)**：
    - 为了获得更高的精度，VGG在测试时采用了非常耗时的评估策略。它会将图像缩放到多个不同的尺度S，并在每个尺度上，从图像的四个角和中心，以及它们的水平翻转版本中，裁剪出多个224x224的图像块。
2.  **结果平均**：
    - 将所有这些裁剪块送入网络得到各自的预测概率，然后将这些概率向量进行平均，得到最终的分类结果。



### 2.2  硬件资源分配

plin模式：摄像头输入数据直接传给pl部分

 前处理：fpga，做在数据流上

 网络主体：npu

 后处理等：cpu

 可视化：cpu


## 4. 模型导出说明

  直接运行1_save.py导出整个模型即可
  


## 5. cpu处理部分c++工程移植说明

CPU部分主要实现了图片的读取，前处理尺寸变换和后处理的Softmax激活和获取预测结果功能
```CPP
   // 统计图片数量
    int index = 0;
    auto namevector = toVector(imgList);
    int totalnum = namevector.size();
    for (auto name : namevector) {
        progress(index, totalnum);
        index++;
        //-------------PRE PROCESS-----------------------//
        std::string img_path = imgRoot + '/' + name;
        PicPre img(img_path, cv::IMREAD_COLOR);
        img.Resize(resize_hw, PicPre::SHORT_SIDE).rCenterCrop(crop_hw);
        Tensor img_tensor = CvMat2Tensor(img.dst_img, network);
        dmaInit(run_sim, netinfo.ImageMake_on, img_tensor, device);
        auto output_tensors = session.forward({ img_tensor});
        if (!run_sim) device.reset(1);
        // 计时
        #ifdef __linux__
        device.reset(1);
        calctime_detail(session);
        #endif

        auto host_tensor_class = output_tensors[0].to(HostDevice::MemRegion());
        auto outputs_class = (float*)host_tensor_class.data().cptr();
        auto softmax_class = softmax(outputs_class, 1, 0, N_CLASS);
        // auto softmax_class = softmax(outputs_class,  0, output_tensors[0].dtype()->shape);
        auto topk_res = topK(softmax_class, 5);//save top-5 res 
        for (int i = 0; i < 5; i++) {
            auto c = topk_res[i].first;
            auto prob = topk_res[i].second;
            std::ostringstream text;
            text << LABELS[c] << " : " << std::fixed << std::setprecision(6) << prob;
            cv::putText(img.ori_img, text.str(), cv::Point2f(10, 20 + i * 15), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(128, 0, 0), 2);
        }
        #ifdef _WIN32
        if (show) {
            cv::imshow("results", img.ori_img);
            cv::waitKey(0);
        }
        if (save) {
            //save top-5 label in txt
            auto res_path = resRoot + "//" + name;
            std::regex reg(R"(\.(\w*)$)");
            res_path = std::regex_replace(res_path, reg, ".txt");
            std::ofstream outputFile(res_path);
            if (!outputFile.is_open()) {
                std::cout << "Create txt file fail." << std::endl;
            }
            for (auto&& res : topk_res) {
                outputFile << res.first << std::endl;
            }
            outputFile.close();
        }
        #elif __linux__
        if (save) {
            //saveRes
            std::regex rgx("\\.(?!.*\\.)"); // 匹配最后一个点号（.）之前的位置，且该点号后面没有其他点号
            std::string RES_NAME = std::regex_replace(name, rgx, "_result.");
            cv::imwrite(resRoot + RES_NAME, img.ori_img);
        }
        #endif

    }
    //关闭设备
    if (!run_sim) Device::Close(device);
    return 0;
```

## 6. ICRAFT编译

---

**编译通过**

- 16bit下推理测试结果：
  | 框架动态图推理                           | 导出静态模型推理                          | 解析组件仿真                       | 量化组件仿真                       | 指令组件仿真                       |
  | ---------------------------------------- | ----------------------------------------- | ---------------------------------- | ---------------------------------- | ---------------------------------- |
  | ![alt text](./assets/output_pytorch.jpg) | ![alt text](./assets/output_pytorch2.jpg) | ![alt text](./assets/output_p.png) | ![alt text](./assets/output_q.png) | ![alt text](./assets/output_g.png) |
  

- 8bit，16bit，混合精度的精度测试结果:
  
- 8bit测试结果:
  
        top1: 65.74%
        top5: 90.02%
- 16bit测试结果:
  
        top1: 66.32000000000001%
        top5: 90.08%


## 7. 上板测试与优化(尚未进行上版测试)

1. 优化前各环节耗时统计

2. 优化后耗时统计(表格)

3. 优化项与效果

    分条描述做了哪些性能优化，提升了多少

4. 运行时工程的整体介绍（最好带流程图）
