FPGA部署卷积神经网络之量化 Caffe restretto 量化工具解析

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容