| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| from .BasePIFuNet import BasePIFuNet |
| import functools |
|
|
| from .net_util import * |
| from lib.dataset.PointFeat import PointFeat |
| from lib.dataset.mesh_util import feat_select |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
|
|
| |
|
|
| |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
|
|
| |
|
|
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
|
|
| |
|
|
| |
| |
|
|
| |
|
|
| class ResnetBlock(nn.Module): |
| """Define a Resnet block""" |
|
|
| def __init__(self, dim, padding_type, norm_layer, use_dropout, use_bias, last=False): |
| """Initialize the Resnet block |
| A resnet block is a conv block with skip connections |
| We construct a conv block with build_conv_block function, |
| and implement skip connections in <forward> function. |
| Original Resnet paper: https://arxiv.org/pdf/1512.03385.pdf |
| """ |
| super(ResnetBlock, self).__init__() |
| self.conv_block = self.build_conv_block(dim, padding_type, norm_layer, use_dropout, use_bias, last) |
|
|
| def build_conv_block(self, dim, padding_type, norm_layer, use_dropout, use_bias, last=False): |
| """Construct a convolutional block. |
| Parameters: |
| dim (int) -- the number of channels in the conv layer. |
| padding_type (str) -- the name of padding layer: reflect | replicate | zero |
| norm_layer -- normalization layer |
| use_dropout (bool) -- if use dropout layers. |
| use_bias (bool) -- if the conv layer uses bias or not |
| Returns a conv block (with a conv layer, a normalization layer, and a non-linearity layer (ReLU)) |
| """ |
| conv_block = [] |
| p = 0 |
| if padding_type == 'reflect': |
| conv_block += [nn.ReflectionPad2d(1)] |
| elif padding_type == 'replicate': |
| conv_block += [nn.ReplicationPad2d(1)] |
| elif padding_type == 'zero': |
| p = 1 |
| else: |
| raise NotImplementedError('padding [%s] is not implemented' % padding_type) |
|
|
| conv_block += [nn.Conv2d(dim, dim, kernel_size=3, padding=p, bias=use_bias), norm_layer(dim), nn.ReLU(True)] |
| if use_dropout: |
| conv_block += [nn.Dropout(0.5)] |
|
|
| p = 0 |
| if padding_type == 'reflect': |
| conv_block += [nn.ReflectionPad2d(1)] |
| elif padding_type == 'replicate': |
| conv_block += [nn.ReplicationPad2d(1)] |
| elif padding_type == 'zero': |
| p = 1 |
| else: |
| raise NotImplementedError('padding [%s] is not implemented' % padding_type) |
| if last: |
| conv_block += [nn.Conv2d(dim, dim, kernel_size=3, padding=p, bias=use_bias)] |
| else: |
| conv_block += [nn.Conv2d(dim, dim, kernel_size=3, padding=p, bias=use_bias), norm_layer(dim)] |
|
|
| return nn.Sequential(*conv_block) |
|
|
| def forward(self, x): |
| """Forward function (with skip connections)""" |
| out = x + self.conv_block(x) |
| return out |
|
|
|
|
| class ResnetFilter(nn.Module): |
| """Resnet-based generator that consists of Resnet blocks between a few downsampling/upsampling operations. |
| We adapt Torch code and idea from Justin Johnson's neural style transfer project(https://github.com/jcjohnson/fast-neural-style) |
| """ |
|
|
| def __init__(self, opt, input_nc=3, output_nc=256, ngf=64, norm_layer=nn.BatchNorm2d, use_dropout=False, |
| n_blocks=6, padding_type='reflect'): |
| """Construct a Resnet-based generator |
| Parameters: |
| input_nc (int) -- the number of channels in input images |
| output_nc (int) -- the number of channels in output images |
| ngf (int) -- the number of filters in the last conv layer |
| norm_layer -- normalization layer |
| use_dropout (bool) -- if use dropout layers |
| n_blocks (int) -- the number of ResNet blocks |
| padding_type (str) -- the name of padding layer in conv layers: reflect | replicate | zero |
| """ |
| assert (n_blocks >= 0) |
| super(ResnetFilter, self).__init__() |
| if type(norm_layer) == functools.partial: |
| use_bias = norm_layer.func == nn.InstanceNorm2d |
| else: |
| use_bias = norm_layer == nn.InstanceNorm2d |
|
|
| model = [nn.ReflectionPad2d(3), |
| nn.Conv2d(input_nc, ngf, kernel_size=7, padding=0, bias=use_bias), |
| norm_layer(ngf), |
| nn.ReLU(True)] |
|
|
| n_downsampling = 2 |
| for i in range(n_downsampling): |
| mult = 2 ** i |
| model += [nn.Conv2d(ngf * mult, ngf * mult * 2, kernel_size=3, stride=2, padding=1, bias=use_bias), |
| norm_layer(ngf * mult * 2), |
| nn.ReLU(True)] |
|
|
| mult = 2 ** n_downsampling |
| for i in range(n_blocks): |
| if i == n_blocks - 1: |
| model += [ResnetBlock(ngf * mult, padding_type=padding_type, norm_layer=norm_layer, |
| use_dropout=use_dropout, use_bias=use_bias, last=True)] |
| else: |
| model += [ResnetBlock(ngf * mult, padding_type=padding_type, norm_layer=norm_layer, |
| use_dropout=use_dropout, use_bias=use_bias)] |
|
|
| if opt.use_tanh: |
| model += [nn.Tanh()] |
| self.model = nn.Sequential(*model) |
|
|
| def forward(self, input): |
| """Standard forward""" |
| return self.model(input) |
|
|