FCN模型讲解
发表于:2025-02-24 | 分类: 语义分割
字数统计: 566 | 阅读时长: 3分钟 | 阅读量:
1
2
3
4
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
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
class FCN_VGG16(nn.Module):
'''
FCN 的 backbone,由 VGG16 修改而来,舍弃最后的全连接层
以池化层为区分,一个池化层到上一个池化层之间的部分认为一个卷积块。
'''
def __init__(self):
super(FCN_VGG16, self).__init__()
self.features = nn.Sequential(
# 第一个卷积块: 输入通道数:3,输出通道数:64,卷积核大小:3*3,步长:1,填充:1
nn.Conv2d(in_channels=3, out_channels=64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
# 第二个卷积块
nn.Conv2d(in_channels=64, out_channels=128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=128, out_channels=128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
# 第三个卷积块
nn.Conv2d(in_channels=128, out_channels=256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=256, out_channels=256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=256, out_channels=256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
# 第四个卷积块
nn.Conv2d(in_channels=256, out_channels=512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=512,out_channels=512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
# 第五个卷积块
nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
)

# 每一层在 features 中的范围,{0,1,2,3,4} 为第一个卷积块,{5,6,7,8,9} 为第二个卷积块...
self.range = ((0, 5), (5, 10), (10, 17), (17, 24), (24, 31))

def forward(self, input):
output = {}
# 每一块的输出
for idx, (start, end) in enumerate(self.range):
for layer in range(start, end):
input = self.features[layer](input)
output["x%d" % (idx + 1)] = input
return output
1
2
3
4
5
6
7
8
9
10
def test_vgg():
# Backbone 的测试函数
input_x = torch.randn((1,3,512,512))
vgg = FCN_VGG16()
output_y = vgg(input_x)

for key in output_y:
print(output_y[key].size())

test_vgg()

Snipaste_2025-02-25_10-19-29

上一篇:
FCN
下一篇:
语义分割基础