MTCNN(九)更改python与c代码的PReLU为ReLU

32 篇文章 6 订阅
20 篇文章 7 订阅

背景:MTCNN的prelu需要训练,并且prelu需要有参数。prelu改为relu之后,相应的参数量会降低并且实现也更简单。

目的:更改MTCNN的prelu为ReLU,并在python端训练出相应的代码,c端结构改为与python端一致。

参考相关:

MTCNN(三)基于python代码的网络结构更改 https://blog.csdn.net/weixin_36474809/article/details/82856171

 MTCNN(一)训练与运行  https://blog.csdn.net/weixin_36474809/article/details/82752199

目录

一、python端结构的更改与参数训练

1.1 更改的位置

1.2 实验结果

1.3 重新训练与测试

Pnet

Rnet

Onet

二、采用网络结构表

Pnet

Rnet

Onet

三、c代码端结构的更改

3.1 函数的定义

3.2 网络的更改


一、python端结构的更改与参数训练

1.1 更改的位置

更改前的prelu

@layer
    def prelu(self, inp, name):
        with tf.variable_scope(name):
            i = int(inp.get_shape()[-1])
            alpha = self.make_var('alpha', shape=(i,))
            return tf.nn.relu(inp) + tf.multiply(alpha, -tf.nn.relu(-inp))

加上relu

 @layer
    def relu(self, inp, name):
        return tf.nn.relu(inp, name=name)

然后把pnet/rnet/onet中的prelu函数全部改为relu函数。

这里批评一下Notepad++之中的空格总是与python需要的空格不一致。每次编辑好之后还要用spyder再进行一次空格,免得报错。IndentationError: unexpected unindent

网络结构定义之中的更改:prelu改为了relu,(层的名字方便起见暂时没有更改)

class PNet(NetWork):

    def setup(self, task='data', reuse=False):

        with tf.variable_scope('pnet', reuse=reuse):
            (
                self.feed(task) .conv(
                    3,
                    3,
                    10,
                    1,
                    1,
                    padding='VALID',
                    relu=False,
                    name='conv1') .relu(
                    name='ReLU1') .conv(
                    3,
                    3,
                    16,
                    2,
                    2,
                    padding='SAME',
                    relu=False,
                    name='pool1_conv1') .relu(
                    name='pool1_ReLU1') .conv(
                    3,
                    3,
                    32,
                    1,
                    1,
                    padding='VALID',
                    relu=False,
                    name='conv2') .relu(
                    name='ReLU2') .conv(
                    3,
                    3,
                    32,
                    1,
                    1,
                    task=task,
                    padding='VALID',
                    relu=False,
                    name='conv3',
                    wd=self.weight_decay_coeff) .relu(
                    name='ReLU3'))

        if self.mode == 'train':
            if task == 'cls':
                (self.feed('ReLU3')
                     .conv(1, 1, 2, 1, 1, task=task, relu=False,
                           name='pnet/conv4-1', wd=self.weight_decay_coeff))
            elif task == 'bbx':
                (self.feed('ReLU3')
                     .conv(1, 1, 4, 1, 1, task=task, relu=False,
                           name='pnet/conv4-2', wd=self.weight_decay_coeff))
            elif task == 'pts':
                (self.feed('ReLU3')
                     .conv(1, 1, 10, 1, 1, task=task, relu=False,
                           name='pnet/conv4-3', wd=self.weight_decay_coeff))
            self.out_put.append(self.get_output())
        else:
            (self.feed('ReLU3')
                 .conv(1, 1, 2, 1, 1, relu=False, name='pnet/conv4-1')
                 .softmax(name='softmax'))
            self.out_put.append(self.get_output())
            (self.feed('ReLU3')
                 .conv(1, 1, 4, 1, 1, relu=False, name='pnet/conv4-2'))
            self.out_put.append(self.get_output())

1.2 实验结果

初步结果:

后续检验过的结果:mAP  57.85%

1.3 重新训练与测试

Pnet

把其中的prelu改为relu,然后训练。

