Skip to content

Commit 5067067

Browse files
ayay
ay
authored and
ay
committed
First_20200817
0 parents  commit 5067067

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+4231
-0
lines changed

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.pythonPath": "/home/qust116-jq/anaconda3/envs/torch/bin/python"
3+
}

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# 语义分割学习实验-基于VOC数据集
2+
usage:
3+
1. 下载VOC数据集,将`JPEGImages` `SegmentationClass`两个文件夹放入到data文件夹下。
4+
2. 终端切换到目标目录,运行`python train.py -h`查看训练
5+
```bash
6+
(torch) qust116-jq@qustx-X299-WU8:~/语义分割$ python train.py -h
7+
usage: train.py [-h] [-m {Unet,FCN,Deeplab}] [-g GPU]
8+
9+
choose the model
10+
11+
optional arguments:
12+
-h, --help show this help message and exit
13+
-m {Unet,FCN,Deeplab}, --model {Unet,FCN,Deeplab}
14+
输入模型名字
15+
-g GPU, --gpu GPU 输入所需GPU
16+
```
17+
选择模型和GPU编号进行训练,例如运行`python train.py -m Unet -g 0`
18+
19+
3. 预测需要手动修改`predict.py`中的模型

data/test.csv

+544
Large diffs are not rendered by default.

data/train.csv

+1,901
Large diffs are not rendered by default.

data/val.csv

+272
Large diffs are not rendered by default.

model/DeepLab.py

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import torch
2+
import torch.nn as nn
3+
import torch.nn.functional as F
4+
5+
import os
6+
7+
# from model.resnet import ResNet18_OS16, ResNet34_OS16, ResNet50_OS16, ResNet101_OS16, ResNet152_OS16, ResNet18_OS8, ResNet34_OS8
8+
from model.resnet import ResNet18_OS8
9+
# from model.aspp import ASPP, ASPP_Bottleneck
10+
from model.aspp import ASPP
11+
12+
class DeepLabV3(nn.Module):
13+
def __init__(self,num_classes): #, model_id, project_dir
14+
super(DeepLabV3, self).__init__()
15+
16+
self.num_classes = num_classes
17+
18+
# self.model_id = model_id
19+
# self.project_dir = project_dir
20+
# self.create_model_dirs()
21+
22+
self.resnet = ResNet18_OS8() # NOTE! specify the type of ResNet here
23+
self.aspp = ASPP(num_classes=self.num_classes) # NOTE! if you use ResNet50-152, set self.aspp = ASPP_Bottleneck(num_classes=self.num_classes) instead
24+
25+
def forward(self, x):
26+
# (x has shape (batch_size, 3, h, w))
27+
28+
h = x.size()[2]
29+
w = x.size()[3]
30+
31+
feature_map = self.resnet(x) # (shape: (batch_size, 512, h/16, w/16)) (assuming self.resnet is ResNet18_OS16 or ResNet34_OS16. If self.resnet is ResNet18_OS8 or ResNet34_OS8, it will be (batch_size, 512, h/8, w/8). If self.resnet is ResNet50-152, it will be (batch_size, 4*512, h/16, w/16))
32+
33+
output = self.aspp(feature_map) # (shape: (batch_size, num_classes, h/16, w/16))
34+
35+
output = F.upsample(output, size=(h, w), mode="bilinear") # (shape: (batch_size, num_classes, h, w))
36+
37+
return output
38+
39+
# def create_model_dirs(self):
40+
# self.logs_dir = self.project_dir + "/training_logs"
41+
# self.model_dir = self.logs_dir + "/model_%s" % self.model_id
42+
# self.checkpoints_dir = self.model_dir + "/checkpoints"
43+
# if not os.path.exists(self.logs_dir):
44+
# os.makedirs(self.logs_dir)
45+
# if not os.path.exists(self.model_dir):
46+
# os.makedirs(self.model_dir)
47+
# os.makedirs(self.checkpoints_dir)

model/FCN.py

