Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[enhancement] Support for YOLOv3 #451

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions components/kendryte_sdk/include/sipeed_yolo2.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,24 @@ typedef struct
float nms_value;
uint32_t coords;
uint32_t anchor_number;
uint8_t branch_number;
int wh[2];
uint8_t ver;
float *anchor;
uint32_t image_width;
uint32_t image_height;
uint32_t classes;
uint32_t net_width;
uint32_t net_height;
uint32_t layer_width;
uint32_t layer_height;
uint32_t layer_width[2];
uint32_t layer_height[2];
uint32_t boxes_number;
uint32_t output_number;
float scale;
float bias;
void *boxes;
//uint8_t *input;
float *output;
float *output[2];
float *probs_buf;
float **probs;
float *activate;
Expand All @@ -53,5 +56,4 @@ void region_layer_deinit(region_layer_t *rl);
void region_layer_run(region_layer_t *rl, obj_info_t *obj_info);
void region_layer_draw_boxes(region_layer_t *rl, callback_draw_box callback);


#endif
133 changes: 88 additions & 45 deletions components/kendryte_sdk/src/sipeed_yolo2.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
#include <math.h>
#include "printf.h"

// #include "lcd.h"

/* start of region_layer.c*/

typedef struct
Expand All @@ -23,42 +21,50 @@ typedef struct
float **probs;
} __attribute__((aligned(8))) sortable_box_t;

uint8_t _branch;

int region_layer_init(region_layer_t *rl, void* ctx)
{
int flag = 0;
uint16_t wi,hi,chi;
uint16_t wo,ho,cho;
uint16_t wi, hi, chi;
uint16_t wo[2], ho[2], cho[2];
size_t size;
int kmodel_type=sipeed_kpu_model_get_type(ctx);


if(sipeed_kpu_model_get_input_shape(ctx, &wi, &hi, &chi) != SIPEED_KPU_ERR_NONE)
{
// mp_printf(&mp_plat_print, "[MAIXPY]rl: first layer not conv layer!\r\n");
return -1;
}

if(sipeed_kpu_model_get_output_shape(ctx, &wo, &ho, &cho) != SIPEED_KPU_ERR_NONE)
{
// mp_printf(&mp_plat_print, "[MAIXPY]rl: can't fetch last layer!\r\n");
return -1;
}
for (uint8_t i = 0; i < rl->branch_number; i++)
{
if(sipeed_kpu_get_outputs_shape(ctx, i, &wo[i], &ho[i], &cho[i]) != SIPEED_KPU_ERR_NONE)
{
// mp_printf(&mp_plat_print, "[MAIXPY]rl: can't fetch last layer!\r\n");
return -1;
}
}

rl->coords = 4;
rl->image_width = wi;
rl->image_height = hi;

rl->classes = cho / 5 - 5;
rl->classes = cho[0] / rl->anchor_number - 5;
rl->net_width = wi;
rl->net_height = hi;
rl->layer_width = wo;
rl->layer_height = ho;
rl->boxes_number = (rl->layer_width * rl->layer_height * rl->anchor_number);

for (uint8_t i = 0; i < rl->branch_number; i++)
{
rl->layer_width[i] = wo[i];
rl->layer_height[i] = ho[i];
rl->boxes_number += (rl->layer_width[i] * rl->layer_height[i] * rl->anchor_number);
rl->wh[i] = rl->layer_width[i] * rl->layer_height[i];
sipeed_kpu_get_output(ctx, i, &rl->output[i], &size);
}

rl->output_number = (rl->boxes_number * (rl->classes + rl->coords + 1));

sipeed_kpu_get_output(ctx, 0, &(rl->output), &size);


//module output -> rl output
//mp_printf(&mp_plat_print, "size=%ld\r\n",size);
//rl->scale = output_scale;
Expand All @@ -74,6 +80,7 @@ int region_layer_init(region_layer_t *rl, void* ctx)
flag = -1;
goto malloc_error;
}*/

rl->boxes = malloc(rl->boxes_number * sizeof(box_t));
if (rl->boxes == NULL)
{
Expand All @@ -92,6 +99,7 @@ int region_layer_init(region_layer_t *rl, void* ctx)
flag = -4;
goto malloc_error;
}

/*rl->activate = malloc(256 * sizeof(float));
if (rl->activate == NULL)
{
Expand All @@ -109,9 +117,11 @@ int region_layer_init(region_layer_t *rl, void* ctx)
rl->activate[i] = 1.0 / (1.0 + expf(-(i * rl->scale + rl->bias)));
rl->softmax[i] = expf(rl->scale * (i - 255));
}*/
for (uint32_t i = 0; i < rl->boxes_number; i++){
rl->probs[i] = &(rl->probs_buf[i * (rl->classes + 1)]);}


for (uint32_t i = 0; i < rl->boxes_number; i++)
{
rl->probs[i] = &(rl->probs_buf[i * (rl->classes + 1)]);
}

return 0;
malloc_error:
Expand All @@ -136,20 +146,22 @@ void region_layer_deinit(region_layer_t *rl)

static void activate_array(region_layer_t *rl, int index, int n)
{
float *output = &rl->output[index];
float *output = &rl->output[_branch][index];
//uint8_t *input = &rl->input[index];

for (int i = 0; i < n; ++i)
{
output[i] = 1.0 / (1.0 + expf(-output[i]));//rl->activate[input[i]];
}
}

static int entry_index(region_layer_t *rl, int location, int entry)
{
int wh = rl->layer_width * rl->layer_height;
int n = location / wh;
int loc = location % wh;

return n * wh * (rl->coords + rl->classes + 1) + entry * wh + loc;
int n = location / rl->wh[_branch];
int loc = location % rl->wh[_branch];

return n * rl->wh[_branch] * (rl->coords + rl->classes + 1) + entry * rl->wh[_branch] + loc;
}