all trainable variables:
<tf.Variable 'pnet/conv1/weights:0' shape=(3, 3, 3, 10) dtype=float32_ref>
<tf.Variable 'pnet/conv1/biases:0' shape=(10,) dtype=float32_ref>
<tf.Variable 'pnet/pool1_conv1/weights:0' shape=(3, 3, 10, 16) dtype=float32_ref>
<tf.Variable 'pnet/pool1_conv1/biases:0' shape=(16,) dtype=float32_ref>
<tf.Variable 'pnet/conv2/weights:0' shape=(3, 3, 16, 32) dtype=float32_ref>
<tf.Variable 'pnet/conv2/biases:0' shape=(32,) dtype=float32_ref>
<tf.Variable 'pnet/conv3/weights:0' shape=(3, 3, 32, 32) dtype=float32_ref>
<tf.Variable 'pnet/conv3/biases:0' shape=(32,) dtype=float32_ref>
<tf.Variable 'pnet/conv4-1/weights:0' shape=(1, 1, 32, 2) dtype=float32_ref>
<tf.Variable 'pnet/conv4-1/biases:0' shape=(2,) dtype=float32_ref>
<tf.Variable 'pnet/conv4-2/weights:0' shape=(1, 1, 32, 4) dtype=float32_ref>
<tf.Variable 'pnet/conv4-2/biases:0' shape=(4,) dtype=float32_ref>
<tf.Variable 'pnet/conv4-3/weights:0' shape=(1, 1, 32, 10) dtype=float32_ref>
<tf.Variable 'pnet/conv4-3/biases:0' shape=(10,) dtype=float32_ref>
all local variable:
input/input_producer/limit_epochs/epochs:0
input_1/input_producer/limit_epochs/epochs:0

只有卷积核与bias需要训练,没有了prelu的斜率。

Rnet

all trainable variables:
<tf.Variable 'rnet/conv1/weights:0' shape=(3, 3, 3, 28) dtype=float32_ref>
<tf.Variable 'rnet/conv1/biases:0' shape=(28,) dtype=float32_ref>
<tf.Variable 'rnet/pool1_conv1/weights:0' shape=(3, 3, 28, 28) dtype=float32_ref>
<tf.Variable 'rnet/pool1_conv1/biases:0' shape=(28,) dtype=float32_ref>
<tf.Variable 'rnet/conv2/weights:0' shape=(3, 3, 28, 48) dtype=float32_ref>
<tf.Variable 'rnet/conv2/biases:0' shape=(48,) dtype=float32_ref>
<tf.Variable 'rnet/pool2_conv3/weights:0' shape=(3, 3, 48, 48) dtype=float32_ref>
<tf.Variable 'rnet/pool2_conv3/biases:0' shape=(48,) dtype=float32_ref>
<tf.Variable 'rnet/conv3/weights:0' shape=(3, 3, 48, 64) dtype=float32_ref>
<tf.Variable 'rnet/conv3/biases:0' shape=(64,) dtype=float32_ref>
<tf.Variable 'rnet/conv4/weights:0' shape=(576, 128) dtype=float32_ref>
<tf.Variable 'rnet/conv4/biases:0' shape=(128,) dtype=float32_ref>
<tf.Variable 'rnet/conv5-1/weights:0' shape=(128, 2) dtype=float32_ref>
<tf.Variable 'rnet/conv5-1/biases:0' shape=(2,) dtype=float32_ref>
<tf.Variable 'rnet/conv5-2/weights:0' shape=(128, 4) dtype=float32_ref>
<tf.Variable 'rnet/conv5-2/biases:0' shape=(4,) dtype=float32_ref>
<tf.Variable 'rnet/conv5-3/weights:0' shape=(128, 10) dtype=float32_ref>
<tf.Variable 'rnet/conv5-3/biases:0' shape=(10,) dtype=float32_ref>
all local variable:
input/input_producer/limit_epochs/epochs:0

Onet