+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# -*- encoding: utf-8 -*-
2+
'''
3+
@File : unet.py
4+
@Time : 2020/08/02 10:19:44
5+
@Author : AngYi
6+
7+
@Department : QDKD shuli
8+
@description :
9+
'''
10+
11+
# here put the import lib
12+
import torch
13+
from torch import nn
14+
from torchvision import models
15+
import numpy as np
16+
17+
pretrained_model=models.vgg16(pretrained=True) #用于 FCN32x FCN16x FCN8x
18+
pretrained_net = models.resnet34(pretrained=True) #用于 FCN8s
19+
20+
def bilinear_kernel(in_channels, out_channels, kernel_size):
21+
'''
22+
return a bilinear filter tensor
23+
双线性卷积核,用于反卷积
24+
'''
25+
factor = (kernel_size + 1) // 2
26+
if kernel_size % 2 == 1:
27+
center = factor - 1
28+
else:
29+
center = factor - 0.5
30+
og = np.ogrid[:kernel_size, :kernel_size]
31+
filt = (1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor)
32+
weight = np.zeros((in_channels, out_channels, kernel_size, kernel_size), dtype='float32')
33+
weight[range(in_channels), range(out_channels), :, :] = filt
34+
return torch.from_numpy(weight)
35+
36+
class FCN32s(nn.Module):
37+
def __init__(self,num_classes):
38+
super(FCN32s, self).__init__()
39+
40+
self.feature=pretrained_model.features
41+
42+
self.conv=nn.Conv2d(512,num_classes, kernel_size=1, stride=1, padding=0)
43+
self.upsample32x=nn.Sequential(
44+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
45+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
46+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
47+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
48+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
49+
)
50+
51+
for m in self.modules():
52+
if isinstance(m,nn.ConvTranspose2d):
53+
m.weight.data.copy_(bilinear_kernel(int(m.in_channels),int(m.out_channels),m.kernel_size[0]))
54+
55+
def forward(self,x):
56+
x=self.feature(x) # 1/32
57+
x=self.conv(x)
58+
x=self.upsample32x(x)
59+
return x
60+
61+
class FCN16s(nn.Module):
62+
def __init__(self,num_classes):
63+
super(FCN16s, self).__init__()
64+
65+
self.feature_1=nn.Sequential(*list(pretrained_model.features.children())[:24])
66+
self.feature_2=nn.Sequential(*list(pretrained_model.features.children())[24:])
67+
68+
self.conv_1=nn.Conv2d(512,num_classes,kernel_size=1,stride=1,padding=0)
69+
self.conv_2=nn.Conv2d(512, num_classes, kernel_size=1, stride=1, padding=0)
70+
71+
self.upsample2x=nn.ConvTranspose2d(num_classes,num_classes,kernel_size=3,stride=2,padding=1,output_padding=1,dilation=1)
72+
self.upsample16x=nn.Sequential(
73+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
74+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
75+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
76+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
77+
)
78+
79+
for m in self.modules():
80+
if isinstance(m,nn.ConvTranspose2d):
81+
m.weight.data.copy_(bilinear_kernel(m.in_channels,m.out_channels,m.kernel_size[0]))
82+
83+
def forward(self, x):
84+
x1=self.feature_1(x)
85+
x2=self.feature_2(x1)
86+
87+
x1=self.conv_1(x1)
88+
x2=self.conv_2(x2)
89+
x2=self.upsample2x(x2)
90+
x2+=x1
91+
92+
x2=self.upsample16x(x2)
93+
return x2
94+
95+
96+
class FCN8s(nn.Module):
97+
def __init__(self, num_classes):
98+
super(FCN8s, self).__init__()
99+
100+
self.feature_1 = nn.Sequential(*list(pretrained_model.features.children())[:17])
101+
self.feature_2 = nn.Sequential(*list(pretrained_model.features.children())[17:24])
102+
self.feature_3 = nn.Sequential(*list(pretrained_model.features.children())[24:])
103+
104+
self.conv_1 = nn.Conv2d(512,num_classes, kernel_size=1, stride=1, padding=0)
105+
self.conv_2=nn.Conv2d(256,num_classes,kernel_size=1, stride=1, padding=0)
106+
self.conv_3=nn.Conv2d(512,num_classes, kernel_size=1, stride=1, padding=0)
107+
108+
self.upsample2x_1 = nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, output_padding=1, dilation=1)
109+
self.upsample2x_2 = nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, output_padding=1,dilation=1)
110+
self.upsample8x = nn.Sequential(
111+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
112+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
113+
nn.ConvTranspose2d(num_classes, num_classes, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1),
114+
)
115+
116+
for m in self.modules():
117+
if isinstance(m, nn.ConvTranspose2d):
118+
m.weight.data=bilinear_kernel(m.in_channels, m.out_channels, m.kernel_size[0])
119+
120+
def forward(self, x):
121+
x1 = self.feature_1(x)
122+
x2 = self.feature_2(x1)
123+
x3=self.feature_3(x2)
124+
125+
x2=self.conv_1(x2)
126+
x3=self.conv_3(x3)
127+
x3=self.upsample2x_1(x3)
128+
x3+=x2
129+
130+
x1=self.conv_2(x1)
131+
x3=self.upsample2x_2(x3)
132+
x3+=x1
133+
134+
x3=self.upsample8x(x3)
135+
return x3
136+
137+
class FCN8x(nn.Module):
138+
def __init__(self, num_classes):
139+
super(FCN8x, self).__init__()
140+
141+
self.stage1 = nn.Sequential(*list(pretrained_net.children())[:-4]) # 第一段
142+
self.stage2 = list(pretrained_net.children())[-4] # 第二段
143+
self.stage3 = list(pretrained_net.children())[-3] # 第三段
144+
145+
self.scores1 = nn.Conv2d(512, num_classes, 1)
146+
self.scores2 = nn.Conv2d(256, num_classes, 1)
147+
self.scores3 = nn.Conv2d(128, num_classes, 1)
148+
149+
self.upsample_8x = nn.ConvTranspose2d(num_classes, num_classes, 16, 8, 4, bias=False)
150+
self.upsample_8x.weight.data = bilinear_kernel(num_classes, num_classes, 16) # 使用双线性 kernel
151+
152+
self.upsample_4x = nn.ConvTranspose2d(num_classes, num_classes, 4, 2, 1, bias=False)
153+
self.upsample_4x.weight.data = bilinear_kernel(num_classes, num_classes, 4) # 使用双线性 kernel
154+
155+
self.upsample_2x = nn.ConvTranspose2d(num_classes, num_classes, 4, 2, 1, bias=False)
156+
self.upsample_2x.weight.data = bilinear_kernel(num_classes, num_classes, 4) # 使用双线性 kernel
157+
158+
def forward(self, x):
159+
x = self.stage1(x)
160+
s1 = x # 1/8
161+
162+
x = self.stage2(x)
163+
s2 = x # 1/16
164+
165+
x = self.stage3(x)
166+
s3 = x # 1/32
167+
168+
s3 = self.scores1(s3)
169+
s3 = self.upsample_2x(s3)
170+
s2 = self.scores2(s2)
171+
s2 = s2 + s3
172+
173+
s1 = self.scores3(s1)
174+
s2 = self.upsample_4x(s2)
175+
s = s1 + s2
176+
177+
s = self.upsample_8x(s2)
178+
return s
179+
180+
181+
182+
183+
184+
185+
186+
if __name__ == "__main__":
187+
pass
188+
from torchsummary import summary
189+
fcn = FCN32s(3)
190+
# fcn.cuda(1)
191+
# summary(fcn,(3,128,128))
192+
# pretrained_model.cuda(1)
193+
# summary(pretrained_model,(3,128,128))

