Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,317 @@
#include "box.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

box float_to_box(float *f)
{
box b;
b.x = f[0];
b.y = f[1];
b.w = f[2];
b.h = f[3];
return b;
}

dbox derivative(box a, box b)
{
dbox d;
d.dx = 0;
d.dw = 0;
float l1 = a.x - a.w/2;
float l2 = b.x - b.w/2;
if (l1 > l2){
d.dx -= 1;
d.dw += .5;
}
float r1 = a.x + a.w/2;
float r2 = b.x + b.w/2;
if(r1 < r2){
d.dx += 1;
d.dw += .5;
}
if (l1 > r2) {
d.dx = -1;
d.dw = 0;
}
if (r1 < l2){
d.dx = 1;
d.dw = 0;
}

d.dy = 0;
d.dh = 0;
float t1 = a.y - a.h/2;
float t2 = b.y - b.h/2;
if (t1 > t2){
d.dy -= 1;
d.dh += .5;
}
float b1 = a.y + a.h/2;
float b2 = b.y + b.h/2;
if(b1 < b2){
d.dy += 1;
d.dh += .5;
}
if (t1 > b2) {
d.dy = -1;
d.dh = 0;
}
if (b1 < t2){
d.dy = 1;
d.dh = 0;
}
return d;
}

float overlap(float x1, float w1, float x2, float w2)
{
float l1 = x1 - w1/2;
float l2 = x2 - w2/2;
float left = l1 > l2 ? l1 : l2;
float r1 = x1 + w1/2;
float r2 = x2 + w2/2;
float right = r1 < r2 ? r1 : r2;
return right - left;
}

float box_intersection(box a, box b)
{
float w = overlap(a.x, a.w, b.x, b.w);
float h = overlap(a.y, a.h, b.y, b.h);
if(w < 0 || h < 0) return 0;
float area = w*h;
return area;
}

float box_union(box a, box b)
{
float i = box_intersection(a, b);
float u = a.w*a.h + b.w*b.h - i;
return u;
}

float box_iou(box a, box b)
{
return box_intersection(a, b)/box_union(a, b);
}

float box_rmse(box a, box b)
{
return sqrt(pow(a.x-b.x, 2) +
pow(a.y-b.y, 2) +
pow(a.w-b.w, 2) +
pow(a.h-b.h, 2));
}

dbox dintersect(box a, box b)
{
float w = overlap(a.x, a.w, b.x, b.w);
float h = overlap(a.y, a.h, b.y, b.h);
dbox dover = derivative(a, b);
dbox di;

di.dw = dover.dw*h;
di.dx = dover.dx*h;
di.dh = dover.dh*w;
di.dy = dover.dy*w;

return di;
}

dbox dunion(box a, box b)
{
dbox du;

dbox di = dintersect(a, b);
du.dw = a.h - di.dw;
du.dh = a.w - di.dh;
du.dx = -di.dx;
du.dy = -di.dy;

return du;
}


