Spaces:
Running
Running
import torch | |
import torch.nn as nn | |
class AddCoordsTh(nn.Module): | |
def __init__(self, x_dim=64, y_dim=64, with_r=False): | |
super(AddCoordsTh, self).__init__() | |
self.x_dim = x_dim | |
self.y_dim = y_dim | |
self.with_r = with_r | |
xx_channel, yy_channel = self._prepare_coords() | |
self.xx_channel = nn.parameter.Parameter(xx_channel, requires_grad=False) | |
self.yy_channel = nn.parameter.Parameter(yy_channel, requires_grad=False) | |
def _prepare_coords(self): | |
xx_ones = torch.ones([1, self.y_dim], dtype=torch.int32) | |
xx_ones = xx_ones.unsqueeze(-1) | |
xx_range = torch.arange(self.x_dim, dtype=torch.int32).unsqueeze(0) | |
xx_range = xx_range.unsqueeze(1) | |
xx_channel = torch.matmul(xx_ones, xx_range) | |
xx_channel = xx_channel.unsqueeze(-1) | |
yy_ones = torch.ones([1, self.x_dim], dtype=torch.int32) | |
yy_ones = yy_ones.unsqueeze(1) | |
yy_range = torch.arange(self.y_dim, dtype=torch.int32).unsqueeze(0) | |
yy_range = yy_range.unsqueeze(-1) | |
yy_channel = torch.matmul(yy_range, yy_ones) | |
yy_channel = yy_channel.unsqueeze(-1) | |
xx_channel = xx_channel.permute(0, 3, 2, 1) | |
yy_channel = yy_channel.permute(0, 3, 2, 1) | |
xx_channel = xx_channel.float() / (self.x_dim - 1) | |
yy_channel = yy_channel.float() / (self.y_dim - 1) | |
xx_channel = xx_channel * 2 - 1 | |
yy_channel = yy_channel * 2 - 1 | |
return xx_channel, yy_channel | |
def forward(self, input_tensor): | |
""" | |
input_tensor: (batch, c, x_dim, y_dim) | |
""" | |
batch_size_tensor = input_tensor.shape[0] | |
xx_channel = self.xx_channel.repeat(batch_size_tensor, 1, 1, 1) | |
yy_channel = self.yy_channel.repeat(batch_size_tensor, 1, 1, 1) | |
ret = torch.cat([input_tensor, xx_channel, yy_channel], dim=1) | |
if self.with_r: | |
rr = torch.sqrt(torch.pow(xx_channel - 0.5, 2) + torch.pow(yy_channel - 0.5, 2)) | |
ret = torch.cat([ret, rr], dim=1) | |
return ret | |