darknet.py 5.6 KB
Newer Older
1
import paddle
littletomatodonkey's avatar
littletomatodonkey 已提交
2 3 4 5 6 7
from paddle import ParamAttr
import paddle.nn as nn
import paddle.nn.functional as F
from paddle.nn import Conv2d, BatchNorm, Linear, Dropout
from paddle.nn import AdaptiveAvgPool2d, MaxPool2d, AvgPool2d
from paddle.nn.initializer import Uniform
W
WuHaobo 已提交
8
import math
9

W
WuHaobo 已提交
10 11 12
__all__ = ["DarkNet53"]


littletomatodonkey's avatar
littletomatodonkey 已提交
13
class ConvBNLayer(nn.Layer):
14 15 16 17 18 19 20 21 22
    def __init__(self,
                 input_channels,
                 output_channels,
                 filter_size,
                 stride,
                 padding,
                 name=None):
        super(ConvBNLayer, self).__init__()

littletomatodonkey's avatar
littletomatodonkey 已提交
23 24 25 26
        self._conv = Conv2d(
            in_channels=input_channels,
            out_channels=output_channels,
            kernel_size=filter_size,
W
WuHaobo 已提交
27 28
            stride=stride,
            padding=padding,
littletomatodonkey's avatar
littletomatodonkey 已提交
29
            weight_attr=ParamAttr(name=name + ".conv.weights"),
W
WuHaobo 已提交
30 31 32
            bias_attr=False)

        bn_name = name + ".bn"
33 34 35 36 37 38 39 40 41 42 43 44 45 46
        self._bn = BatchNorm(
            num_channels=output_channels,
            act="relu",
            param_attr=ParamAttr(name=bn_name + ".scale"),
            bias_attr=ParamAttr(name=bn_name + ".offset"),
            moving_mean_name=bn_name + ".mean",
            moving_variance_name=bn_name + ".var")

    def forward(self, inputs):
        x = self._conv(inputs)
        x = self._bn(x)
        return x


littletomatodonkey's avatar
littletomatodonkey 已提交
47
class BasicBlock(nn.Layer):
48
    def __init__(self, input_channels, output_channels, name=None):
W
wqz960 已提交
49
        super(BasicBlock, self).__init__()
50 51 52 53 54 55 56 57 58

        self._conv1 = ConvBNLayer(
            input_channels, output_channels, 1, 1, 0, name=name + ".0")
        self._conv2 = ConvBNLayer(
            output_channels, output_channels * 2, 3, 1, 1, name=name + ".1")

    def forward(self, inputs):
        x = self._conv1(inputs)
        x = self._conv2(x)
littletomatodonkey's avatar
littletomatodonkey 已提交
59
        return paddle.elementwise_add(x=inputs, y=x)
60 61


littletomatodonkey's avatar
littletomatodonkey 已提交
62
class DarkNet(nn.Layer):
63
    def __init__(self, class_dim=1000):
W
wqz960 已提交
64
        super(DarkNet, self).__init__()
65 66 67 68 69 70

        self.stages = [1, 2, 8, 8, 4]
        self._conv1 = ConvBNLayer(3, 32, 3, 1, 1, name="yolo_input")
        self._conv2 = ConvBNLayer(
            32, 64, 3, 2, 1, name="yolo_input.downsample")

W
wqz960 已提交
71
        self._basic_block_01 = BasicBlock(64, 32, name="stage.0.0")
72 73 74
        self._downsample_0 = ConvBNLayer(
            64, 128, 3, 2, 1, name="stage.0.downsample")

W
wqz960 已提交
75 76
        self._basic_block_11 = BasicBlock(128, 64, name="stage.1.0")
        self._basic_block_12 = BasicBlock(128, 64, name="stage.1.1")
77 78 79
        self._downsample_1 = ConvBNLayer(
            128, 256, 3, 2, 1, name="stage.1.downsample")