void test_dunion()
{
box a = {0, 0, 1, 1};
box dxa= {0+.0001, 0, 1, 1};
box dya= {0, 0+.0001, 1, 1};
box dwa= {0, 0, 1+.0001, 1};
box dha= {0, 0, 1, 1+.0001};

box b = {.5, .5, .2, .2};
dbox di = dunion(a,b);
printf("Union: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
float inter = box_union(a, b);
float xinter = box_union(dxa, b);
float yinter = box_union(dya, b);
float winter = box_union(dwa, b);
float hinter = box_union(dha, b);
xinter = (xinter - inter)/(.0001F);
yinter = (yinter - inter)/(.0001F);
winter = (winter - inter)/(.0001F);
hinter = (hinter - inter)/(.0001F);
printf("Union Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
}
void test_dintersect()
{
box a = {0, 0, 1, 1};
box dxa= {0+.0001, 0, 1, 1};
box dya= {0, 0+.0001, 1, 1};
box dwa= {0, 0, 1+.0001, 1};
box dha= {0, 0, 1, 1+.0001};

box b = {.5, .5, .2, .2};
dbox di = dintersect(a,b);
printf("Inter: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
float inter = box_intersection(a, b);
float xinter = box_intersection(dxa, b);
float yinter = box_intersection(dya, b);
float winter = box_intersection(dwa, b);
float hinter = box_intersection(dha, b);
xinter = (xinter - inter)/(.0001F);
yinter = (yinter - inter)/(.0001F);
winter = (winter - inter)/(.0001F);
hinter = (hinter - inter)/(.0001F);
printf("Inter Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
}

void test_box()
{
test_dintersect();
test_dunion();
box a = {0, 0, 1, 1};
box dxa= {0+.00001, 0, 1, 1};
box dya= {0, 0+.00001, 1, 1};
box dwa= {0, 0, 1+.00001, 1};
box dha= {0, 0, 1, 1+.00001};

box b = {.5, 0, .2, .2};

float iou = box_iou(a,b);
iou = (1-iou)*(1-iou);
printf("%f\n", iou);
dbox d = diou(a, b);
printf("%f %f %f %f\n", d.dx, d.dy, d.dw, d.dh);

float xiou = box_iou(dxa, b);
float yiou = box_iou(dya, b);
float wiou = box_iou(dwa, b);
float hiou = box_iou(dha, b);
xiou = ((1-xiou)*(1-xiou) - iou)/(.00001F);
yiou = ((1-yiou)*(1-yiou) - iou)/(.00001F);
wiou = ((1-wiou)*(1-wiou) - iou)/(.00001F);
hiou = ((1-hiou)*(1-hiou) - iou)/(.00001F);
printf("manual %f %f %f %f\n", xiou, yiou, wiou, hiou);
}

dbox diou(box a, box b)
{
float u = box_union(a,b);
float i = box_intersection(a,b);
dbox di = dintersect(a,b);
dbox du = dunion(a,b);
dbox dd = {0,0,0,0};

if(i <= 0 || 1) {
dd.dx = b.x - a.x;
dd.dy = b.y - a.y;
dd.dw = b.w - a.w;
dd.dh = b.h - a.h;
return dd;
}

dd.dx = 2*pow((1-(i/u)),1)*(di.dx*u - du.dx*i)/(u*u);
dd.dy = 2*pow((1-(i/u)),1)*(di.dy*u - du.dy*i)/(u*u);
dd.dw = 2*pow((1-(i/u)),1)*(di.dw*u - du.dw*i)/(u*u);
dd.dh = 2*pow((1-(i/u)),1)*(di.dh*u - du.dh*i)/(u*u);
return dd;
}

typedef struct{
int index;
int class;
float **probs;
} sortable_bbox;

int nms_comparator(const void *pa, const void *pb)
{
sortable_bbox a = *(sortable_bbox *)pa;
sortable_bbox b = *(sortable_bbox *)pb;
float diff = a.probs[a.index][b.class] - b.probs[b.index][b.class];
if(diff < 0) return 1;
else if(diff > 0) return -1;
return 0;
}

void do_nms_sort(box *boxes, float **probs, int total, int classes, float thresh)
{
int i, j, k;
sortable_bbox *s = calloc(total, sizeof(sortable_bbox));

for(i = 0; i < total; ++i){
s[i].index = i;
s[i].class = 0;
s[i].probs = probs;
}

for(k = 0; k < classes; ++k){
for(i = 0; i < total; ++i){
s[i].class = k;
}
qsort(s, total, sizeof(sortable_bbox), nms_comparator);
for(i = 0; i < total; ++i){
if(probs[s[i].index][k] == 0) continue;
box a = boxes[s[i].index];
for(j = i+1; j < total; ++j){
box b = boxes[s[j].index];
if (box_iou(a, b) > thresh){
probs[s[j].index][k] = 0;
}
}
}
}
free(s);
}

void do_nms(box *boxes, float **probs, int total, int classes, float thresh)
{
int i, j, k;
for(i = 0; i < total; ++i){
int any = 0;
for(k = 0; k < classes; ++k) any = any || (probs[i][k] > 0);
if(!any) {
continue;
}
for(j = i+1; j < total; ++j){
if (box_iou(boxes[i], boxes[j]) > thresh){
for(k = 0; k < classes; ++k){
if (probs[i][k] < probs[j][k]) probs[i][k] = 0;
else probs[j][k] = 0;
}
}
}
}
}

box encode_box(box b, box anchor)
{
box encode;
encode.x = (b.x - anchor.x) / anchor.w;
encode.y = (b.y - anchor.y) / anchor.h;
encode.w = log2(b.w / anchor.w);
encode.h = log2(b.h / anchor.h);
return encode;
}

box decode_box(box b, box anchor)
{
box decode;
decode.x = b.x * anchor.w + anchor.x;
decode.y = b.y * anchor.h + anchor.y;
decode.w = pow(2., b.w) * anchor.w;
decode.h = pow(2., b.h) * anchor.h;
return decode;
}
@@ -0,0 +1,21 @@
#ifndef BOX_H
#define BOX_H

typedef struct{
float x, y, w, h;
} box;

typedef struct{
float dx, dy, dw, dh;
} dbox;

box float_to_box(float *f);
float box_iou(box a, box b);
float box_rmse(box a, box b);
dbox diou(box a, box b);
void do_nms(box *boxes, float **probs, int total, int classes, float thresh);
void do_nms_sort(box *boxes, float **probs, int total, int classes, float thresh);
box decode_box(box b, box anchor);
box encode_box(box b, box anchor);

#endif
@@ -0,0 +1,79 @@
#pragma once
#ifndef GPU_H
#define GPU_H

#ifdef __cplusplus
extern "C" {
#endif


#ifdef GPU

struct layer;
typedef struct layer layer;
typedef struct layer local_layer;

void pull_batchnorm_layer(layer l); // not required now
void push_batchnorm_layer(layer l); // not required now
void pull_local_layer(local_layer l); // not required now
void push_local_layer(local_layer l); // not required now
void pull_connected_layer(local_layer l); // not required now
void push_connected_layer(local_layer l); // not required now


void check_error(cudaError_t status);
void cuda_set_device(int n);
int cuda_get_device();

#ifdef CUDNN
cudnnHandle_t cudnn_handle();
#endif

float *cuda_make_array(float *x, size_t n);
int *cuda_make_int_array(size_t n);
void cuda_free(float *x_gpu);
void cuda_push_array(float *x_gpu, float *x, size_t n);
void cuda_pull_array(float *x_gpu, float *x, size_t n);
float *get_network_output_layer_gpu(network net, int i);
float *get_network_output_gpu(network net);
dim3 cuda_gridsize(size_t n);
void pull_convolutional_layer(convolutional_layer layer);
void push_convolutional_layer(convolutional_layer layer);

// -------------------- CUDA functions -------------------

// add BIAS
void add_bias_gpu(float *output, float *biases, int batch, int n, int size);

// normalization
void normalize_gpu(float *x, float *mean, float *variance, int batch, int filters, int spatial);

// fill array
void fill_ongpu(int N, float ALPHA, float * X, int INCX);

// scale BIAS
void scale_bias_gpu(float *output, float *biases, int batch, int n, int size);

// max-pool layer
void forward_maxpool_layer_gpu(maxpool_layer layer, network_state state);

// flatten
void flatten_ongpu(float *x, int spatial, int layers, int batch, int forward, float *out);


// activations
void activate_array_ongpu(float *x, int n, ACTIVATION a);

// softmax layer
void softmax_gpu(float *input, int n, int offset, int groups, float temp, float *output);

// reorg layer
void reorg_ongpu(float *x, int w, int h, int c, int batch, int stride, int forward, float *out);

#endif // GPU

#ifdef __cplusplus
}
#endif

#endif // GPU_H

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.