static void softmax(float *data, int n, int stride)
Expand Down Expand Up @@ -197,17 +209,25 @@ static void forward_region_layer(region_layer_t *rl)

for (int n = 0; n < rl->anchor_number; ++n)
{
index = entry_index(rl, n * rl->layer_width * rl->layer_height, 0);
activate_array(rl, index, 2 * rl->layer_width * rl->layer_height);
index = entry_index(rl, n * rl->layer_width * rl->layer_height, 4);
activate_array(rl, index, rl->layer_width * rl->layer_height);
}
index = entry_index(rl, n * rl->layer_width[_branch] * rl->layer_height[_branch], 0);
activate_array(rl, index, 2 * rl->layer_width[_branch] * rl->layer_height[_branch]);
index = entry_index(rl, n * rl->layer_width[_branch] * rl->layer_height[_branch], 4);
activate_array(rl, index, rl->layer_width[_branch] * rl->layer_height[_branch]);

if (rl->ver == 3)
{
index = entry_index(rl, n * rl->layer_width[_branch] * rl->layer_height[_branch], 5);
activate_array(rl, index, rl->classes * rl->layer_width[_branch] * rl->layer_height[_branch]);
}
}

if (rl->ver == 2)
{
index = entry_index(rl, 0, rl->coords + 1);
softmax_cpu(rl->output + index, rl->classes, rl->anchor_number,\
rl->output_number / rl->anchor_number, rl->layer_width * rl->layer_height,\
rl->layer_width * rl->layer_height);
softmax_cpu(rl->output[_branch] + index, rl->classes, rl->anchor_number,\
rl->output_number / rl->anchor_number, rl->layer_width[_branch] * rl->layer_height[_branch],\
rl->layer_width[_branch] * rl->layer_height[_branch]);
}
}

static void correct_region_boxes(region_layer_t *rl, box_t *boxes)
Expand Down Expand Up @@ -245,48 +265,67 @@ static void correct_region_boxes(region_layer_t *rl, box_t *boxes)
}
}

static box_t get_region_box(float *x, float *biases, int n, int index, int i, int j, int w, int h, int stride)
static box_t get_region_box(float *x, float *biases, int n, int index,
int i, int j, int w, int h,
int stride, region_layer_t *rl)
{
volatile box_t b;

b.x = (i + x[index + 0 * stride]) / w;
b.y = (j + x[index + 1 * stride]) / h;
b.w = expf(x[index + 2 * stride]) * biases[2 * n] / w;
b.h = expf(x[index + 3 * stride]) * biases[2 * n + 1] / h;

if (rl->ver == 2)
{
b.w = expf(x[index + 2 * stride]) * biases[2 * n + rl->anchor_number * 2 * _branch] / w;
b.h = expf(x[index + 3 * stride]) * biases[2 * n + 1 + rl->anchor_number * 2 * _branch] / h;
}

if (rl->ver == 3)
{
b.w = expf(x[index + 2 * stride]) * biases[2 * n + rl->anchor_number * 2 * _branch];
b.h = expf(x[index + 3 * stride]) * biases[2 * n + 1 + rl->anchor_number * 2 * _branch];
}

return b;
}

static void get_region_boxes(region_layer_t *rl, float *predictions, float **probs, box_t *boxes)
{
uint32_t layer_width = rl->layer_width;
uint32_t layer_height = rl->layer_height;
uint32_t anchor_number = rl->anchor_number;
uint8_t branch_num = rl->branch_number;
uint32_t classes = rl->classes;
uint32_t coords = rl->coords;
float threshold = rl->threshold;

uint32_t layer_width = rl->layer_width[_branch];
uint32_t layer_height = rl->layer_height[_branch];

for (int i = 0; i < layer_width * layer_height; ++i)
{
int row = i / layer_width;
int col = i % layer_width;

for (int n = 0; n < anchor_number; ++n)
{
int index = n * layer_width * layer_height + i;
int index = n * layer_width * layer_height + i
+ (rl->layer_width[_branch - 1] * rl->layer_height[_branch - 1] * rl->anchor_number) * _branch;

for (int j = 0; j < classes; ++j)
probs[index][j] = 0;

int obj_index = entry_index(rl, n * layer_width * layer_height + i, coords);
int box_index = entry_index(rl, n * layer_width * layer_height + i, 0);
float scale = predictions[obj_index];

boxes[index] = get_region_box(predictions, rl->anchor, n, box_index, col, row,
layer_width, layer_height, layer_width * layer_height);
boxes[index] = get_region_box(predictions, rl->anchor, n, box_index,
col, row, layer_width, layer_height,
layer_width * layer_height, rl);

float max = 0;

for (int j = 0; j < classes; ++j)
{

int class_index = entry_index(rl, n * layer_width * layer_height + i, coords + 1 + j);
float prob = scale * predictions[class_index];

Expand Down Expand Up @@ -430,9 +469,13 @@ static void region_layer_output(region_layer_t *rl, obj_info_t *obj_info)
}

void region_layer_run(region_layer_t *rl, obj_info_t *obj_info)
{
forward_region_layer(rl);
get_region_boxes(rl, rl->output, rl->probs, rl->boxes);
{
for (_branch = 0; _branch < rl->branch_number; _branch++)
{
forward_region_layer(rl);
get_region_boxes(rl, rl->output[_branch], rl->probs, rl->boxes);
}

do_nms_sort(rl, rl->boxes, rl->probs);
region_layer_output(rl, obj_info);
}
Expand Down
Loading