Skip to content

Commit

Permalink
batchnorm and scale on vector and image, fix Tencent#331
Browse files Browse the repository at this point in the history
  • Loading branch information
nihui authored and ghimiredhikura committed Jul 26, 2020
1 parent ab61263 commit 33c7ff2
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 61 deletions.
4 changes: 4 additions & 0 deletions src/layer/arm/batchnorm_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ DEFINE_LAYER_CREATOR(BatchNorm_arm)

int BatchNorm_arm::forward_inplace(Mat& bottom_top_blob) const
{
int dims = bottom_top_blob.dims;
if (dims != 3)
return BatchNorm::forward_inplace(bottom_top_blob);

// a = bias - slope * mean / sqrt(var)
// b = slope / sqrt(var)
// value = b * value + a
Expand Down
4 changes: 4 additions & 0 deletions src/layer/arm/scale_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ DEFINE_LAYER_CREATOR(Scale_arm)

int Scale_arm::forward_inplace(Mat& bottom_top_blob) const
{
int dims = bottom_top_blob.dims;
if (dims != 3)
return Scale::forward_inplace(bottom_top_blob);

int w = bottom_top_blob.w;
int h = bottom_top_blob.h;
int channels = bottom_top_blob.c;
Expand Down
56 changes: 46 additions & 10 deletions src/layer/batchnorm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,57 @@ int BatchNorm::forward_inplace(Mat& bottom_top_blob) const
// b = slope / sqrt(var)
// value = b * value + a

int w = bottom_top_blob.w;
int h = bottom_top_blob.h;
int size = w * h;
int dims = bottom_top_blob.dims;

#pragma omp parallel for
for (int q=0; q<channels; q++)
if (dims == 1)
{
float* ptr = bottom_top_blob.channel(q);
int w = bottom_top_blob.w;

float a = a_data[q];
float b = b_data[q];
float* ptr = bottom_top_blob;

for (int i=0; i<size; i++)
#pragma omp parallel for
for (int i=0; i<w; i++)
{
ptr[i] = b * ptr[i] + a;
ptr[i] = b_data[i] * ptr[i] + a_data[i];
}
}

if (dims == 2)
{
int w = bottom_top_blob.w;
int h = bottom_top_blob.h;

#pragma omp parallel for
for (int i=0; i<h; i++)
{
float* ptr = bottom_top_blob.row(i);
float a = a_data[i];
float b = b_data[i];

for (int j=0; j<w; j++)
{
ptr[j] = b * ptr[j] + a;
}
}
}

if (dims == 3)
{
int w = bottom_top_blob.w;
int h = bottom_top_blob.h;
int size = w * h;

#pragma omp parallel for
for (int q=0; q<channels; q++)
{
float* ptr = bottom_top_blob.channel(q);
float a = a_data[q];
float b = b_data[q];

for (int i=0; i<size; i++)
{
ptr[i] = b * ptr[i] + a;
}
}
}

Expand Down
134 changes: 83 additions & 51 deletions src/layer/scale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,86 +59,118 @@ int Scale::forward_inplace(std::vector<Mat>& bottom_top_blobs) const
Mat& bottom_top_blob = bottom_top_blobs[0];
const Mat& scale_blob = bottom_top_blobs[1];

int w = bottom_top_blob.w;
int h = bottom_top_blob.h;
int channels = bottom_top_blob.c;
int size = w * h;
int dims = bottom_top_blob.dims;

if (bias_term)
if (dims == 1)
{
#pragma omp parallel for
for (int q=0; q<channels; q++)
{
float* ptr = bottom_top_blob.channel(q);
int w = bottom_top_blob.w;

float s = scale_blob[q];
float bias = bias_data[q];
float* ptr = bottom_top_blob;

for (int i=0; i<size; i++)
if (bias_term)
{
#pragma omp parallel for
for (int i=0; i<w; i++)
{
ptr[i] = ptr[i] * s + bias;
ptr[i] = ptr[i] * scale_blob[i] + bias_data[i];
}
}
}
else
{
#pragma omp parallel for
for (int q=0; q<channels; q++)
else
{
float* ptr = bottom_top_blob.channel(q);

float s = scale_blob[q];

for (int i=0; i<size; i++)
#pragma omp parallel for
for (int i=0; i<w; i++)
{
ptr[i] *= s;
ptr[i] *= scale_blob[i];
}
}
}

return 0;
}

int Scale::forward_inplace(Mat& bottom_top_blob) const
{
int w = bottom_top_blob.w;
int h = bottom_top_blob.h;
int channels = bottom_top_blob.c;
int size = w * h;

if (bias_term)
if (dims == 2)
{
#pragma omp parallel for
for (int q=0; q<channels; q++)
{
float* ptr = bottom_top_blob.channel(q);

float s = scale_data[q];
float bias = bias_data[q];
int w = bottom_top_blob.w;
int h = bottom_top_blob.h;

for (int i=0; i<size; i++)
if (bias_term)
{
#pragma omp parallel for
for (int i=0; i<h; i++)
{
ptr[i] = ptr[i] * s + bias;
float* ptr = bottom_top_blob.row(i);
float s = scale_blob[i];
float bias = bias_data[i];

for (int j=0; j<w; j++)
{
ptr[j] = ptr[j] * s + bias;
}
}
}
else
{
#pragma omp parallel for
for (int i=0; i<h; i++)
{
float* ptr = bottom_top_blob.row(i);
float s = scale_blob[i];

for (int j=0; j<w; j++)
{
ptr[j] *= s;
}
}
}
}
else

if (dims == 3)
{
#pragma omp parallel for
for (int q=0; q<channels; q++)
int w = bottom_top_blob.w;
int h = bottom_top_blob.h;
int channels = bottom_top_blob.c;
int size = w * h;

if (bias_term)
{
float* ptr = bottom_top_blob.channel(q);
#pragma omp parallel for
for (int q=0; q<channels; q++)
{
float* ptr = bottom_top_blob.channel(q);

float s = scale_data[q];
float s = scale_blob[q];
float bias = bias_data[q];

for (int i=0; i<size; i++)
for (int i=0; i<size; i++)
{
ptr[i] = ptr[i] * s + bias;
}
}
}
else
{
#pragma omp parallel for
for (int q=0; q<channels; q++)
{
ptr[i] *= s;
float* ptr = bottom_top_blob.channel(q);

float s = scale_blob[q];

for (int i=0; i<size; i++)
{
ptr[i] *= s;
}
}
}
}

return 0;
}

int Scale::forward_inplace(Mat& bottom_top_blob) const
{
std::vector<Mat> bottom_top_blobs(2);
bottom_top_blobs[0] = bottom_top_blob;
bottom_top_blobs[1] = scale_data;

return forward_inplace(bottom_top_blobs);
}

} // namespace ncnn

0 comments on commit 33c7ff2

Please sign in to comment.