all trainable variables:
<tf.Variable 'onet/conv1/weights:0' shape=(3, 3, 3, 32) dtype=float32_ref>
<tf.Variable 'onet/conv1/biases:0' shape=(32,) dtype=float32_ref>
<tf.Variable 'onet/conv2/weights:0' shape=(3, 3, 32, 32) dtype=float32_ref>
<tf.Variable 'onet/conv2/biases:0' shape=(32,) dtype=float32_ref>
<tf.Variable 'onet/conv3/weights:0' shape=(3, 3, 32, 64) dtype=float32_ref>
<tf.Variable 'onet/conv3/biases:0' shape=(64,) dtype=float32_ref>
<tf.Variable 'onet/conv4_/weights:0' shape=(3, 3, 64, 64) dtype=float32_ref>
<tf.Variable 'onet/conv4_/biases:0' shape=(64,) dtype=float32_ref>
<tf.Variable 'onet/conv5_/weights:0' shape=(3, 3, 64, 128) dtype=float32_ref>
<tf.Variable 'onet/conv5_/biases:0' shape=(128,) dtype=float32_ref>
<tf.Variable 'onet/conv6_/weights:0' shape=(3, 3, 128, 128) dtype=float32_ref>
<tf.Variable 'onet/conv6_/biases:0' shape=(128,) dtype=float32_ref>
<tf.Variable 'onet/conv5/weights:0' shape=(1152, 256) dtype=float32_ref>
<tf.Variable 'onet/conv5/biases:0' shape=(256,) dtype=float32_ref>
<tf.Variable 'onet/conv6-1/weights:0' shape=(256, 2) dtype=float32_ref>
<tf.Variable 'onet/conv6-1/biases:0' shape=(2,) dtype=float32_ref>
<tf.Variable 'onet/conv6-2/weights:0' shape=(256, 4) dtype=float32_ref>
<tf.Variable 'onet/conv6-2/biases:0' shape=(4,) dtype=float32_ref>
<tf.Variable 'onet/conv6-3/weights:0' shape=(256, 10) dtype=float32_ref>
<tf.Variable 'onet/conv6-3/biases:0' shape=(10,) dtype=float32_ref>
all local variable:
input/input_producer/limit_epochs/epochs:0

二、采用网络结构表

Pnet

Feature size

name

Kernel size

Stride

Padding

12*12*3

conv1

ReLU1

3*3*10

1

Valid

10*10*10

pool1_conv1

pool1_ReLU1

3*3*16

2

Same

5*5*16

conv2

ReLU2

3*3*32

1

Valid

3*3*32

conv3

ReLU3

3*3*32

1

Valid

1*1*32

 

 

 

 

Rnet

Feature size

name

Kernel size

Stride

Padding

24*24*3

conv1

relu1

3*3*28

1

Same

24*24*28

pool1_conv1

pool1_relu1

3*3*282Same
12*12*28

conv2

relu2

3*3*481Same
12*12*48

pool2_conv3

poo2_relu3

3*3*482Same
6*6*48

conv3

relu3

3*3*642Same
3*3*64 

 

 

 

Onet

Feature size

name

Kernel size

Stride

Padding

48*48*3

conv1

relu1

3*3*32

1

Same

48*48*32

conv2

relu2

3*3*32

2

Same

24*24*32

conv3

relu3

3*3*64

1

Same

24*24*64

conv4_

relu4_

3*3*64

2

Same

12*12*64

conv5_

relu5_

3*3*128

2

Same

6*6*128

conv6_

relu6_

3*3*128

2

Same

3*3*128    

三、c代码端结构的更改

3.1 函数的定义

在network.cpp之中

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 += *pb;
            if(*op<0)*op=0;
            op++;
        }
        pb++;
    }
}
void prelu(struct pBox *pbox, mydataFmt *pbias, mydataFmt *prelu_gmma){
    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;
    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++;
    }
}

3.2 网络的更改

因为relu直接将值进行了替换,所以不存在开辟内存空间的问题,只有运算,并且维度一样,可以直接将prelu函数换位relu函数。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祥瑞Coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值