paddlepaddle框架5种模型实现车牌识别

模型目录

    • ResNet模型
    • DNN模型
    • LeNet模型
    • AlexNet 网络结构
    • VGG模型

ResNet模型

paddlepaddle框架5种模型实现车牌识别_第1张图片

####################### ResNet
import numpy as np
import argparse
import ast
import paddle
import paddle.fluid as fluid
from paddle.fluid.layer_helper import LayerHelper
from paddle.fluid.dygraph.nn import Conv2D, Pool2D, BatchNorm, Linear
from paddle.fluid.dygraph.base import to_variable
from paddle.fluid import framework
import math
import sys
from paddle.fluid.param_attr import ParamAttr
class ConvBNLayer(fluid.dygraph.Layer):
    def __init__(self,
                 name_scope,
                 num_channels,
                 num_filters,
                 filter_size,
                 stride=1,
                 groups=1,
                 act=None):
        super(ConvBNLayer, self).__init__(name_scope)

        self._conv = Conv2D(
            num_channels=num_channels,
            num_filters=num_filters,
            filter_size=filter_size,
            stride=stride,
            padding=(filter_size - 1) // 2,
            groups=groups,
            act=None,
            bias_attr=False)

        self._batch_norm = BatchNorm(num_filters, act=act)

    def forward(self, inputs):
        y = self._conv(inputs)
        y = self._batch_norm(y)

        return y


class BottleneckBlock(fluid.dygraph.Layer):
    def __init__(self,
                 name_scope,
                 num_channels,
                 num_filters,
                 stride,
                 shortcut=True):
        super(BottleneckBlock, self).__init__(name_scope)

        # 连续三个卷积+BN层
        self.conv0 = ConvBNLayer(
            self.full_name(),
            num_channels=num_channels,
            num_filters=num_filters,
            filter_size=1,
            act='relu')
        self.conv1 = ConvBNLayer(
            self.full_name(),
            num_channels=num_filters,
            num_filters=num_filters,
            filter_size=3,
            stride=stride,
            act='relu')
        self.conv2 = ConvBNLayer(
            self.full_name(),
            num_channels=num_filters,
            num_filters=num_filters * 4,
            filter_size=1,
            act=None)

        # 如果shortcut为false,即不shortcut,则加一个short层
        if not shortcut:
            self.short = ConvBNLayer(
                self.full_name(),
                num_channels=num_channels,
                num_filters=num_filters * 4,
                filter_size=1,
                stride=stride)

        self.shortcut = shortcut

        self._num_channels_out = num_filters * 4

    def forward(self, inputs):
        # 先经过最开始的三个卷积BN层
        y = self.conv0(inputs)
        conv1 = self.conv1(y)
        conv2 = self.conv2(conv1)

        # 如果要shortcut,则直接把inputs给short
        if self.shortcut:
            short = inputs
        else:
            # 如果不shortcut,则用inputs进入名为self.short的卷积BN层,再给short
            short = self.short(inputs)
        
        # 对两个 Tensor 逐元素相加,对应的数学操作符为 +
        y = fluid.layers.elementwise_add(x=short, y=conv2)

        layer_helper = LayerHelper(self.full_name(), act='relu')
        return layer_helper.append_activation(y)


class ResNet(fluid.dygraph.Layer):
    def __init__(self, name_scope, layers=50, class_dim=5):
        super(ResNet, self).__init__(name_scope)

        self.layers = layers
        supported_layers = [50, 101, 152]
        assert layers in supported_layers,             "supported layers are {} but input layer is {}".format(supported_layers, layers)

        if layers == 50:
            depth = [1, 1, 1, 1]
        elif layers == 101:
            depth = [3, 4, 23, 3]
        elif layers == 152:
            depth = [3, 8, 36, 3]
        num_filters = [6, 16, 28, 48]

        # 一个卷积+BN层
        self.conv = ConvBNLayer(
            self.full_name(),
            num_channels=1,
            num_filters=6,
            filter_size=3,
            stride=1,
            act='relu')
        # 一个池化层
        self.pool2d_max = Pool2D(
            pool_size=3,
            pool_stride=1,
            pool_padding=1,
            pool_type='max')

        self.bottleneck_block_list = []
        num_channels = 6
        for block in range(len(depth)):
            shortcut = False
            for i in range(depth[block]):
                # 在每层depth中的第一个的shortcut为false,随后的都是true
                bottleneck_block = self.add_sublayer(
                    'bb_%d_%d' % (block, i),
                    BottleneckBlock(
                        self.full_name(),
                        num_channels=num_channels,
                        num_filters=num_filters[block],
                        stride=2 if i == 0 and block != 0 else 1,
                        shortcut=shortcut))
                num_channels = bottleneck_block._num_channels_out
                self.bottleneck_block_list.append(bottleneck_block)
                shortcut = True
        
        # 再经历一个池化层
        self.pool2d_avg = Pool2D(pool_size=7, pool_type='avg', global_pooling=True)

        import math
        stdv = 1.0 / math.sqrt(2048 * 1.0)
        
        # 最后一个全连接,走你
        self.out = Linear(input_dim=num_channels,
                          output_dim=class_dim,
                          act='softmax',
                          param_attr=fluid.param_attr.ParamAttr(
                              initializer=fluid.initializer.Uniform(-stdv, stdv)))

    def forward(self, inputs, label=None):
        '''
        [128, 1, 20, 20]
        [128, 16, 20, 20]
        [128, 16, 20, 20]
        [128, 64, 20, 20]
        [128, 64, 20, 20]
        [128, 128, 10, 10]
        [128, 128, 10, 10]
        [128, 256, 5, 5]
        [128, 256, 5, 5]
        [128, 512, 3, 3]
        [128, 512, 3, 3]
        [128, 512, 1, 1]
        '''
        # 最开始的卷积和池化
        #print(inputs.shape)
        y = self.conv(inputs)
        #print(y.shape)
        y = self.pool2d_max(y)
        #print(y.shape)
        # y= fluid.layers.dropout(y, 0.1)
        # 进入每个depth
        for bottleneck_block in self.bottleneck_block_list:
            y = bottleneck_block(y)
            #print(y.shape)
            # y= fluid.layers.dropout(y, 0.1)
        # 出来再来个池化
        y = self.pool2d_avg(y)
        #print(y.shape)
        y = fluid.layers.reshape(x=y, shape=[-1, y.shape[1]])
        # 进入全连接层
        y = self.out(y)
        if label is not None:
            acc = fluid.layers.accuracy(input=y, label=label)
            return y, acc
        else:
            return y