model/Unet.py

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
""" Parts of the U-Net model """
2+
3+
import torch
4+
import torch.nn as nn
5+
import torch.nn.functional as F
6+
7+
8+
class DoubleConv(nn.Module):
9+
"""(convolution => [BN] => ReLU) * 2"""
10+
11+
def __init__(self, in_channels, out_channels, mid_channels=None):
12+
super().__init__()
13+
if not mid_channels:
14+
mid_channels = out_channels
15+
self.double_conv = nn.Sequential(
16+
nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1),
17+
nn.BatchNorm2d(mid_channels),
18+
nn.ReLU(inplace=True),
19+
nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1),
20+
nn.BatchNorm2d(out_channels),
21+
nn.ReLU(inplace=True)
22+
)
23+
24+
def forward(self, x):
25+
return self.double_conv(x)
26+
27+
28+
class Down(nn.Module):
29+
"""Downscaling with maxpool then double conv"""
30+
31+
def __init__(self, in_channels, out_channels):
32+
super().__init__()
33+
self.maxpool_conv = nn.Sequential(
34+
nn.MaxPool2d(2),
35+
DoubleConv(in_channels, out_channels)
36+
)
37+
38+
def forward(self, x):
39+
return self.maxpool_conv(x)
40+
41+
42+
class Up(nn.Module):
43+
"""Upscaling then double conv"""
44+
45+
def __init__(self, in_channels, out_channels, bilinear=True):
46+
super().__init__()
47+
48+
# if bilinear, use the normal convolutions to reduce the number of channels
49+
if bilinear:
50+
self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
51+
self.conv = DoubleConv(in_channels, out_channels, in_channels // 2)
52+
else:
53+
self.up = nn.ConvTranspose2d(in_channels , in_channels // 2, kernel_size=2, stride=2)
54+
self.conv = DoubleConv(in_channels, out_channels)
55+
56+
57+
def forward(self, x1, x2):
58+
x1 = self.up(x1)
59+
# input is CHW
60+
diffY = x2.size()[2] - x1.size()[2]
61+
diffX = x2.size()[3] - x1.size()[3]
62+
63+
x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
64+
diffY // 2, diffY - diffY // 2])
65+
# if you have padding issues, see
66+
# https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a
67+
# https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd
68+
x = torch.cat([x2, x1], dim=1)
69+
return self.conv(x)
70+
71+
72+
class OutConv(nn.Module):
73+
def __init__(self, in_channels, out_channels):
74+
super(OutConv, self).__init__()
75+
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)
76+
77+
def forward(self, x):
78+
return self.conv(x)
79+
80+
81+
""" Full assembly of the parts to form the complete network """
82+
83+
import torch.nn.functional as F
84+
85+
86+
87+
class UNet(nn.Module):
88+
def __init__(self, n_channels, n_classes, bilinear=True):
89+
super(UNet, self).__init__()
90+
self.n_channels = n_channels
91+
self.n_classes = n_classes
92+
self.bilinear = bilinear
93+
94+
self.inc = DoubleConv(n_channels, 64)
95+
self.down1 = Down(64, 128)
96+
self.down2 = Down(128, 256)
97+
self.down3 = Down(256, 512)
98+
factor = 2 if bilinear else 1
99+
self.down4 = Down(512, 1024 // factor)
100+
self.up1 = Up(1024, 512 // factor, bilinear)
101+
self.up2 = Up(512, 256 // factor, bilinear)
102+
self.up3 = Up(256, 128 // factor, bilinear)
103+
self.up4 = Up(128, 64, bilinear)
104+
self.outc = OutConv(64, n_classes)
105+
106+
def forward(self, x):
107+
x1 = self.inc(x)
108+
x2 = self.down1(x1)
109+
x3 = self.down2(x2)
110+
x4 = self.down3(x3)
111+
x5 = self.down4(x4)
112+
x = self.up1(x5, x4)
113+
x = self.up2(x, x3)
114+
x = self.up3(x, x2)
115+
x = self.up4(x, x1)
116+
logits = self.outc(x)
117+
return logits
118+
1.03 KB
Binary file not shown.

model/__pycache__/FCN.cpython-37.pyc

5.36 KB
Binary file not shown.

model/__pycache__/FCN.cpython-38.pyc

5.21 KB
Binary file not shown.

model/__pycache__/Unet.cpython-38.pyc

3.71 KB
Binary file not shown.

model/__pycache__/aspp.cpython-38.pyc

2.72 KB
Binary file not shown.
6.32 KB
Binary file not shown.

0 commit comments

Comments
 (0)