Life sucks, but you're gonna love it.

0%

PaddlePaddle|图像分割

Python

pdb - python 自带调试器

1
2
3
4
5
6
7
8
import pdb
pdb.set_tract() #添加断点

#运行之后会出现 (pdb)然后输入值
运行下一行 - n
打印 - p 变量名1 变量名2
退出调试 - q
添加动态断点 - b 添加断点行数 ex. b 23

Paddle Paddle

快速入门

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import paddle.fluid
import numpy as np


# 定义两个constant张量
x1 = fluid.layers.fill_constant(shape=[2, 2], value=1, dtype='int64')
x2 = fluid.layers.fill_constant(shape=[2, 2], value=1, dtype='int64')
# 将两个张量求和
y1 = fluid.layers.sum(x=[x1, x2])

#定义两层的place holder为张量变量 variable name / tensor name
a = fluid.layers.create_tensor(dtype='int64', name='c')
b = fluid.layers.create_tensor(dtype='int64', name='d')

#定义y为两层之和
y = fluid.layers.sum(x=[a, b])

# 创建一个使用CPU的解释器
place = fluid.CPUPlace()
exe = fluid.executor.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())

# 创建一个使用CPU的解释器
place = fluid.CPUPlace()
exe = fluid.executor.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())

# 定义两个要计算的变量
a1 = np.array([3, 2]).astype('int64')
b1 = np.array([1, 1]).astype('int64')

# 进行运算,并把y的结果输出
# feed进去的需要标明是 层名字:变量名
# fetch list是层的variable name
out_a, out_b, result = exe.run(program=fluid.default_main_program(),
feed={'c': a1, 'd': b1},
fetch_list=[a, b, y])
print(out_a, " + ", out_b," = ", result)


定义简单网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import paddle.fluid as fluid
import paddle
import numpy as np
import matplotlib.pyplot as plt
import os

BUF_SIZE = 500
BATCH_SIZE = 20

# preapare data
trainer_reader = paddle.batch(paddle.reader.shuffle(paddle.uci.housing.train()), buf_size=BUF_SIZE)
test_reader = paddle.batch(paddle.reader.shuffle(paddle.uci.housing.test()), buf_size=BUF_SIZE)

# build net
x = fluid.layers.data(name='x', shape=[13], dtype='float32')
y_predict=fluid.layers.fc(input=x,size=1,act=None) #定义一个简单的线性网络,连接输入和输出的全连接层

y = fluid.layers.data(name='y', shape=[1], dtype='float32') #定义张量y,表示目标值

# define cost function
cost = fluid.layers.square_error_cost(input=y_predict, label=y) #求一个batch的损失值
avg_cost = fluid.layers.mean(cost) #对损失值求平均值

# define optimization function
optimizer = fluid.optimizer.SGDOptimizer(learning_rate=0.001)
opts = optimizer.minimize(avg_cost)
test_program = fluid.default_main_program().clone(for_test=True)

# model training

# build exector
use_cuda = False #use_cuda为False,表示运算场所为CPU;use_cuda为True,表示运算场所为GPU
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
exe = fluid.Executor(place) #创建一个Executor实例exe
exe.run(fluid.default_startup_program()) #Executor的run()方法执行startup_program(),进行参数初始化

feeder = fluid.DataFeeder(place=place, feed_list=[x, y])#feed_list:向模型输入的变量表或变量表名

iter=0;
iters=[]
train_costs=[]

def draw_train_process(iters,train_costs):
title="training cost"
plt.title(title, fontsize=24)
plt.xlabel("iter", fontsize=14)
plt.ylabel("cost", fontsize=14)
plt.plot(iters, train_costs,color='red',label='training cost')
plt.grid()
plt.show()

# save model
EPOCH_NUM=50
model_save_dir = "/home/aistudio/work/fit_a_line.inference.model"

for pass_id in range(EPOCH_NUM): #训练EPOCH_NUM轮
# 开始训练并输出最后一个batch的损失值
train_cost = 0
for batch_id, data in enumerate(train_reader()): #遍历train_reader迭代器
train_cost = exe.run(program=fluid.default_main_program(),#运行主程序
feed=feeder.feed(data), #喂入一个batch的训练数据,根据feed_list和data提供的信息,将输入数据转成一种特殊的数据结构
fetch_list=[avg_cost])
if batch_id % 40 == 0:
print("Pass:%d, Cost:%0.5f" % (pass_id, train_cost[0][0])) #打印最后一个batch的损失值
iter=iter+BATCH_SIZE
iters.append(iter)
train_costs.append(train_cost[0][0])