DNN模型

class DNN(fluid.dygraph.Layer):
    def __init__(self):
        super(DNN,self).__init__()
        self.hidden1 = Linear(20*20,600,act='relu')
        self.hidden2 = Linear(600,600,act='relu')
        self.hidden3 = Linear(600,600,act='relu')
        self.hidden4 = Linear(600,65,act='softmax')
    def forward(self,input):
        x = fluid.layers.reshape(input, [-1, 400])
        x = self.hidden1(x)
        x= fluid.layers.dropout(x, 0.1)
        x = self.hidden2(x)
        x= fluid.layers.dropout(x, 0.1)
        x = self.hidden3(x)
        x= fluid.layers.dropout(x, 0.1)
        y = self.hidden4(x)
        return y

LeNet模型

class MyLeNet(fluid.dygraph.Layer):
    def __init__(self):
        super(MyLeNet,self).__init__()
        self.hidden1_1 = Conv2D(1,6,5,1) # 通道数: 1 ,卷积核个数:6 ,卷积核大小5(即长宽均为5) , 步长为1
        self.hidden1_2 = Pool2D(pool_size=2,pool_type='max',pool_stride=1) # 池化核:2 ,max_pooling ,池化步长为1
        self.hidden2_1 = Conv2D(6,16,3,1) # 通道数: 6 ,卷积核个数:16,卷积核大小3(即长宽均为3) , 步长为1
        self.hidden2_2 = Pool2D(pool_size=2,pool_type='max',pool_stride=1)
        self.hidden3 = Conv2D(16,32,3,1) # 通道数: 16 ,卷积核个数:32,卷积核大小3(即长宽均为3) , 步长为1
        self.hidden4 = Linear(32*10*10,65,act='softmax')
    def forward(self,input):
        x = self.hidden1_1(input)
        x = self.hidden1_2(x)
        x = self.hidden2_1(x)
        x = self.hidden2_2(x)
        x = self.hidden3(x)
        x = fluid.layers.reshape(x, shape=[-1, 32*10*10])
        y = self.hidden4(x)
        return y

AlexNet 网络结构

class AlexNet(fluid.dygraph.Layer):
    def __init__(self, name_scope, num_classes=1):
        super(AlexNet, self).__init__(name_scope)
        name_scope = self.full_name()
        # AlexNet与LeNet一样也会同时使用卷积和池化层提取图像特征
        # 与LeNet不同的是激活函数换成了‘relu’
        self.conv1 = Conv2D(1, num_filters=16, filter_size=3, stride=1, padding=1, act='relu')
        self.pool1 = Pool2D( pool_size=2, pool_stride=2, pool_type='max')
        self.conv2 = Conv2D(16, num_filters=32, filter_size=3, stride=1, padding=1, act='relu')
        self.pool2 = Pool2D( pool_size=2, pool_stride=2, pool_type='max')
        self.conv3 = Conv2D(32, num_filters=64, filter_size=3, stride=1, padding=1, act='relu')
        # self.conv4 = Conv2D(64, num_filters=128, filter_size=3, stride=1, padding=1, act='relu')
        # self.conv5 = Conv2D(128, num_filters=256, filter_size=3, stride=1, padding=1, act='relu')
        self.pool5 = Pool2D( pool_size=2, pool_stride=2, pool_type='max')

        self.fc1 = fluid.dygraph.Linear(input_dim=256, output_dim=256, act='relu')
        self.drop_ratio1 = 0.1
        self.fc2 = fluid.dygraph.Linear(input_dim=256, output_dim=256, act='relu')
        self.drop_ratio2 = 0.1
        self.fc3 = fluid.dygraph.Linear(input_dim=256, output_dim=num_classes, act='softmax')

        
    def forward(self, x):
        x = self.conv1(x)
        # x= fluid.layers.dropout(x, 0.1)
        x = self.pool1(x)
        x = self.conv2(x)
        # x= fluid.layers.dropout(x, 0.1)
        x = self.pool2(x)
        x = self.conv3(x)
        # x= fluid.layers.dropout(x, 0.1)
        # x = self.conv4(x)
        # x = self.conv5(x)
        x = self.pool5(x)
        # print(x.shape) [128, 64, 2, 2]

        x = fluid.layers.reshape(x, [-1, 256])

        x = self.fc1(x)
        # 在全连接之后使用dropout抑制过拟合
        x= fluid.layers.dropout(x, self.drop_ratio1)
        x = self.fc2(x)
        # 在全连接之后使用dropout抑制过拟合
        x = fluid.layers.dropout(x, self.drop_ratio2)
        x = self.fc3(x)
        return x