W
wqz960 已提交
80 81 82 83 84 85 86 87
        self._basic_block_21 = BasicBlock(256, 128, name="stage.2.0")
        self._basic_block_22 = BasicBlock(256, 128, name="stage.2.1")
        self._basic_block_23 = BasicBlock(256, 128, name="stage.2.2")
        self._basic_block_24 = BasicBlock(256, 128, name="stage.2.3")
        self._basic_block_25 = BasicBlock(256, 128, name="stage.2.4")
        self._basic_block_26 = BasicBlock(256, 128, name="stage.2.5")
        self._basic_block_27 = BasicBlock(256, 128, name="stage.2.6")
        self._basic_block_28 = BasicBlock(256, 128, name="stage.2.7")
88 89 90
        self._downsample_2 = ConvBNLayer(
            256, 512, 3, 2, 1, name="stage.2.downsample")

W
wqz960 已提交
91 92 93 94 95 96 97 98
        self._basic_block_31 = BasicBlock(512, 256, name="stage.3.0")
        self._basic_block_32 = BasicBlock(512, 256, name="stage.3.1")
        self._basic_block_33 = BasicBlock(512, 256, name="stage.3.2")
        self._basic_block_34 = BasicBlock(512, 256, name="stage.3.3")
        self._basic_block_35 = BasicBlock(512, 256, name="stage.3.4")
        self._basic_block_36 = BasicBlock(512, 256, name="stage.3.5")
        self._basic_block_37 = BasicBlock(512, 256, name="stage.3.6")
        self._basic_block_38 = BasicBlock(512, 256, name="stage.3.7")
99 100 101
        self._downsample_3 = ConvBNLayer(
            512, 1024, 3, 2, 1, name="stage.3.downsample")

W
wqz960 已提交
102 103 104 105
        self._basic_block_41 = BasicBlock(1024, 512, name="stage.4.0")
        self._basic_block_42 = BasicBlock(1024, 512, name="stage.4.1")
        self._basic_block_43 = BasicBlock(1024, 512, name="stage.4.2")
        self._basic_block_44 = BasicBlock(1024, 512, name="stage.4.3")
106

littletomatodonkey's avatar
littletomatodonkey 已提交
107
        self._pool = AdaptiveAvgPool2d(1)
108 109 110

        stdv = 1.0 / math.sqrt(1024.0)
        self._out = Linear(
littletomatodonkey's avatar
littletomatodonkey 已提交
111 112 113 114
            1024,
            class_dim,
            weight_attr=ParamAttr(
                name="fc_weights", initializer=Uniform(-stdv, stdv)),
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
            bias_attr=ParamAttr(name="fc_offset"))

    def forward(self, inputs):
        x = self._conv1(inputs)
        x = self._conv2(x)

        x = self._basic_block_01(x)
        x = self._downsample_0(x)

        x = self._basic_block_11(x)
        x = self._basic_block_12(x)
        x = self._downsample_1(x)

        x = self._basic_block_21(x)
        x = self._basic_block_22(x)
        x = self._basic_block_23(x)
        x = self._basic_block_24(x)
        x = self._basic_block_25(x)
        x = self._basic_block_26(x)
        x = self._basic_block_27(x)
        x = self._basic_block_28(x)
        x = self._downsample_2(x)

        x = self._basic_block_31(x)
        x = self._basic_block_32(x)
        x = self._basic_block_33(x)
        x = self._basic_block_34(x)
        x = self._basic_block_35(x)
        x = self._basic_block_36(x)
        x = self._basic_block_37(x)
        x = self._basic_block_38(x)
        x = self._downsample_3(x)

        x = self._basic_block_41(x)
        x = self._basic_block_42(x)
        x = self._basic_block_43(x)
        x = self._basic_block_44(x)

        x = self._pool(x)
littletomatodonkey's avatar
littletomatodonkey 已提交
154
        x = paddle.squeeze(x, axis=[2, 3])
155 156 157 158 159 160
        x = self._out(x)
        return x


def DarkNet53(**args):
    model = DarkNet(**args)
littletomatodonkey's avatar
littletomatodonkey 已提交
161
    return model