美文网首页
FPGA部署卷积神经网络之量化 Caffe restretto

FPGA部署卷积神经网络之量化 Caffe restretto

作者: 鹏宝阿加西 | 来源:发表于2018-10-16 18:05 被阅读0次

    Caffe restretto 动态量化

    主要记录下DYNAMIC_FIXED_POINT模式下对Lenet5的量化过程。

    参考 https://blog.csdn.net/xiaoxiaowenqiang/article/details/81713131
    ①.输入数据为test_data,在不同batch的数据下,推理iteration遍,得出网络运行在FLOAT32下的基本精度。

      // Run the reference floating point network on validation set to find baseline
      // accuracy.
      Net<float>* net_val = new Net<float>(model_, caffe::TEST);
      net_val->CopyTrainedLayersFrom(weights_);
      float accuracy;
      RunForwardBatches(this->iterations_, net_val, &accuracy);       //this->iterations在运行时输入
      test_score_baseline_ = accuracy;
    

    ②.输入数据为train_data, 网络在不同batch的数据下推理10遍,得出网络中层类型为ConvolutionInnerProducttop blobbottom blobweight_param中数据的最大绝对值,其中权重数据不包括bias

    void Net<Dtype>::RangeInLayers(vector<string>* layer_name,
          vector<Dtype>* max_in, vector<Dtype>* max_out, vector<Dtype>* max_param) {
      // Initialize vector elements, if needed.
      if(layer_name->size()==0) {
        for (int layer_id = 0; layer_id < layers_.size(); ++layer_id) {
          if (strcmp(layers_[layer_id]->type(), "Convolution") == 0 ||
              strcmp(layers_[layer_id]->type(), "InnerProduct") == 0) {
            layer_name->push_back(this->layer_names()[layer_id]);
            max_in->push_back(0);
            max_out->push_back(0);
            max_param->push_back(0);
          }
        }
      }
      // Find maximal values.
      int index = 0;
      Dtype max_val;
      for (int layer_id = 0; layer_id < layers_.size(); ++layer_id) {
        if (strcmp(layers_[layer_id]->type(), "Convolution") == 0 ||
              strcmp(layers_[layer_id]->type(), "InnerProduct") == 0) {
          max_val = findMax(bottom_vecs_[layer_id][0]);
          max_in->at(index) = std::max(max_in->at(index), max_val);
          max_val = findMax(top_vecs_[layer_id][0]);
          max_out->at(index) = std::max(max_out->at(index), max_val);
          // Consider the weights only, ignore the bias
          max_val = findMax(&(*layers_[layer_id]->blobs()[0]));
          max_param->at(index) = std::max(max_param->at(index), max_val);
          index++;
        }
      }
    }
    

    下面列出第一次推理和推理十次后,统计的各个blob中的数据最大绝对值

    推理一次

    Tables max_in max_out max_params
    Conv1 0.99609375 3.49374723 0.612441599
    Conv2 3.49374723 11.2924623 0.257983446
    ip1 9.2909193 10.6955347 0.0975953862
    ip2 10.6955347 26.3756752 0.25352037

    推理十次

    Tables max_in max_out max_params
    Conv1 0.99609375 3.58768392 0.612441599
    Conv2 3.5301609 11.5329533 0.257983446
    ip1 10.1861591 12.5225191 0.0975953862
    ip2 12.5225191 29.3337383 0.25352037

    依据上表数据得出每层的输入特征图,卷积权值,输出特征图的整数位宽和小数位宽。
    fl表示数据小数位宽,il表示整数位宽,bw(bit_width)表示定点数据位宽。

    定点数据范围:-(\rm 2^{\cal bw- 1}){*}{2^{\cal -fl}}≤data ≤(\rm 2^{\cal bw- 1}- 1){*}{2^{\cal -fl}}

    在量化模式下推理的量化过程如下:

    template <typename Dtype>// 模板类型 Dtype
    void BaseRistrettoLayer<Dtype>::Trim2FixedPoint_cpu(
          Dtype* data,    // 数据起始指针
          const int cnt,  // 数据数量
          const int bit_width,// 量化总位宽
          const int rounding, // 取整策略
          int fl)             // 小数位量化位宽
    {
    // 计算定点数据范围
        Dtype max_data = (pow(2, bit_width - 1) - 1) * pow(2, -fl);
        Dtype min_data = -pow(2, bit_width - 1) * pow(2, -fl);
    
      for (int index = 0; index < cnt; ++index)// 遍历每一个需要量化的数据
      {
        // Saturate data 上下溢出处理
        data[index] = std::max(std::min(data[index], max_data), min_data);
    
        // Round data
        data[index] /= pow(2, -fl);// 放大小数部分 对应的位宽倍数
        {
        case QuantizationParameter_Rounding_NEAREST:
          data[index] = round(data[index]);// 最近偶数取整
          break;
        case QuantizationParameter_Rounding_STOCHASTIC:
          data[index] = floor(data[index] + RandUniform_cpu());// 随机取整
          break;
        default:
          break;
        }
        data[index] *= pow(2, -fl);// 最后再反量化会小数 缩小对应的位宽倍数
      }
    }
    

    上溢处理:等于定点最大值
    下溢处理:等于定点最小值
    rounding_scheme 量化的舍入方案:
    a. 最近偶数(NEAREST)
    b. 随机舍入(STOCHASTIC)
    默认使用方案A
    Data_{quant}=\frac{round(Data*2^{-fl})}{2^{-fl}}

    具体计算举例:
    Data=3.5301609 ,符号位1位,整数位2位 ,小数位13位
    data_temp = 3.5301609 * 2^13 = 28919.0780928
    round(data_temp) = 28919
    Data_quant = 28919 / 2^13 = 3.5301513671875

    相关文章

      网友评论

          本文标题:FPGA部署卷积神经网络之量化 Caffe restretto

          本文链接:https://www.haomeiwen.com/subject/hovlaftx.html