VGG模型

class ConvBlock(fluid.dygraph.Layer):
    """
    卷积+池化
    """
    def __init__(self, name_scope, num_channels, num_filters, groups):
        """构造函数"""
        super(ConvBlock, self).__init__(name_scope)

        self._conv2d_list = []
        init_num_channels = num_channels
        for i in range(groups):
            conv2d = self.add_sublayer(
                'bb_%d' % i,
                fluid.dygraph.Conv2D(
                    init_num_channels, num_filters=num_filters, filter_size=3,
                    stride=1, padding=1, act='relu'
                )
            )
            self._conv2d_list.append(conv2d)
            init_num_channels = num_filters

        self._pool = fluid.dygraph.Pool2D(
            pool_size=2, pool_type='max', pool_stride=2
        )

    def forward(self, inputs):
        """前向计算"""
        x = inputs
        for conv in self._conv2d_list:
            x = conv(x)
        x = self._pool(x)
        return x


class VGGNet(fluid.dygraph.Layer):
    """
    VGG网络
    """
    def __init__(self, name_scope, layers=16, class_dim=1000):
        """
        构造函数
        :param name_scope:   命名空间
        :param layers:       具体的层数如VGG-16、VGG-19等
        """
        super(VGGNet, self).__init__(name_scope)
        self.vgg_spec = {
            11: ([1, 1, 2, 2, 2]),
            13: ([2, 2, 2, 2, 2]),
            16: ([2, 2, 3, 3, 3]),
            19: ([2, 2, 4, 4, 4])
        }
        assert layers in self.vgg_spec.keys(), \
            "supported layers are {} but input layer is {}".format(self.vgg_spec.keys(), layers)

        nums = self.vgg_spec[layers]
        self.conv1 = ConvBlock(self.full_name(), num_channels=1, num_filters=16, groups=1)
        self.conv2 = ConvBlock(self.full_name(), num_channels=16, num_filters=32, groups=1)
        self.conv3 = ConvBlock(self.full_name(), num_channels=32, num_filters=64, groups=1)
        self.conv4 = ConvBlock(self.full_name(), num_channels=64, num_filters=128, groups=1)
        self.conv5 = ConvBlock(self.full_name(), num_channels=12, num_filters=12, groups=nums[4])

        fc_dim = 128
        self.fc1 = fluid.dygraph.Linear(input_dim=128, output_dim=fc_dim, act='relu')
        self.fc2 = fluid.dygraph.Linear(input_dim=fc_dim, output_dim=fc_dim, act='relu')
        self.out = fluid.dygraph.Linear(input_dim=fc_dim, output_dim=class_dim, act='softmax')

    def forward(self, inputs, label=None):
        """前向计算"""
        # print(inputs.shape)
        out = self.conv1(inputs)
        out = fluid.layers.dropout(out, dropout_prob=0.15)
        out = self.conv2(out)
        out = fluid.layers.dropout(out, dropout_prob=0.15)
        out = self.conv3(out)
        out = fluid.layers.dropout(out, dropout_prob=0.2)
        out = self.conv4(out)
        out = fluid.layers.dropout(out, dropout_prob=0.2)
        # out = self.conv5(out)
        # out = fluid.layers.dropout(out, dropout_prob=0.15)
        # print(out.shape)
        out = fluid.layers.reshape(out, [-1, 128])

        out = self.fc1(out)
        # out = fluid.layers.batch_norm(out)
        out = fluid.layers.dropout(out, dropout_prob=0.5)
        
        out = self.fc2(out)
        # out = fluid.layers.batch_norm(out)
        out = fluid.layers.dropout(out, dropout_prob=0.5)
        
        out = self.out(out)
        
        if label is not None:
            acc = fluid.layers.accuracy(input=out, label=label)
            return out, acc
        else:
            return out

你可能感兴趣的:(Machine,Learning)