Files
MTCNN-FaceNet-light/src/network.cpp
ChrisKong 729eecac2e 整理代码结构
整理代码结构

Co-Authored-By: Chris Kong <609027949@qq.com>
2019-12-28 17:48:50 +08:00

747 lines
28 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "network.h"
void addbias(struct pBox *pbox, mydataFmt *pbias) {
if (pbox->pdata == NULL) {
cout << "Relu feature is NULL!!" << endl;
return;
}
if (pbias == NULL) {
cout << "the Relu bias is NULL!!" << endl;
return;
}
mydataFmt *op = pbox->pdata;
mydataFmt *pb = pbias;
long dis = pbox->width * pbox->height;
for (int channel = 0; channel < pbox->channel; channel++) {
for (int col = 0; col < dis; col++) {
*op = *op + *pb;
op++;
}
pb++;
}
}
void image2MatrixInit(Mat &image, struct pBox *pbox) {
if ((image.data == NULL) || (image.type() != CV_8UC3)) {
cout << "image's type is wrong!!Please set CV_8UC3" << endl;
return;
}
pbox->channel = image.channels();
pbox->height = image.rows;
pbox->width = image.cols;
pbox->pdata = (mydataFmt *) malloc(pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
if (pbox->pdata == NULL)cout << "the image2MatrixInit failed!!" << endl;
memset(pbox->pdata, 0, pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
}
void image2Matrix(const Mat &image, const struct pBox *pbox, int num) {
if ((image.data == NULL) || (image.type() != CV_8UC3)) {
cout << "image's type is wrong!!Please set CV_8UC3" << endl;
return;
}
if (pbox->pdata == NULL) {
return;
}
mydataFmt *p = pbox->pdata;
double sqr, stddev_adj;
int size;
mydataFmt mymean, mystddev;
// prewhiten
if (num != 0) {
MeanAndDev(image, mymean, mystddev);
cout << mymean << "----" << mystddev << endl;
size = image.cols * image.rows * image.channels();
sqr = sqrt(double(size));
if (mystddev >= 1.0 / sqr) {
stddev_adj = mystddev;
} else {
stddev_adj = 1.0 / sqr;
}
}
for (int rowI = 0; rowI < image.rows; rowI++) {
for (int colK = 0; colK < image.cols; colK++) {
if (num == 0) {
*p = (image.at<Vec3b>(rowI, colK)[2] - 127.5) * 0.0078125;
*(p + image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[1] - 127.5) * 0.0078125;
*(p + 2 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[0] - 127.5) * 0.0078125;
p++;
} else {
// brg2rgb
*(p + 0 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[2] - mymean) / stddev_adj;
*(p + 1 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[1] - mymean) / stddev_adj;
*(p + 2 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[0] - mymean) / stddev_adj;
p++;
}
}
}
}
void MeanAndDev(const Mat &image, mydataFmt &p, mydataFmt &q) {
mydataFmt meansum = 0, stdsum = 0;
for (int rowI = 0; rowI < image.rows; rowI++) {
for (int colK = 0; colK < image.cols; colK++) {
meansum += image.at<Vec3b>(rowI, colK)[0] + image.at<Vec3b>(rowI, colK)[1] + image.at<Vec3b>(rowI, colK)[2];
}
}
p = meansum / (image.cols * image.rows * image.channels());
for (int rowI = 0; rowI < image.rows; rowI++) {
for (int colK = 0; colK < image.cols; colK++) {
stdsum += pow((image.at<Vec3b>(rowI, colK)[0] - p), 2) +
pow((image.at<Vec3b>(rowI, colK)[1] - p), 2) +
pow((image.at<Vec3b>(rowI, colK)[2] - p), 2);
}
}
q = sqrt(stdsum / (image.cols * image.rows * image.channels()));
}
void featurePadInit(const pBox *pbox, pBox *outpBox, const int pad, const int padw, const int padh) {
if (pad < -1) {
cout << "the data needn't to pad,please check you network!" << endl;
return;
}
outpBox->channel = pbox->channel;
if (pad == -1) {
outpBox->height = pbox->height + 2 * padh;
outpBox->width = pbox->width + 2 * padw;
} else {
outpBox->height = pbox->height + 2 * pad;
outpBox->width = pbox->width + 2 * pad;
}
long RowByteNum = outpBox->width * sizeof(mydataFmt);
outpBox->pdata = (mydataFmt *) malloc(outpBox->channel * outpBox->height * RowByteNum);
if (outpBox->pdata == NULL)cout << "the featurePadInit is failed!!" << endl;
memset(outpBox->pdata, 0, outpBox->channel * outpBox->height * RowByteNum);
}
void featurePad(const pBox *pbox, pBox *outpBox, const int pad, const int padw, const int padh) {
mydataFmt *p = outpBox->pdata;
mydataFmt *pIn = pbox->pdata;
if (pad == -1) {
for (int row = 0; row < outpBox->channel * outpBox->height; row++) {
if ((row % outpBox->height) < padh || (row % outpBox->height > (outpBox->height - padh - 1))) {
p += outpBox->width;
continue;
}
p += padw;
memcpy(p, pIn, pbox->width * sizeof(mydataFmt));
p += pbox->width + padw;
pIn += pbox->width;
}
} else {
for (int row = 0; row < outpBox->channel * outpBox->height; row++) {
if ((row % outpBox->height) < pad || (row % outpBox->height > (outpBox->height - pad - 1))) {
p += outpBox->width;
continue;
}
p += pad;
memcpy(p, pIn, pbox->width * sizeof(mydataFmt));
p += pbox->width + pad;
pIn += pbox->width;
}
}
}
void convolutionInit(const Weight *weight, pBox *pbox, pBox *outpBox) {
outpBox->channel = weight->selfChannel;
// ((imginputh - ckh + 2 * ckpad) / stride) + 1;
if (weight->kernelSize == 0) {
outpBox->width = ((pbox->width - weight->w + 2 * weight->padw) / weight->stride) + 1;
// outpBox->width = (pbox->width - weight->w) / weight->stride + 1;
// outpBox->height = (pbox->height - weight->h) / weight->stride + 1;
outpBox->height = (pbox->height - weight->h + 2 * weight->padh) / weight->stride + 1;
} else {
outpBox->width = ((pbox->width - weight->kernelSize + 2 * weight->pad) / weight->stride) + 1;
outpBox->height = ((pbox->height - weight->kernelSize + 2 * weight->pad) / weight->stride) + 1;
}
// cout << outpBox->pdata << endl;
outpBox->pdata = (mydataFmt *) malloc(outpBox->width * outpBox->height * outpBox->channel * sizeof(mydataFmt));
// cout << outpBox->pdata << endl;
if (outpBox->pdata == NULL)cout << "the convolutionInit is failed!!" << endl;
memset(outpBox->pdata, 0, outpBox->width * outpBox->height * outpBox->channel * sizeof(mydataFmt));
if (weight->pad != 0) {
pBox *padpbox = new pBox;
featurePadInit(pbox, padpbox, weight->pad, weight->padw, weight->padh);
featurePad(pbox, padpbox, weight->pad, weight->padw, weight->padh);
*pbox = *padpbox;
}
}
void convolution(const Weight *weight, const pBox *pbox, pBox *outpBox) {
int ckh, ckw, ckd, stride, cknum, ckpad, imginputh, imginputw, imginputd, Nh, Nw;
mydataFmt *ck, *imginput;
// float *output = outpBox->pdata;
float temp;
ck = weight->pdata;
if (weight->kernelSize == 0) {
ckh = weight->h;
ckw = weight->w;
} else {
ckh = weight->kernelSize;
ckw = weight->kernelSize;
}
ckd = weight->lastChannel;
cknum = weight->selfChannel;
ckpad = weight->pad;
stride = weight->stride;
imginput = pbox->pdata;
imginputh = pbox->height;
imginputw = pbox->width;
imginputd = pbox->channel;
Nh = outpBox->height;
Nw = outpBox->width;
// Nh = ((imginputh - ckh + 2 * ckpad) / stride) + 1;
// Nw = ((imginputw - ckw + 2 * ckpad) / stride) + 1;
for (int i = 0; i < cknum; ++i) {
for (int j = 0; j < Nh; j++) {
for (int k = 0; k < Nw; k++) {
temp = 0;
for (int m = 0; m < ckd; ++m) {
for (int n = 0; n < ckh; ++n) {
for (int i1 = 0; i1 < ckw; ++i1) {
temp += imginput[(j * stride + n) * imginputw
+ (k * stride + i1)
+ m * imginputh * imginputw]
* ck[i * ckh * ckw * ckd + m * ckh * ckw + n * ckw + i1];
}
}
}
//按照顺序存储
outpBox->pdata[i * outpBox->height * outpBox->width + j * outpBox->width + k] = temp;
}
}
}
}
void maxPoolingInit(const pBox *pbox, pBox *Matrix, int kernelSize, int stride, int flag) {
if (flag == 1) {
Matrix->width = floor((float) (pbox->width - kernelSize) / stride + 1);
Matrix->height = floor((float) (pbox->height - kernelSize) / stride + 1);
} else {
Matrix->width = ceil((float) (pbox->width - kernelSize) / stride + 1);
Matrix->height = ceil((float) (pbox->height - kernelSize) / stride + 1);
}
Matrix->channel = pbox->channel;
Matrix->pdata = (mydataFmt *) malloc(Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
if (Matrix->pdata == NULL)cout << "the maxPoolingI nit is failed!!" << endl;
memset(Matrix->pdata, 0, Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
}
void maxPooling(const pBox *pbox, pBox *Matrix, int kernelSize, int stride) {
if (pbox->pdata == NULL) {
cout << "the feature2Matrix pbox is NULL!!" << endl;
return;
}
mydataFmt *p = Matrix->pdata;
mydataFmt *pIn;
mydataFmt *ptemp;
mydataFmt maxNum = 0;
if ((pbox->width - kernelSize) % stride == 0 && (pbox->height - kernelSize) % stride == 0) {
for (int row = 0; row < Matrix->height; row++) {
for (int col = 0; col < Matrix->width; col++) {
pIn = pbox->pdata + row * stride * pbox->width + col * stride;
for (int channel = 0; channel < pbox->channel; channel++) {
ptemp = pIn + channel * pbox->height * pbox->width;
maxNum = *ptemp;
for (int kernelRow = 0; kernelRow < kernelSize; kernelRow++) {
for (int i = 0; i < kernelSize; i++) {
if (maxNum < *(ptemp + i + kernelRow * pbox->width))
maxNum = *(ptemp + i + kernelRow * pbox->width);
}
}
*(p + channel * Matrix->height * Matrix->width) = maxNum;
}
p++;
}
}
} else {
int diffh = 0, diffw = 0;
for (int channel = 0; channel < pbox->channel; channel++) {
pIn = pbox->pdata + channel * pbox->height * pbox->width;
for (int row = 0; row < Matrix->height; row++) {
for (int col = 0; col < Matrix->width; col++) {
ptemp = pIn + row * stride * pbox->width + col * stride;
maxNum = *ptemp;
diffh = row * stride - pbox->height + 1;
diffw = col * stride - pbox->width + 1;
for (int kernelRow = 0; kernelRow < kernelSize; kernelRow++) {
if ((kernelRow + diffh) > 0)break;
for (int i = 0; i < kernelSize; i++) {
if ((i + diffw) > 0)break;
if (maxNum < *(ptemp + i + kernelRow * pbox->width))
maxNum = *(ptemp + i + kernelRow * pbox->width);
}
}
*p++ = maxNum;
}
}
}
}
}
void avePoolingInit(const pBox *pbox, pBox *Matrix, int kernelSize, int stride) {
Matrix->width = ceil((float) (pbox->width - kernelSize) / stride + 1);
Matrix->height = ceil((float) (pbox->height - kernelSize) / stride + 1);
Matrix->channel = pbox->channel;
Matrix->pdata = (mydataFmt *) malloc(Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
if (Matrix->pdata == NULL)cout << "the maxPoolingInit is failed!!" << endl;
memset(Matrix->pdata, 0, Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
}
void avePooling(const pBox *pbox, pBox *Matrix, int kernelSize, int stride) {
if (pbox->pdata == NULL) {
cout << "the feature2Matrix pbox is NULL!!" << endl;
return;
}
mydataFmt *p = Matrix->pdata;
mydataFmt *pIn;
mydataFmt *ptemp;
mydataFmt sumNum = 0;
if ((pbox->width - kernelSize) % stride == 0 && (pbox->height - kernelSize) % stride == 0) {
for (int row = 0; row < Matrix->height; row++) {
for (int col = 0; col < Matrix->width; col++) {
pIn = pbox->pdata + row * stride * pbox->width + col * stride;
for (int channel = 0; channel < pbox->channel; channel++) {
ptemp = pIn + channel * pbox->height * pbox->width;
sumNum = 0;
for (int kernelRow = 0; kernelRow < kernelSize; kernelRow++) {
for (int i = 0; i < kernelSize; i++) {
sumNum += *(ptemp + i + kernelRow * pbox->width);
}
}
*(p + channel * Matrix->height * Matrix->width) = sumNum / (kernelSize * kernelSize);
}
p++;
}
}
}
}
/**
* 激活函数 有系数
* @param pbox
* @param pbias
* @param prelu_gmma
*/
void prelu(struct pBox *pbox, mydataFmt *pbias, mydataFmt *prelu_gmma) {
if (pbox->pdata == NULL) {
cout << "the pRelu feature is NULL!!" << endl;
return;
}
if (pbias == NULL) {
cout << "the pRelu bias is NULL!!" << endl;
return;
}
mydataFmt *op = pbox->pdata;
mydataFmt *pb = pbias;
mydataFmt *pg = prelu_gmma;
long dis = pbox->width * pbox->height;
for (int channel = 0; channel < pbox->channel; channel++) {
for (int col = 0; col < dis; col++) {
*op = *op + *pb;
*op = (*op > 0) ? (*op) : ((*op) * (*pg));
op++;
}
pb++;
pg++;
}
}
/**
* 激活函数 没有系数
* @param pbox
* @param pbias
*/
void relu(struct pBox *pbox, mydataFmt *pbias) {
if (pbox->pdata == NULL) {
cout << "the Relu feature is NULL!!" << endl;
return;
}
if (pbias == NULL) {
cout << "the Relu bias is NULL!!" << endl;
return;
}
mydataFmt *op = pbox->pdata;
mydataFmt *pb = pbias;
long dis = pbox->width * pbox->height;
for (int channel = 0; channel < pbox->channel; channel++) {
for (int col = 0; col < dis; col++) {
*op = *op + *pb;
*op = (*op > 0) ? (*op) : ((*op) * 0);
op++;
}
pb++;
}
}
void fullconnectInit(const Weight *weight, pBox *outpBox) {
outpBox->channel = weight->selfChannel;
outpBox->width = 1;
outpBox->height = 1;
outpBox->pdata = (mydataFmt *) malloc(weight->selfChannel * sizeof(mydataFmt));
if (outpBox->pdata == NULL)cout << "the fullconnectInit is failed!!" << endl;
memset(outpBox->pdata, 0, weight->selfChannel * sizeof(mydataFmt));
}
void fullconnect(const Weight *weight, const pBox *pbox, pBox *outpBox) {
if (pbox->pdata == NULL) {
cout << "the fc feature is NULL!!" << endl;
return;
}
if (weight->pdata == NULL) {
cout << "the fc weight is NULL!!" << endl;
return;
}
memset(outpBox->pdata, 0, weight->selfChannel * sizeof(mydataFmt));
//Y←αAX + βY β must be 0(zero)
// row no trans A's row A'col
//cblas_sgemv(CblasRowMajor, CblasNoTrans, weight->selfChannel, weight->lastChannel, 1, weight->pdata, weight->lastChannel, pbox->pdata, 1, 0, outpBox->pdata, 1);
vectorXmatrix(pbox->pdata, weight->pdata,
weight->lastChannel, weight->selfChannel,
outpBox->pdata);
}
void vectorXmatrix(mydataFmt *matrix, mydataFmt *v, int v_w, int v_h, mydataFmt *p) {
for (int i = 0; i < v_h; i++) {
p[i] = 0;
for (int j = 0; j < v_w; j++) {
p[i] += matrix[j] * v[i * v_w + j];
}
}
}
void readData(string filename, long dataNumber[], mydataFmt *pTeam[], int length) {
ifstream in(filename.data());
string line;
long temp = dataNumber[0];
if (in) {
int i = 0;
int count = 0;
int pos = 0;
while (getline(in, line)) {
try {
if (i < temp) {
line.erase(0, 1);
pos = line.find(']');
line.erase(pos, 1);
pos = line.find('\r');
if (pos != -1) {
line.erase(pos, 1);
}
if (dataNumber[count] != 0) {
*(pTeam[count])++ = atof(line.data());
}
} else {
count++;
if ((length != 0) && (count == length))
break;
temp += dataNumber[count];
line.erase(0, 1);
pos = line.find(']');
line.erase(pos, 1);
pos = line.find('\r');
if (pos != -1) {
line.erase(pos, 1);
}
if (dataNumber[count] != 0) {
*(pTeam[count])++ = atof(line.data());
}
}
i++;
}
catch (exception &e) {
cout << " error " << i << endl;
return;
}
}
} else {
cout << "no such file" << filename << endl;
}
}
// w sc lc ks s p kw kh
long ConvAndFcInit(struct Weight *weight, int schannel, int lchannel, int kersize,
int stride, int pad, int w, int h, int padw, int padh) {
weight->selfChannel = schannel;
weight->lastChannel = lchannel;
weight->kernelSize = kersize;
weight->h = h;
weight->w = w;
weight->padh = padh;
weight->padw = padw;
weight->stride = stride;
weight->pad = pad;
weight->pbias = (mydataFmt *) malloc(schannel * sizeof(mydataFmt));
if (weight->pbias == NULL)cout << "Memory request not successful!!!";
memset(weight->pbias, 0, schannel * sizeof(mydataFmt));
long byteLenght;
if (kersize == 0) {
byteLenght = weight->selfChannel * weight->lastChannel * weight->h * weight->w;
} else {
byteLenght = weight->selfChannel * weight->lastChannel * weight->kernelSize * weight->kernelSize;
}
weight->pdata = (mydataFmt *) malloc(byteLenght * sizeof(mydataFmt));
if (weight->pdata == NULL)cout << "Memory request not successful!!!";
memset(weight->pdata, 0, byteLenght * sizeof(mydataFmt));
return byteLenght;
}
void pReluInit(struct pRelu *prelu, int width) {
prelu->width = width;
prelu->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
if (prelu->pdata == NULL)cout << "prelu apply for memory failed!!!!";
memset(prelu->pdata, 0, width * sizeof(mydataFmt));
}
void softmax(const struct pBox *pbox) {
if (pbox->pdata == NULL) {
cout << "the softmax's pdata is NULL , Please check !" << endl;
return;
}
mydataFmt *p2D = pbox->pdata;
mydataFmt *p3D = NULL;
long mapSize = pbox->width * pbox->height;
mydataFmt eleSum = 0;
for (int row = 0; row < pbox->height; row++) {
for (int col = 0; col < pbox->width; col++) {
eleSum = 0;
for (int channel = 0; channel < pbox->channel; channel++) {
p3D = p2D + channel * mapSize;
*p3D = exp(*p3D);
eleSum += *p3D;
}
for (int channel = 0; channel < pbox->channel; channel++) {
p3D = p2D + channel * mapSize;
*p3D = (*p3D) / eleSum;
}
p2D++;
}
}
}
bool cmpScore(struct orderScore lsh, struct orderScore rsh) {
if (lsh.score < rsh.score)
return true;
else
return false;
}
void nms(vector<struct Bbox> &boundingBox_, vector<struct orderScore> &bboxScore_, const mydataFmt overlap_threshold,
string modelname) {
if (boundingBox_.empty()) {
return;
}
std::vector<int> heros;
//sort the score
sort(bboxScore_.begin(), bboxScore_.end(), cmpScore);
int order = 0;
float IOU = 0;
float maxX = 0;
float maxY = 0;
float minX = 0;
float minY = 0;
while (bboxScore_.size() > 0) {
order = bboxScore_.back().oriOrder;
bboxScore_.pop_back();
if (order < 0)continue;
heros.push_back(order);
boundingBox_.at(order).exist = false;//delete it
for (int num = 0; num < boundingBox_.size(); num++) {
if (boundingBox_.at(num).exist) {
//the iou
maxX = (boundingBox_.at(num).x1 > boundingBox_.at(order).x1) ? boundingBox_.at(num).x1
: boundingBox_.at(order).x1;
maxY = (boundingBox_.at(num).y1 > boundingBox_.at(order).y1) ? boundingBox_.at(num).y1
: boundingBox_.at(order).y1;
minX = (boundingBox_.at(num).x2 < boundingBox_.at(order).x2) ? boundingBox_.at(num).x2
: boundingBox_.at(order).x2;
minY = (boundingBox_.at(num).y2 < boundingBox_.at(order).y2) ? boundingBox_.at(num).y2
: boundingBox_.at(order).y2;
//maxX1 and maxY1 reuse
maxX = ((minX - maxX + 1) > 0) ? (minX - maxX + 1) : 0;
maxY = ((minY - maxY + 1) > 0) ? (minY - maxY + 1) : 0;
//IOU reuse for the area of two bbox
IOU = maxX * maxY;
if (!modelname.compare("Union"))
IOU = IOU / (boundingBox_.at(num).area + boundingBox_.at(order).area - IOU);
else if (!modelname.compare("Min")) {
IOU = IOU /
((boundingBox_.at(num).area < boundingBox_.at(order).area) ? boundingBox_.at(num).area
: boundingBox_.at(
order).area);
}
if (IOU > overlap_threshold) {
boundingBox_.at(num).exist = false;
for (vector<orderScore>::iterator it = bboxScore_.begin(); it != bboxScore_.end(); it++) {
if ((*it).oriOrder == num) {
(*it).oriOrder = -1;
break;
}
}
}
}
}
}
for (int i = 0; i < heros.size(); i++)
boundingBox_.at(heros.at(i)).exist = true;
}
void refineAndSquareBbox(vector<struct Bbox> &vecBbox, const int &height, const int &width) {
if (vecBbox.empty()) {
cout << "Bbox is empty!!" << endl;
return;
}
float bbw = 0, bbh = 0, maxSide = 0;
float h = 0, w = 0;
float x1 = 0, y1 = 0, x2 = 0, y2 = 0;
for (vector<struct Bbox>::iterator it = vecBbox.begin(); it != vecBbox.end(); it++) {
if ((*it).exist) {
bbh = (*it).x2 - (*it).x1 + 1;
bbw = (*it).y2 - (*it).y1 + 1;
x1 = (*it).x1 + (*it).regreCoord[1] * bbh;
y1 = (*it).y1 + (*it).regreCoord[0] * bbw;
x2 = (*it).x2 + (*it).regreCoord[3] * bbh;
y2 = (*it).y2 + (*it).regreCoord[2] * bbw;
h = x2 - x1 + 1;
w = y2 - y1 + 1;
maxSide = (h > w) ? h : w;
x1 = x1 + h * 0.5 - maxSide * 0.5;
y1 = y1 + w * 0.5 - maxSide * 0.5;
(*it).x2 = round(x1 + maxSide - 1);
(*it).y2 = round(y1 + maxSide - 1);
(*it).x1 = round(x1);
(*it).y1 = round(y1);
//boundary check
if ((*it).x1 < 0)(*it).x1 = 0;
if ((*it).y1 < 0)(*it).y1 = 0;
if ((*it).x2 > height)(*it).x2 = height - 1;
if ((*it).y2 > width)(*it).y2 = width - 1;
it->area = (it->x2 - it->x1) * (it->y2 - it->y1);
}
}
}
void conv_mergeInit(pBox *output, pBox *c1, pBox *c2, pBox *c3, pBox *c4) {
output->channel = 0;
output->height = c1->height;
output->width = c1->width;
if (c1 != 0) {
output->channel = c1->channel;
if (c2 != 0) {
output->channel += c2->channel;
if (c3 != 0) {
output->channel += c3->channel;
if (c4 != 0) {
output->channel += c4->channel;
}
}
}
}
output->pdata = (mydataFmt *) malloc(output->width * output->height * output->channel * sizeof(mydataFmt));
if (output->pdata == NULL)cout << "the conv_mergeInit is failed!!" << endl;
memset(output->pdata, 0, output->width * output->height * output->channel * sizeof(mydataFmt));
}
void conv_merge(pBox *output, pBox *c1, pBox *c2, pBox *c3, pBox *c4) {
// cout << "output->channel:" << output->channel << endl;
if (c1 != 0) {
long count1 = c1->height * c1->width * c1->channel;
//output->pdata = c1->pdata;
for (long i = 0; i < count1; i++) {
output->pdata[i] = c1->pdata[i];
}
if (c2 != 0) {
long count2 = c2->height * c2->width * c2->channel;
for (long i = 0; i < count2; i++) {
output->pdata[count1 + i] = c2->pdata[i];
}
if (c3 != 0) {
long count3 = c3->height * c3->width * c3->channel;
for (long i = 0; i < count3; i++) {
output->pdata[count1 + count2 + i] = c3->pdata[i];
}
if (c4 != 0) {
long count4 = c4->height * c4->width * c4->channel;
for (long i = 0; i < count4; i++) {
output->pdata[count1 + count2 + count3 + i] = c4->pdata[i];
}
}
}
}
} else { cout << "conv_mergeInit" << endl; }
}
void mulandaddInit(const pBox *inpbox, const pBox *temppbox, pBox *outpBox, float scale) {
outpBox->channel = temppbox->channel;
outpBox->width = temppbox->width;
outpBox->height = temppbox->height;
outpBox->pdata = (mydataFmt *) malloc(outpBox->width * outpBox->height * outpBox->channel * sizeof(mydataFmt));
if (outpBox->pdata == NULL)cout << "the mulandaddInit is failed!!" << endl;
memset(outpBox->pdata, 0, outpBox->width * outpBox->height * outpBox->channel * sizeof(mydataFmt));
}
void mulandadd(const pBox *inpbox, const pBox *temppbox, pBox *outpBox, float scale) {
mydataFmt *ip = inpbox->pdata;
mydataFmt *tp = temppbox->pdata;
mydataFmt *op = outpBox->pdata;
long dis = inpbox->width * inpbox->height * inpbox->channel;
for (long i = 0; i < dis; i++) {
op[i] = ip[i] + tp[i] * scale;
}
}
void BatchNormInit(struct BN *var, struct BN *mean, struct BN *beta, int width) {
var->width = width;
var->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
if (var->pdata == NULL)cout << "prelu apply for memory failed!!!!";
memset(var->pdata, 0, width * sizeof(mydataFmt));
mean->width = width;
mean->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
if (mean->pdata == NULL)cout << "prelu apply for memory failed!!!!";
memset(mean->pdata, 0, width * sizeof(mydataFmt));
beta->width = width;
beta->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
if (beta->pdata == NULL)cout << "prelu apply for memory failed!!!!";
memset(beta->pdata, 0, width * sizeof(mydataFmt));
}
void BatchNorm(struct pBox *pbox, struct BN *var, struct BN *mean, struct BN *beta) {
if (pbox->pdata == NULL) {
cout << "Relu feature is NULL!!" << endl;
return;
}
if ((var->pdata == NULL) || (mean->pdata == NULL) || (beta->pdata == NULL)) {
cout << "the BatchNorm bias is NULL!!" << endl;
return;
}
mydataFmt *pp = pbox->pdata;
mydataFmt *vp = var->pdata;
mydataFmt *mp = mean->pdata;
mydataFmt *bp = beta->pdata;
int gamma = 1;
float epsilon = 0.001;
long dis = pbox->width * pbox->height;
mydataFmt temp = 0;
for (int channel = 0; channel < pbox->channel; channel++) {
temp = gamma / sqrt(((vp[channel]) + epsilon));
for (int col = 0; col < dis; col++) {
*pp = temp * (*pp) + ((bp[channel]) - temp * (mp[channel]));
pp++;
}
}
}