最近跟随百度的老师,完成了7天的语义分割课程,终于手把手带我搭建了框架,欢饮雀跃哈哈
想参与的详见课程链接百度7天分割课程
作业内容
import numpy as np
import paddle.fluid as fluid
from paddle.fluid.dygraph import to_variable
from paddle.fluid.dygraph import Layer
from paddle.fluid.dygraph import Conv2D
from paddle.fluid.dygraph import BatchNorm
from paddle.fluid.dygraph import Dropout
from resnet_dilated import ResNet50
# pool with different bin_size
# interpolate back to input size
# concat
class PSPModule(Layer):
def __init__(self,num_channels,bin_size_list):
super(PSPModule,self).__init__()
self.bin_size_list = bin_size_list
num_filters = num_channels //len(bin_size_list)
self.features = []
#融合部分
for i in range(len(bin_size_list)):
self.features.append(
fluid.dygraph.Sequential(
Conv2D(num_channels,num_filters,1),
BatchNorm(num_filters,act='relu')
)
)
def forward(self,inputs):
out = [inputs]
for idx,f in enumerate(self.features):
x = fluid.layers.adaptive_pool2d(inputs,self.bin_size_list[idx])
x = f(x)
x = fluid.layers.interpolate(x,inputs.shape[2::],align_corners=True)
out.append(x)
#out is list
out = fluid.layers.concat(out,axis=1) #NCHW
return out
class PSPNet(Layer):
def __init__(self, num_classes=59, backbone='resnet50'):
super(PSPNet, self).__init__()
res = ResNet50(False)
# stem: res.conv, res.pool2d_max
self.layer0 = fluid.dygraph.Sequential(
res.conv,
res.pool2d_max
)
self.layer1 =res.layer1
self.layer2 =res.layer2
self.layer3 =res.layer3
self.layer4 =res.layer4
# psp: 2048 -> 2048*2
num_channels = 2048
self.pspmodule = PSPModule(num_channels,[1,2,3,6])
num_channels *= 2
# cls: 2048*2 -> 512 -> num_classes
self.classifier = fluid.dygraph.Sequential(
Conv2D(num_channels=num_channels,num_filters=512,filter_size=3,padding=1),
BatchNorm(512,'relu'),
Dropout(0.1),
Conv2D(num_channels= 512,num_filters=num_classes,filter_size=1),
)
# aux: 1024 -> 256 -> num_classes
def forward(self, inputs):
x = self.layer0(inputs)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.pspmodule(x)
x = self.classifier(x)
x = fluid.layers.interpolate(x,inputs.shape[2::],align_corners=True)
return x
# aux: tmp_x = layer3
def main():
with fluid.dygraph.guard(fluid.CPUPlace()):
x_data=np.random.rand(2,3, 473, 473).astype(np.float32)
x = to_variable(x_data)
model = PSPNet(num_classes=59)
model.train()
pred, aux = model(x)
print(pred.shape, aux.shape)
if __name__ =="__main__":
main()
import cv2
import numpy as np
import random
import numbers
import collections
import sys
from basic_dataloader import BasicDataLoader
import os
if sys.version_info < (3, 3):
Sequence = collections.Sequence
Iterable = collections.Iterable
else:
Sequence = collections.abc.Sequence
Iterable = collections.abc.Iterable
class Compose(object):
def __init__(self, transforms):
self.transforms = transforms
def __call__(self, image, label=None):
for t in self.transforms:
image, label = t(image, label)
return image, label
class Normalize(object):
def __init__(self, mean_val, std_val, val_scale=1):
# set val_scale = 1 if mean and std are in range (0,1)
# set val_scale to other value, if mean and std are in range (0,255)
self.mean = np.array(mean_val, dtype=np.float32)
self.std = np.array(std_val, dtype=np.float32)
self.val_scale = 1 / 255.0 if val_scale == 1 else 1
def __call__(self, image, label=None):
image = image.astype(np.float32)