























#include"stdio.h"#include"stdlib.h"#include"math.h"#include <string.h>typedef struct conv_info{
float weight[4];
float bias[4];
int weight_int8[4];
int bias_int[4];
float scale;
}conv_info;
typedef struct tensor_info{
float data[4];
int data_int8[4];
float scale;
}tensor_info;
void init_tensor(struct tensor_info* tensor, float* data, int num){
for(int i=0; i<num; i++){
tensor->data[i] = data[i];
}}void init_conv(struct conv_info* conv, float* weight, float* bias, int num){
for(int i=0; i<num; i++){
conv->weight[i] = weight[i];
conv->bias[i] = bias[i];
}}void CalculateConvScale(struct conv_info* conv, int num){
float abs_max=0;
float *data = conv->weight;
for(int i=0; i<num; i++){
if(fabs(data[i])>abs_max){
abs_max = fabs(data[i]);
} }conv->scale = abs_max/127.0;
for(int i=0; i<num; i++){
int temp = round(data[i]/(conv->scale));
conv->weight_int8[i] = temp;
}}void ClaculateConvBiasInt8(struct conv_info* conv, struct tensor_info* tensor, int num){
for(int i=0; i<num; i++){
int temp = round(conv->bias[i]/(conv->scale*tensor->scale));
conv->bias_int[i] = temp;
}}void CalculateTensorScale(struct tensor_info* tensor, int num){
float abs_max=0;
float *data = tensor->data;
for(int i=0; i<num; i++){
if(fabs(data[i])>abs_max){
abs_max = fabs(data[i]);
} }tensor->scale = abs_max/127.0;
}void ConvFloat(struct tensor_info* input, struct conv_info* conv, struct tensor_info* output, int num){
for(int i=0; i<num; i++){
output->data[i] = input->data[i]*conv->weight[i]+conv->bias[i];
}}void ConvInt(struct tensor_info* input, struct conv_info* conv, struct tensor_info* output, int num){
for(int i=0; i<num; i++){
int input_int8 = round(input->data[i] / input->scale);
int out_int8 = input_int8 * conv->weight_int8[i];
int out_bias_int8 = out_int8 + conv->bias_int[i];
output->data[i] = out_bias_int8 * input->scale * conv->scale;
}}void updateBiasInt8(struct conv_info* conv, float scale, int num){
for(int i=0; i<num; i++){
int temp = round(conv->bias[i]/scale);
conv->bias_int[i] = temp;
}}void ConvFrontTial(struct tensor_info* input, struct conv_info* conv1, struct conv_info* conv2, struct conv_info* conv3,
struct tensor_info* output, int num){
for(int i=0; i<num; i++){
int input_int = round(input->data[i] / input->scale);
int input_int_1 = input_int * conv1->weight_int8[i] + conv1->bias_int[i];
int input_int_2 = input_int_1 * conv2->weight_int8[i] + conv2->bias_int[i];
int input_int_3 = input_int_2 * conv3->weight_int8[i] + conv3->bias_int[i];
output->data[i] = input_int_3 * input->scale * conv1->scale * conv2->scale * conv3->scale;
}}int main(){
tensor_info* input = (tensor_info*) malloc(sizeof(tensor_info));
float input_data[4] = {0.24, -0.08, 0.16, -0.61};
init_tensor(input, input_data, 4);
conv_info* conv1 = (conv_info*) malloc(sizeof(conv_info));
float weight_data1[4] = {0.02, 0.01, -0.04, 0.01} ;
float bias1[4] = {11.4, -6.3, -57.2, 5.48};
init_conv(conv1, weight_data1, bias1, 4);
conv_info* conv2 = (conv_info*) malloc(sizeof(conv_info));
float weight_data2[4] = {0.6, 0.25, -0.48, 0.69} ;
float bias2[4] = {10.4, -6.3, -31.2, 5.48};
init_conv(conv2, weight_data2, bias2, 4);
conv_info* conv3 = (conv_info*) malloc(sizeof(conv_info));
float weight_data3[4] = {-2.4, 6.4, 1.2, 0.69} ;
float bias3[4] = {-5.4, 7.2, 26.3, 3.24};
init_conv(conv3, weight_data3, bias3, 4);
printf("\n 1 ******** float 推理 ******** \n");
tensor_info* middle1 = (tensor_info*) malloc(sizeof(tensor_info));
tensor_info* middle2 = (tensor_info*) malloc(sizeof(tensor_info));
tensor_info* output_res = (tensor_info*) malloc(sizeof(tensor_info));
ConvFloat(input, conv1, middle1, 4);
ConvFloat(middle1, conv2, middle2, 4);
ConvFloat(middle2, conv3, output_res, 4);
for(int i=0; i<4; i++){
printf(" %f ", output_res->data[i]);
}printf("\n 2 ******** 量化推理 ******** \n");
CalculateConvScale(conv1, 4);
CalculateConvScale(conv2, 4);
CalculateConvScale(conv3, 4);
CalculateTensorScale(input, 4);
CalculateTensorScale(middle1, 4);
CalculateTensorScale(middle2, 4);
ClaculateConvBiasInt8(conv1, input, 4);
ClaculateConvBiasInt8(conv2, middle1, 4);
ClaculateConvBiasInt8(conv3, middle2, 4);
ConvInt(input, conv1, middle1, 4);
ConvInt(middle1, conv2, middle2, 4);
ConvInt(middle2, conv3, output_res, 4);
for(int i=0; i<4; i++){
printf(" %f ", output_res->data[i]);
}printf("\n 3 ******** 首尾量化推理 ******** \n");
updateBiasInt8(conv1, input->scale*conv1->scale, 4);
updateBiasInt8(conv2, input->scale*conv1->scale*conv2->scale, 4);
updateBiasInt8(conv3, input->scale*conv1->scale*conv2->scale*conv3->scale, 4);
ConvFrontTial(input, conv1, conv2, conv3, output_res, 4);
for(int i=0; i<4; i++){
printf(" %f ", output_res->data[i]);
}printf("\n【第一个卷积】 输入scale:%f 权重scale:%f \n", input->scale, conv1->scale);
for(int i=0; i<4; i++){
printf("weight_scaled(int8):%d bias_scaled(int32):%d ",conv1->weight_int8[i], conv1->bias_int[i]);
}printf("\n【第二个卷积】 输入scale:%f 权重scale:%f \n", middle1->scale, conv2->scale);
for(int i=0; i<4; i++){
printf("weight_scaled(int8):%d bias_scaled(int32):%d ",conv2->weight_int8[i], conv2->bias_int[i]);
}printf("\n【第三个卷积】 输入scale:%f 权重scale:%f \n", middle2->scale, conv3->scale);
for(int i=0; i<4; i++){
printf("weight_scaled(int8):%d bias_scaled(int32):%d ",conv3->weight_int8[i], conv3->bias_int[i]);
}return 0;
}此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。