定义卷积层+初始化
from torch import nn
def conv_layer(in_channels, out_channles, kernel_size, stride=1, padding=0, bias=True):
layer = nn.Conv2d(in_channels, out_channles, kernel_size, stride, padding, bias=bias)
layer.weight.data.zero_() # 初始化
if bias:
layer.bias.data.zero_()
return layer
反卷积层+初始化
import numpy as np
import torch
from torch import nn
def get_upsampling_weight(in_channels, out_channels, kernel_size):
"""
Make a 2D bilinear kernel suitable for unsampling
"""
factor = (kernel_size + 1) // 2
if kernel_size % 2 == 1:
center = factor - 1
else:
center = factor - 0.5
og = np.ogrid[:kernel_size, :kernel_size]
bilinear_filter = (1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor)
weight = np.zeros((in_channels, out_channels, kernel_size, kernel_size), dtype=np.float32)
weight[range(in_channels), range(out_channels), :, :] = bilinear_filter
return torch.from_numpy(weight).float()
def bilinear_upsampling(in_channels, out_channels, kernel_size, stride, bias=False):
initial_weight = get_upsampling_weight(in_channels, out_channels, kernel_size)
layer = nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride, bias=bias)
layer.weight.data.copy_(initial_weight)
# weight is frozen because it's just a bilinear upsampling
layer.weight.requires_grad = False
return layer
def cross_entropy2d(input, target, weight=None, size_average=True):
# input: (n, c, h, w), target: (n, h, w)
n, c, h, w = input.size()
# log_p: (n, c, h, w)
log_p = F.log_softmax(input, dim=1)
# log_p: (n*h*w, c) # 这里的操作是把背景去掉
log_p = log_p.transpose(1, 2).transpose(2, 3).contiguous()
log_p = log_p[target.view(n, h, w, 1).repeat(1, 1, 1, c) >= 0]
log_p = log_p.view(-1, c)
# target: (n*h*w,)
mask = target >= 0
target = target[mask]
# 比较去掉背景后的两个值
loss = F.nll_loss(log_p, target, weight=weight, reduction='sum')
if size_average:
loss /= mask.data.sum()
return loss
在其他文件,通过以下代码import
from layers.bilinear_upsample import bilinear_upsampling
from layers.conv_layer import conv_layer
from layers.cross_entropy2d import cross_entropy2d