模型目录
- ResNet模型
- DNN模型
- LeNet模型
- AlexNet 网络结构
- VGG模型
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)
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)
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):
y = self.conv0(inputs)
conv1 = self.conv1(y)
conv2 = self.conv2(conv1)
if self.shortcut:
short = inputs
else:
short = self.short(inputs)
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]
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]):
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]
'''
y = self.conv(inputs)
y = self.pool2d_max(y)
for bottleneck_block in self.bottleneck_block_list:
y = bottleneck_block(y)
y = self.pool2d_avg(y)
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)
self.hidden1_2 = Pool2D(pool_size=2,pool_type='max',pool_stride=1)
self.hidden2_1 = Conv2D(6,16,3,1)
self.hidden2_2 = Pool2D(pool_size=2,pool_type='max',pool_stride=1)
self.hidden3 = Conv2D(16,32,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()
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.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 = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.conv3(x)
x = self.pool5(x)
x = fluid.layers.reshape(x, [-1, 256])
x = self.fc1(x)
x= fluid.layers.dropout(x, self.drop_ratio1)
x = self.fc2(x)
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):
"""前向计算"""
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 = fluid.layers.reshape(out, [-1, 128])
out = self.fc1(out)
out = fluid.layers.dropout(out, dropout_prob=0.5)
out = self.fc2(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