# 开始测试并输出最后一个batch的损失值
test_cost = 0
for batch_id, data in enumerate(test_reader()): #遍历test_reader迭代器
test_cost= exe.run(program=test_program, #运行测试cheng
feed=feeder.feed(data), #喂入一个batch的测试数据
fetch_list=[avg_cost]) #fetch均方误差
print('Test:%d, Cost:%0.5f' % (pass_id, test_cost[0][0])) #打印最后一个batch的损失值

#保存模型
# 如果保存路径不存在就创建
if not os.path.exists(model_save_dir):
os.makedirs(model_save_dir)
print ('save models to %s' % (model_save_dir))
fluid.io.save_inference_model(model_save_dir, #保存推理model的路径
['x'], #推理(inference)需要 feed 的数据
[y_predict], #保存推理(inference)结果的 Variables
exe) #exe 保存 inference model
draw_train_process(iters,train_costs)


# model prediction

infer_exe = fluid.Executor(place) #创建推测用的executor
inference_scope = fluid.core.Scope() #Scope指定作用域

infer_results=[]
groud_truths=[]

#绘制真实值和预测值对比图
def draw_infer_result(groud_truths,infer_results):
title='Boston'
plt.title(title, fontsize=24)
x = np.arange(1,20)
y = x
plt.plot(x, y)
plt.xlabel('ground truth', fontsize=14)
plt.ylabel('infer result', fontsize=14)
plt.scatter(groud_truths, infer_results,color='green',label='training cost')
plt.grid()
plt.show()

with fluid.scope_guard(inference_scope):#修改全局/默认作用域(scope), 运行时中的所有变量都将分配给新的scope。
#从指定目录中加载 推理model(inference model)
[inference_program, #推理的program
feed_target_names, #需要在推理program中提供数据的变量名称
fetch_targets] = fluid.io.load_inference_model(#fetch_targets: 推断结果
model_save_dir, #model_save_dir:模型训练路径
infer_exe) #infer_exe: 预测用executor
#获取预测数据
infer_reader = paddle.batch(paddle.dataset.uci_housing.test(), #获取uci_housing的测试数据
batch_size=200) #从测试数据中读取一个大小为200的batch数据
#从test_reader中分割x
test_data = next(infer_reader())
test_x = np.array([data[0] for data in test_data]).astype("float32")
test_y= np.array([data[1] for data in test_data]).astype("float32")
results = infer_exe.run(inference_program, #预测模型
feed={feed_target_names[0]: np.array(test_x)}, #喂入要预测的x值
fetch_list=fetch_targets) #得到推测结果

print("infer results: (House Price)")
for idx, val in enumerate(results[0]):
print("%d: %.2f" % (idx, val))
infer_results.append(val)
print("ground truth:")
for idx, val in enumerate(test_y):
print("%d: %.2f" % (idx, val))
groud_truths.append(val)
draw_infer_result(groud_truths,infer_results)

Class 1 语义分割 intro

图像分割的类型

  1. Image Segmentation
  2. Image Semantic Segmentation - 给每个pixel分类
  3. Image Instance Segmentation - 检测相关,给每个object 分mask cat1 cat2
  4. Image Panomic Segmentation - 背景pixel分类+框里mask
  5. Video Object Segmentation - 通常会给定目标mask
  6. Video Instance Segmentation

语义分割算法的基本概念

语义分割算法的根本目的:像素级分类

语义分割算法的基本流程

  1. 输入:图像(rgb) - dataloader imread batchsize
  2. 算法:深度学习模型
  3. 输出:分类结果 (与输入大小一致的单通道图像)
  4. 训练过程:
    1. 输入: image + label
    2. 前向:out = model(inage)
    3. 计算损失
    4. 反向
    5. 更新权重

语义分割性能指标

  • mIoU:分割每一类别的交并比
  • mAcc:pred 和gt 对应位置的“分类”标准率,更趋近于各种不同灰度

为什么acc不够 还要有iou呢?忽略了很重要的一类

实践部分

basic net

basic DataLoader

Fully Convolutional Network. (FCN 全卷积网络)

为什么要用FCN

卷积神经网络首先被分类卷积网络 - 全卷积网络

变大feature map - 上采样/反卷积/unpooling

什么是fcn

双线插值 (bilinear interpolation)

Nchw - nch’w’ 图像放大:简单,快

un-pooling

transpose conv

如何建立一个fcn