refactor
This commit is contained in:
+2
-123
@@ -1,127 +1,11 @@
|
||||
from os import path as osp
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
import torch.nn.parallel
|
||||
|
||||
|
||||
def type_name(m):
|
||||
name = type(m).__name__
|
||||
if name == "TorchObject":
|
||||
name = m._typename.replace("cudnn.", "")
|
||||
return name
|
||||
|
||||
|
||||
def model_tm2pm(model):
|
||||
layer_map = {}
|
||||
for m in model.modules:
|
||||
layer_map[m.name] = tm2pm(m)
|
||||
return layer_map
|
||||
|
||||
|
||||
"""'
|
||||
removed layers: [[ 'ab_conv1_1', 'bw_conv1_1' ]]
|
||||
"""
|
||||
|
||||
ref_color_layernames = [
|
||||
"relu1_1",
|
||||
"conv1_2",
|
||||
"relu1_2",
|
||||
"conv1_2norm",
|
||||
"conv1_2norm_ss",
|
||||
"conv2_1",
|
||||
"relu2_1",
|
||||
"conv2_2",
|
||||
"relu2_2",
|
||||
"conv2_2norm",
|
||||
"conv2_2norm_ss",
|
||||
"conv3_1",
|
||||
"relu3_1",
|
||||
"conv3_2",
|
||||
"relu3_2",
|
||||
"conv3_3",
|
||||
"relu3_3",
|
||||
"conv3_3norm",
|
||||
"conv3_3norm_ss",
|
||||
"conv4_1",
|
||||
"relu4_1",
|
||||
"conv4_2",
|
||||
"relu4_2",
|
||||
"conv4_3",
|
||||
"relu4_3",
|
||||
"conv4_3norm",
|
||||
"conv5_1",
|
||||
"relu5_1",
|
||||
"conv5_2",
|
||||
"relu5_2",
|
||||
"conv5_3",
|
||||
"relu5_3",
|
||||
"conv5_3norm",
|
||||
"conv6_1",
|
||||
"relu6_1",
|
||||
"conv6_2",
|
||||
"relu6_2",
|
||||
"conv6_3",
|
||||
"relu6_3",
|
||||
"conv6_3norm",
|
||||
"conv7_1",
|
||||
"relu7_1",
|
||||
"conv7_2",
|
||||
"relu7_2",
|
||||
"conv7_3",
|
||||
"relu7_3",
|
||||
"conv7_3norm",
|
||||
"conv8_1",
|
||||
"conv3_3_short",
|
||||
"relu8_1_comb",
|
||||
"conv8_2",
|
||||
"relu8_2",
|
||||
"conv8_3",
|
||||
"relu8_3",
|
||||
"conv8_3norm",
|
||||
"conv9_1",
|
||||
"conv2_2_short",
|
||||
"relu9_1_comb",
|
||||
"conv9_2",
|
||||
"relu9_2",
|
||||
"conv9_2norm",
|
||||
"conv10_1",
|
||||
"conv1_2_short",
|
||||
"relu10_1_comb",
|
||||
"conv10_2",
|
||||
"relu10_2",
|
||||
"conv10_ab",
|
||||
]
|
||||
|
||||
|
||||
class ColorVidNet(nn.Module):
|
||||
def __init__(
|
||||
self, ic, ref_color_torch_model="convert_caffe_model/torch_model/reference_model/color_nodist_model.t7"
|
||||
):
|
||||
def __init__(self, ic):
|
||||
super(ColorVidNet, self).__init__()
|
||||
"""torch_model = load_lua(ref_color_torch_model, unknown_classes=True)
|
||||
if type(torch_model).__name__ == 'hashable_uniq_dict':
|
||||
torch_model = torch_model.model
|
||||
|
||||
# fix the ugly typo error
|
||||
for m in torch_model.modules:
|
||||
if m.name == 'conv8_1_comb' and type_name(m) == 'ReLU':
|
||||
m.name = 'relu8_1_comb'
|
||||
|
||||
pytorch_model = model_tm2pm(torch_model)
|
||||
|
||||
self.add_module('conv1_1', nn.Sequential(nn.Conv2d(ic, 32, 3, 1, 1), nn.ReLU(), nn.Conv2d(32, 64, 3, 1, 1), nn.ReLU()))
|
||||
|
||||
for l_name in ref_color_layernames:
|
||||
self.add_module(l_name, pytorch_model[l_name])
|
||||
|
||||
### replace all deconvolution with neareast upsample + convolution
|
||||
assert type(self.conv8_1).__name__=='ConvTranspose2d' and type(self.conv9_1).__name__=='ConvTranspose2d' and \
|
||||
type(self.conv10_1).__name__=='ConvTranspose2d', 'conv8_1, conv9_1, conv10_1 should be all ConvTranspose2d'
|
||||
"""
|
||||
|
||||
##### Written by Ak. #####
|
||||
self.conv1_1 = nn.Sequential(nn.Conv2d(ic, 32, 3, 1, 1), nn.ReLU(), nn.Conv2d(32, 64, 3, 1, 1))
|
||||
self.conv1_2 = nn.Conv2d(64, 64, 3, 1, 1)
|
||||
self.conv1_2norm = nn.BatchNorm2d(64, affine=False)
|
||||
@@ -191,11 +75,8 @@ class ColorVidNet(nn.Module):
|
||||
self.relu9_1_comb = nn.ReLU()
|
||||
self.relu9_2 = nn.ReLU()
|
||||
self.relu10_1_comb = nn.ReLU()
|
||||
# self.relu10_2 = nn.ReLU()
|
||||
self.relu10_2 = nn.LeakyReLU(0.2, True)
|
||||
|
||||
##### Above #####
|
||||
|
||||
print("replace all deconv with [nearest + conv]")
|
||||
self.conv8_1 = nn.Sequential(nn.Upsample(scale_factor=2, mode="nearest"), nn.Conv2d(512, 256, 3, 1, 1))
|
||||
self.conv9_1 = nn.Sequential(nn.Upsample(scale_factor=2, mode="nearest"), nn.Conv2d(256, 128, 3, 1, 1))
|
||||
@@ -211,7 +92,6 @@ class ColorVidNet(nn.Module):
|
||||
self.conv7_3norm = nn.InstanceNorm2d(512)
|
||||
self.conv8_3norm = nn.InstanceNorm2d(256)
|
||||
self.conv9_2norm = nn.InstanceNorm2d(128)
|
||||
# print(self)
|
||||
|
||||
def forward(self, x):
|
||||
""" x: gray image (1 channel), ab(2 channel), ab_err, ba_err"""
|
||||
@@ -260,6 +140,5 @@ class ColorVidNet(nn.Module):
|
||||
conv10_1_comb = self.relu10_1_comb(conv10_1 + conv1_2_short)
|
||||
conv10_2 = self.relu10_2(self.conv10_2(conv10_1_comb))
|
||||
conv10_ab = self.conv10_ab(conv10_2)
|
||||
pred_ab = torch.tanh(conv10_ab) * 128
|
||||
|
||||
return pred_ab
|
||||
return torch.tanh(conv10_ab) * 128
|
||||
|
||||
+11
-24
@@ -1,21 +1,9 @@
|
||||
# from imports import *
|
||||
import torch
|
||||
from utils.tensor_lab2rgb import tensor_lab2rgb
|
||||
from utils.util import *
|
||||
|
||||
if torch.cuda.is_available():
|
||||
device = torch.device("cuda")
|
||||
else:
|
||||
device = troch.device("cpu")
|
||||
|
||||
|
||||
def warp_color(IA_l, IB_lab, features_B, vggnet, nonlocal_net, colornet, feature_noise=0, temperature=0.01):
|
||||
"""
|
||||
joint_train=True, enable grad; otherwise disable grad
|
||||
"""
|
||||
# change to rgb for feature extraction
|
||||
IA_rgb_from_gray = gray2rgb_batch(IA_l)
|
||||
|
||||
with torch.no_grad():
|
||||
A_relu1_1, A_relu2_1, A_relu3_1, A_relu4_1, A_relu5_1 = vggnet(
|
||||
IA_rgb_from_gray, ["r12", "r22", "r32", "r42", "r52"], preprocess=True
|
||||
@@ -34,18 +22,17 @@ def warp_color(IA_l, IB_lab, features_B, vggnet, nonlocal_net, colornet, feature
|
||||
B_relu4_1 = feature_normalize(B_relu4_1)
|
||||
B_relu5_1 = feature_normalize(B_relu5_1)
|
||||
|
||||
# if feature_noise > 0:
|
||||
# A_relu2_1 = A_relu2_1 + torch.randn_like(A_relu2_1, requires_grad=False) * feature_noise
|
||||
# B_relu2_1 = B_relu2_1 + torch.randn_like(B_relu2_1, requires_grad=False) * feature_noise
|
||||
# A_relu3_1 = A_relu3_1 + torch.randn_like(A_relu3_1, requires_grad=False) * feature_noise
|
||||
# B_relu3_1 = B_relu3_1 + torch.randn_like(B_relu3_1, requires_grad=False) * feature_noise
|
||||
# A_relu4_1 = A_relu4_1 + torch.randn_like(A_relu4_1, requires_grad=False) * feature_noise
|
||||
# B_relu4_1 = B_relu4_1 + torch.randn_like(B_relu4_1, requires_grad=False) * feature_noise
|
||||
# A_relu5_1 = A_relu5_1 + torch.randn_like(A_relu5_1, requires_grad=False) * feature_noise
|
||||
# B_relu5_1 = B_relu5_1 + torch.randn_like(B_relu5_1, requires_grad=False) * feature_noise
|
||||
|
||||
nonlocal_BA_lab, similarity_map = nonlocal_net(
|
||||
IB_lab, A_relu2_1, A_relu3_1, A_relu4_1, A_relu5_1, B_relu2_1, B_relu3_1, B_relu4_1, B_relu5_1, temperature=0.01
|
||||
IB_lab,
|
||||
A_relu2_1,
|
||||
A_relu3_1,
|
||||
A_relu4_1,
|
||||
A_relu5_1,
|
||||
B_relu2_1,
|
||||
B_relu3_1,
|
||||
B_relu4_1,
|
||||
B_relu5_1,
|
||||
temperature=temperature,
|
||||
)
|
||||
|
||||
return nonlocal_BA_lab, similarity_map, features_A
|
||||
@@ -64,7 +51,7 @@ def frame_colorization(
|
||||
luminance_noise=0,
|
||||
temperature=0.01,
|
||||
):
|
||||
# change to rgb for feature extraction
|
||||
|
||||
IA_l = IA_lab[:, 0:1, :, :]
|
||||
if luminance_noise:
|
||||
IA_l = IA_l + torch.randn_like(IA_l, requires_grad=False) * luminance_noise
|
||||
|
||||
+11
-31
@@ -81,11 +81,11 @@ class Self_Attention(nn.Module):
|
||||
|
||||
def forward(self, x):
|
||||
"""
|
||||
inputs :
|
||||
x : input feature maps( B X C X W X H)
|
||||
returns :
|
||||
out : self attention value + input feature
|
||||
attention: B X N X N (N is Width*Height)
|
||||
inputs :
|
||||
x : input feature maps( B X C X W X H)
|
||||
returns :
|
||||
out : self attention value + input feature
|
||||
attention: B X N X N (N is Width*Height)
|
||||
"""
|
||||
m_batchsize, C, width, height = x.size()
|
||||
proj_query = self.query_conv(x).view(m_batchsize, -1, width * height).permute(0, 2, 1) # B X CX(N)
|
||||
@@ -98,13 +98,12 @@ class Self_Attention(nn.Module):
|
||||
out = out.view(m_batchsize, C, width, height)
|
||||
|
||||
out = self.gamma * out + x
|
||||
# return out, attention
|
||||
return out
|
||||
|
||||
|
||||
class Discriminator_WITHOUT_FC_x64_video(nn.Module):
|
||||
"""
|
||||
Discriminative Network
|
||||
Discriminative Network
|
||||
"""
|
||||
|
||||
def __init__(self, in_size=6, ndf=64):
|
||||
@@ -137,18 +136,7 @@ class Discriminator_WITHOUT_FC_x64_video(nn.Module):
|
||||
nn.LeakyReLU(0.2, inplace=True),
|
||||
)
|
||||
|
||||
# sate size: (ndf * 8) x 4 x 4
|
||||
# Self_Attention(self.ndf * 8, 'relu')
|
||||
|
||||
self.last = SpectralNorm(nn.Conv2d(self.ndf * 8, 1, [3, 6], 1, 0))
|
||||
# nn.Sigmoid()
|
||||
# state size: 1 x 1 x 1
|
||||
|
||||
# for m in self.modules():
|
||||
# if isinstance(m, nn.Conv2d):
|
||||
# m.weight.data.normal_(0.0, 0.02)
|
||||
# if m.bias is not None:
|
||||
# m.bias.data.zero_()
|
||||
|
||||
def forward(self, input):
|
||||
feature1 = self.layer1(input)
|
||||
@@ -163,7 +151,7 @@ class Discriminator_WITHOUT_FC_x64_video(nn.Module):
|
||||
|
||||
class Discriminator_WITHOUT_FC_x64_video_BIG(nn.Module):
|
||||
"""
|
||||
Discriminative Network
|
||||
Discriminative Network
|
||||
"""
|
||||
|
||||
def __init__(self, in_size=6, ndf=64):
|
||||
@@ -219,7 +207,7 @@ class Discriminator_WITHOUT_FC_x64_video_BIG(nn.Module):
|
||||
|
||||
class Discriminator_WITHOUT_FC_x64(nn.Module):
|
||||
"""
|
||||
Discriminative Network
|
||||
Discriminative Network
|
||||
"""
|
||||
|
||||
def __init__(self, in_size=3, ndf=64):
|
||||
@@ -248,14 +236,6 @@ class Discriminator_WITHOUT_FC_x64(nn.Module):
|
||||
)
|
||||
|
||||
self.last = SpectralNorm(nn.Conv2d(self.ndf * 8, 1, 4, 1, 0))
|
||||
# nn.Sigmoid()
|
||||
# state size: 1 x 1 x 1
|
||||
|
||||
# for m in self.modules():
|
||||
# if isinstance(m, nn.Conv2d):
|
||||
# m.weight.data.normal_(0.0, 0.02)
|
||||
# if m.bias is not None:
|
||||
# m.bias.data.zero_()
|
||||
|
||||
def forward(self, input):
|
||||
|
||||
@@ -268,7 +248,7 @@ class Discriminator_WITHOUT_FC_x64(nn.Module):
|
||||
|
||||
class Discriminator_WITHOUT_FC_x64_BIG(nn.Module):
|
||||
"""
|
||||
Discriminative Network
|
||||
Discriminative Network
|
||||
"""
|
||||
|
||||
def __init__(self, in_size=3, ndf=64):
|
||||
@@ -316,7 +296,7 @@ class Discriminator_WITHOUT_FC_x64_BIG(nn.Module):
|
||||
|
||||
class Discriminator_WITHOUT_FC_x128(nn.Module):
|
||||
"""
|
||||
Discriminative Network
|
||||
Discriminative Network
|
||||
"""
|
||||
|
||||
def __init__(self, in_size=3, ndf=64):
|
||||
@@ -359,7 +339,7 @@ class Discriminator_WITHOUT_FC_x128(nn.Module):
|
||||
|
||||
class Discriminator_WITHOUT_FC_x256(nn.Module):
|
||||
"""
|
||||
Discriminative Network
|
||||
Discriminative Network
|
||||
"""
|
||||
|
||||
def __init__(self, in_size=3, ndf=64):
|
||||
|
||||
+55
-124
@@ -14,12 +14,14 @@ def find_local_patch(x, patch_size):
|
||||
x_unfold = F.unfold(
|
||||
x, kernel_size=(patch_size, patch_size), padding=(patch_size // 2, patch_size // 2), stride=(1, 1)
|
||||
)
|
||||
out = x_unfold.view(N, x_unfold.shape[1], H, W)
|
||||
return out
|
||||
|
||||
return x_unfold.view(N, x_unfold.shape[1], H, W)
|
||||
|
||||
|
||||
class WeightedAverage(nn.Module):
|
||||
def __init__(self,):
|
||||
def __init__(
|
||||
self,
|
||||
):
|
||||
super(WeightedAverage, self).__init__()
|
||||
|
||||
def forward(self, x_lab, patch_size=3, alpha=1, scale_factor=1):
|
||||
@@ -34,14 +36,13 @@ class WeightedAverage(nn.Module):
|
||||
local_difference_l = (local_l - l) ** 2
|
||||
correlation = nn.functional.softmax(-1 * local_difference_l / alpha, dim=1)
|
||||
|
||||
weighted_ab = torch.cat(
|
||||
return torch.cat(
|
||||
(
|
||||
torch.sum(correlation * local_a, dim=1, keepdim=True),
|
||||
torch.sum(correlation * local_b, dim=1, keepdim=True),
|
||||
),
|
||||
1,
|
||||
)
|
||||
return weighted_ab
|
||||
|
||||
|
||||
class WeightedAverage_color(nn.Module):
|
||||
@@ -49,11 +50,13 @@ class WeightedAverage_color(nn.Module):
|
||||
smooth the image according to the color distance in the LAB space
|
||||
"""
|
||||
|
||||
def __init__(self,):
|
||||
def __init__(
|
||||
self,
|
||||
):
|
||||
super(WeightedAverage_color, self).__init__()
|
||||
|
||||
def forward(self, x_lab, x_lab_predict, patch_size=3, alpha=1, scale_factor=1):
|
||||
# alpha=0: less smooth; alpha=inf: smoother
|
||||
""" alpha=0: less smooth; alpha=inf: smoother """
|
||||
x_lab = F.interpolate(x_lab, scale_factor=scale_factor)
|
||||
l = uncenter_l(x_lab[:, 0:1, :, :])
|
||||
a = x_lab[:, 1:2, :, :]
|
||||
@@ -71,18 +74,19 @@ class WeightedAverage_color(nn.Module):
|
||||
-1 * local_color_difference / alpha, dim=1
|
||||
) # so that sum of weights equal to 1
|
||||
|
||||
weighted_ab = torch.cat(
|
||||
return torch.cat(
|
||||
(
|
||||
torch.sum(correlation * local_a_predict, dim=1, keepdim=True),
|
||||
torch.sum(correlation * local_b_predict, dim=1, keepdim=True),
|
||||
),
|
||||
1,
|
||||
)
|
||||
return weighted_ab
|
||||
|
||||
|
||||
class NonlocalWeightedAverage(nn.Module):
|
||||
def __init__(self,):
|
||||
def __init__(
|
||||
self,
|
||||
):
|
||||
super(NonlocalWeightedAverage, self).__init__()
|
||||
|
||||
def forward(self, x_lab, feature, patch_size=3, alpha=0.1, scale_factor=1):
|
||||
@@ -113,56 +117,36 @@ class CorrelationLayer(nn.Module):
|
||||
self.search_range = search_range
|
||||
|
||||
def forward(self, x1, x2, alpha=1, raw_output=False, metric="similarity"):
|
||||
# args = self.args
|
||||
|
||||
shape = list(x1.size())
|
||||
shape[1] = (self.search_range * 2 + 1) ** 2
|
||||
cv = torch.zeros(shape).to(torch.device("cuda"))
|
||||
|
||||
if metric == "similarity":
|
||||
for i in range(-self.search_range, self.search_range + 1):
|
||||
for j in range(-self.search_range, self.search_range + 1):
|
||||
if i < 0:
|
||||
slice_h, slice_h_r = slice(None, i), slice(-i, None)
|
||||
elif i > 0:
|
||||
slice_h, slice_h_r = slice(i, None), slice(None, -i)
|
||||
else:
|
||||
slice_h, slice_h_r = slice(None), slice(None)
|
||||
for i in range(-self.search_range, self.search_range + 1):
|
||||
for j in range(-self.search_range, self.search_range + 1):
|
||||
if i < 0:
|
||||
slice_h, slice_h_r = slice(None, i), slice(-i, None)
|
||||
elif i > 0:
|
||||
slice_h, slice_h_r = slice(i, None), slice(None, -i)
|
||||
else:
|
||||
slice_h, slice_h_r = slice(None), slice(None)
|
||||
|
||||
if j < 0:
|
||||
slice_w, slice_w_r = slice(None, j), slice(-j, None)
|
||||
elif j > 0:
|
||||
slice_w, slice_w_r = slice(j, None), slice(None, -j)
|
||||
else:
|
||||
slice_w, slice_w_r = slice(None), slice(None)
|
||||
if j < 0:
|
||||
slice_w, slice_w_r = slice(None, j), slice(-j, None)
|
||||
elif j > 0:
|
||||
slice_w, slice_w_r = slice(j, None), slice(None, -j)
|
||||
else:
|
||||
slice_w, slice_w_r = slice(None), slice(None)
|
||||
|
||||
# storage sequence (eg. search_range=3): -24, -23, .., -1, 0, 1, ..., 23, 24
|
||||
if metric == "similarity":
|
||||
cv[:, (self.search_range * 2 + 1) * i + j, slice_h, slice_w] = (
|
||||
x1[:, :, slice_h, slice_w] * x2[:, :, slice_h_r, slice_w_r]
|
||||
).sum(1)
|
||||
else: # patchwise subtraction
|
||||
for i in range(-self.search_range, self.search_range + 1):
|
||||
for j in range(-self.search_range, self.search_range + 1):
|
||||
if i < 0:
|
||||
slice_h, slice_h_r = slice(None, i), slice(-i, None)
|
||||
elif i > 0:
|
||||
slice_h, slice_h_r = slice(i, None), slice(None, -i)
|
||||
else:
|
||||
slice_h, slice_h_r = slice(None), slice(None)
|
||||
|
||||
if j < 0:
|
||||
slice_w, slice_w_r = slice(None, j), slice(-j, None)
|
||||
elif j > 0:
|
||||
slice_w, slice_w_r = slice(j, None), slice(None, -j)
|
||||
else:
|
||||
slice_w, slice_w_r = slice(None), slice(None)
|
||||
|
||||
# storage sequence (eg. search_range=3): -24, -23, .., -1, 0, 1, ..., 23, 24
|
||||
else: # patchwise subtraction
|
||||
cv[:, (self.search_range * 2 + 1) * i + j, slice_h, slice_w] = -(
|
||||
(x1[:, :, slice_h, slice_w] - x2[:, :, slice_h_r, slice_w_r]) ** 2
|
||||
).sum(1)
|
||||
|
||||
## TODO sigmoid?
|
||||
# TODO sigmoid?
|
||||
if raw_output:
|
||||
return cv
|
||||
else:
|
||||
@@ -185,11 +169,11 @@ class Self_Attn(nn.Module):
|
||||
|
||||
def forward(self, x):
|
||||
"""
|
||||
inputs :
|
||||
x : input feature maps(B X C X W X H)
|
||||
returns :
|
||||
out : self attention value + input feature
|
||||
attention: B X N X N (N is Width*Height)
|
||||
inputs :
|
||||
x : input feature maps(B X C X W X H)
|
||||
returns :
|
||||
out : self attention value + input feature
|
||||
attention: B X N X N (N is Width*Height)
|
||||
"""
|
||||
m_batchsize, C, width, height = x.size()
|
||||
proj_query = self.query_conv(x).view(m_batchsize, -1, width * height).permute(0, 2, 1) # B X N X C
|
||||
@@ -206,7 +190,7 @@ class Self_Attn(nn.Module):
|
||||
|
||||
|
||||
class VGG19_feature_color_torchversion(nn.Module):
|
||||
"""
|
||||
"""
|
||||
NOTE: no need to pre-process the input; input tensor should range in [0,1]
|
||||
"""
|
||||
|
||||
@@ -242,7 +226,7 @@ class VGG19_feature_color_torchversion(nn.Module):
|
||||
self.pool5 = nn.AvgPool2d(kernel_size=2, stride=2)
|
||||
|
||||
def forward(self, x, out_keys, preprocess=True):
|
||||
"""
|
||||
"""
|
||||
NOTE: input tensor should range in [0,1]
|
||||
"""
|
||||
out = {}
|
||||
@@ -283,8 +267,8 @@ class VGG19_feature_color(nn.Module):
|
||||
"""Extract multiple convolutional feature maps."""
|
||||
features = []
|
||||
for name, layer in self.vgg._modules.items():
|
||||
x = layer(x)
|
||||
if name in self.select:
|
||||
x = layer(x)
|
||||
features.append(x)
|
||||
return features
|
||||
|
||||
@@ -301,70 +285,20 @@ class VGG19_feature(nn.Module):
|
||||
return A_relu3_1, A_relu4_1, A_relu5_1, B_relu3_1, B_relu4_1, B_relu5_1
|
||||
|
||||
|
||||
class VGG19_feature_new(nn.Module):
|
||||
# input: [LLL] channels, range=[0,255]
|
||||
def __init__(self, gpu_ids):
|
||||
super(VGG19_feature_new, self).__init__()
|
||||
self.vgg19_gray_new = vgg19_gray_new().cuda()
|
||||
|
||||
def forward(self, A_l, B_l):
|
||||
A_relu2_1, A_relu3_1, A_relu4_1, A_relu5_1 = self.vgg19_gray_new(A_l)
|
||||
B_relu2_1, B_relu3_1, B_relu4_1, B_relu5_1 = self.vgg19_gray_new(B_l)
|
||||
return A_relu2_1, A_relu3_1, A_relu4_1, A_relu5_1, B_relu2_1, B_relu3_1, B_relu4_1, B_relu5_1
|
||||
|
||||
|
||||
class WTA(torch.autograd.Function):
|
||||
"""
|
||||
We can implement our own custom autograd Functions by subclassing
|
||||
torch.autograd.Function and implementing the forward and backward passes
|
||||
which operate on Tensors.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def forward(ctx, input):
|
||||
"""
|
||||
In the forward pass we receive a Tensor containing the input and return a
|
||||
Tensor containing the output. You can cache arbitrary Tensors for use in the
|
||||
backward pass using the save_for_backward method.
|
||||
"""
|
||||
height = input.shape[2]
|
||||
width = input.shape[3]
|
||||
activation_max, index_max = torch.topk(input, -1, keepdim=True)
|
||||
input_zeros = input * 0
|
||||
output_max_only = torch.where(input == activation_max, input, input_zeros)
|
||||
|
||||
mask = (output_max_only > 0).type(torch.float)
|
||||
ctx.save_for_backward(input, mask)
|
||||
return output_max_only
|
||||
|
||||
@staticmethod
|
||||
def backward(ctx, grad_output):
|
||||
"""
|
||||
In the backward pass we receive a Tensor containing the gradient of the loss
|
||||
with respect to the output, and we need to compute the gradient of the loss
|
||||
with respect to the input.
|
||||
"""
|
||||
# import pdb
|
||||
# pdb.set_trace()
|
||||
input, mask = ctx.saved_tensors
|
||||
grad_input = grad_output.clone() * mask
|
||||
return grad_input
|
||||
|
||||
|
||||
class WTA_scale(torch.autograd.Function):
|
||||
"""
|
||||
We can implement our own custom autograd Functions by subclassing
|
||||
torch.autograd.Function and implementing the forward and backward passes
|
||||
which operate on Tensors.
|
||||
"""
|
||||
We can implement our own custom autograd Functions by subclassing
|
||||
torch.autograd.Function and implementing the forward and backward passes
|
||||
which operate on Tensors.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def forward(ctx, input, scale=1e-4):
|
||||
"""
|
||||
In the forward pass we receive a Tensor containing the input and return a
|
||||
Tensor containing the output. You can cache arbitrary Tensors for use in the
|
||||
backward pass using the save_for_backward method.
|
||||
"""
|
||||
In the forward pass we receive a Tensor containing the input and return a
|
||||
Tensor containing the output. You can cache arbitrary Tensors for use in the
|
||||
backward pass using the save_for_backward method.
|
||||
"""
|
||||
activation_max, index_max = torch.max(input, -1, keepdim=True)
|
||||
input_scale = input * scale # default: 1e-4
|
||||
# input_scale = input * scale # default: 1e-4
|
||||
@@ -377,10 +311,10 @@ class WTA_scale(torch.autograd.Function):
|
||||
@staticmethod
|
||||
def backward(ctx, grad_output):
|
||||
"""
|
||||
In the backward pass we receive a Tensor containing the gradient of the loss
|
||||
with respect to the output, and we need to compute the gradient of the loss
|
||||
with respect to the input.
|
||||
"""
|
||||
In the backward pass we receive a Tensor containing the gradient of the loss
|
||||
with respect to the output, and we need to compute the gradient of the loss
|
||||
with respect to the input.
|
||||
"""
|
||||
# import pdb
|
||||
# pdb.set_trace()
|
||||
input, mask = ctx.saved_tensors
|
||||
@@ -418,9 +352,9 @@ class ResidualBlock(nn.Module):
|
||||
return out
|
||||
|
||||
|
||||
## NOTE: THIS IS THE FINAL VERSION
|
||||
class WarpNet(nn.Module):
|
||||
# input is Al, Bl, channel = 1, range~[0,255]
|
||||
""" input is Al, Bl, channel = 1, range~[0,255] """
|
||||
|
||||
def __init__(self, batch_size):
|
||||
super(WarpNet, self).__init__()
|
||||
self.feature_channel = 64
|
||||
@@ -549,12 +483,9 @@ class WarpNet(nn.Module):
|
||||
similarity_map = similarity_map.view(batch_size, 1, feature_height, feature_width)
|
||||
|
||||
# f can be negative
|
||||
if WTA_scale_weight == 1:
|
||||
f_WTA = f
|
||||
else:
|
||||
f_WTA = WTA_scale.apply(f, WTA_scale_weight)
|
||||
f_WTA = f if WTA_scale_weight == 1 else WTA_scale.apply(f, WTA_scale_weight)
|
||||
f_WTA = f_WTA / temperature
|
||||
f_div_C = F.softmax(f_WTA.squeeze_(), dim=-1) # 2*1936*1936; softmax along the horizontal line (dim=-1)
|
||||
f_div_C = F.softmax(f_WTA.squeeze_(), dim=-1) # 2*1936*1936;
|
||||
|
||||
# downsample the reference color
|
||||
B_lab = F.avg_pool2d(B_lab_map, 4)
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
import torch
|
||||
from torch import nn
|
||||
from torch.autograd import Variable
|
||||
from torch.nn import functional as F
|
||||
|
||||
# from .box_filter import BoxFilter
|
||||
|
||||
|
||||
def diff_x(input, r):
|
||||
assert input.dim() == 4
|
||||
|
||||
left = input[:, :, r : 2 * r + 1]
|
||||
middle = input[:, :, 2 * r + 1 :] - input[:, :, : -2 * r - 1]
|
||||
right = input[:, :, -1:] - input[:, :, -2 * r - 1 : -r - 1]
|
||||
|
||||
output = torch.cat([left, middle, right], dim=2)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def diff_y(input, r):
|
||||
assert input.dim() == 4
|
||||
|
||||
left = input[:, :, :, r : 2 * r + 1]
|
||||
middle = input[:, :, :, 2 * r + 1 :] - input[:, :, :, : -2 * r - 1]
|
||||
right = input[:, :, :, -1:] - input[:, :, :, -2 * r - 1 : -r - 1]
|
||||
|
||||
output = torch.cat([left, middle, right], dim=3)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
class BoxFilter(nn.Module):
|
||||
def __init__(self, r):
|
||||
super(BoxFilter, self).__init__()
|
||||
|
||||
self.r = r
|
||||
|
||||
def forward(self, x):
|
||||
assert x.dim() == 4
|
||||
|
||||
return diff_y(diff_x(x.cumsum(dim=2), self.r).cumsum(dim=3), self.r)
|
||||
|
||||
|
||||
class FastGuidedFilter(nn.Module):
|
||||
def __init__(self, r, eps=1e-8):
|
||||
super(FastGuidedFilter, self).__init__()
|
||||
|
||||
self.r = r
|
||||
self.eps = eps
|
||||
self.boxfilter = BoxFilter(r)
|
||||
|
||||
def forward(self, lr_x, lr_y, hr_x):
|
||||
n_lrx, c_lrx, h_lrx, w_lrx = lr_x.size()
|
||||
n_lry, c_lry, h_lry, w_lry = lr_y.size()
|
||||
n_hrx, c_hrx, h_hrx, w_hrx = hr_x.size()
|
||||
|
||||
assert n_lrx == n_lry and n_lry == n_hrx
|
||||
assert c_lrx == c_hrx and (c_lrx == 1 or c_lrx == c_lry)
|
||||
assert h_lrx == h_lry and w_lrx == w_lry
|
||||
assert h_lrx > 2 * self.r + 1 and w_lrx > 2 * self.r + 1
|
||||
|
||||
## N
|
||||
N = self.boxfilter(Variable(lr_x.data.new().resize_((1, 1, h_lrx, w_lrx)).fill_(1.0)))
|
||||
|
||||
## mean_x
|
||||
mean_x = self.boxfilter(lr_x) / N
|
||||
## mean_y
|
||||
mean_y = self.boxfilter(lr_y) / N
|
||||
## cov_xy
|
||||
cov_xy = self.boxfilter(lr_x * lr_y) / N - mean_x * mean_y
|
||||
## var_x
|
||||
var_x = self.boxfilter(lr_x * lr_x) / N - mean_x * mean_x
|
||||
|
||||
## A
|
||||
A = cov_xy / (var_x + self.eps)
|
||||
## b
|
||||
b = mean_y - A * mean_x
|
||||
|
||||
## mean_A; mean_b
|
||||
mean_A = F.upsample(A, (h_hrx, w_hrx), mode="bilinear")
|
||||
mean_b = F.upsample(b, (h_hrx, w_hrx), mode="bilinear")
|
||||
|
||||
return mean_A * hr_x + mean_b
|
||||
|
||||
|
||||
class GuidedFilter(nn.Module):
|
||||
def __init__(self, r, eps=1e-8):
|
||||
super(GuidedFilter, self).__init__()
|
||||
|
||||
self.r = r
|
||||
self.eps = eps
|
||||
self.boxfilter = BoxFilter(r)
|
||||
|
||||
def forward(self, x, y):
|
||||
n_x, c_x, h_x, w_x = x.size()
|
||||
n_y, c_y, h_y, w_y = y.size()
|
||||
|
||||
assert n_x == n_y
|
||||
assert c_x == 1 or c_x == c_y
|
||||
assert h_x == h_y and w_x == w_y
|
||||
assert h_x > 2 * self.r + 1 and w_x > 2 * self.r + 1
|
||||
|
||||
# N
|
||||
N = self.boxfilter(Variable(x.data.new().resize_((1, 1, h_x, w_x)).fill_(1.0)))
|
||||
|
||||
# mean_x
|
||||
mean_x = self.boxfilter(x) / N
|
||||
# mean_y
|
||||
mean_y = self.boxfilter(y) / N
|
||||
# cov_xy
|
||||
cov_xy = self.boxfilter(x * y) / N - mean_x * mean_y
|
||||
# var_x
|
||||
var_x = self.boxfilter(x * x) / N - mean_x * mean_x
|
||||
|
||||
# A
|
||||
A = cov_xy / (var_x + self.eps)
|
||||
# b
|
||||
b = mean_y - A * mean_x
|
||||
|
||||
# mean_A; mean_b
|
||||
mean_A = self.boxfilter(A) / N
|
||||
mean_b = self.boxfilter(b) / N
|
||||
|
||||
return mean_A * x + mean_b
|
||||
@@ -1,9 +1,6 @@
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
from torch import Tensor, nn
|
||||
from torch.autograd import Variable
|
||||
from torch import nn
|
||||
from torch.nn import Parameter
|
||||
from torch.optim.optimizer import Optimizer, required
|
||||
|
||||
|
||||
def l2normalize(v, eps=1e-12):
|
||||
@@ -29,7 +26,6 @@ class SpectralNorm(nn.Module):
|
||||
v.data = l2normalize(torch.mv(torch.t(w.view(height, -1).data), u.data))
|
||||
u.data = l2normalize(torch.mv(w.view(height, -1).data, v.data))
|
||||
|
||||
# sigma = torch.dot(u.data, torch.mv(w.view(height,-1).data, v.data))
|
||||
sigma = u.dot(w.view(height, -1).mv(v))
|
||||
setattr(self.module, self.name, w / sigma.expand_as(w))
|
||||
|
||||
|
||||
+2
-44
@@ -1,9 +1,7 @@
|
||||
from collections import OrderedDict, namedtuple
|
||||
from functools import reduce
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from torch.autograd import Variable
|
||||
|
||||
|
||||
class LambdaBase(nn.Sequential):
|
||||
@@ -15,6 +13,7 @@ class LambdaBase(nn.Sequential):
|
||||
output = []
|
||||
for module in self._modules.values():
|
||||
output.append(module(input))
|
||||
|
||||
return output if output else input
|
||||
|
||||
|
||||
@@ -126,13 +125,10 @@ model = nn.Sequential( # Sequential,
|
||||
)
|
||||
|
||||
|
||||
model.load_state_dict(torch.load("models/vgg19_gray.pth"))
|
||||
# print(model)
|
||||
model.load_state_dict(torch.load("data/vgg19_gray.pth"))
|
||||
vgg19_gray_net = torch.nn.Sequential()
|
||||
for (name, layer) in model._modules.items():
|
||||
vgg19_gray_net.add_module(layer_names[int(name)], model[int(name)])
|
||||
# print(vgg19_gray_net)
|
||||
|
||||
|
||||
for param in vgg19_gray_net.parameters():
|
||||
param.requires_grad = False
|
||||
@@ -163,8 +159,6 @@ class vgg19_gray(torch.nn.Module):
|
||||
h_relu4_1 = h
|
||||
h = self.slice3(h)
|
||||
h_relu5_1 = h
|
||||
# vgg_outputs = namedtuple("VggOutputs", ['h_relu3_1', 'h_relu4_1', 'h_relu5_1'])
|
||||
# out = vgg_outputs(h_relu3_1, h_relu4_1, h_relu5_1)
|
||||
return h_relu3_1, h_relu4_1, h_relu5_1
|
||||
|
||||
|
||||
@@ -197,40 +191,4 @@ class vgg19_gray_new(torch.nn.Module):
|
||||
h_relu4_1 = h
|
||||
h = self.slice3(h)
|
||||
h_relu5_1 = h
|
||||
# vgg_outputs = namedtuple("VggOutputs", ['h_relu3_1', 'h_relu4_1', 'h_relu5_1'])
|
||||
# out = vgg_outputs(h_relu3_1, h_relu4_1, h_relu5_1)
|
||||
return h_relu2_1, h_relu3_1, h_relu4_1, h_relu5_1
|
||||
|
||||
|
||||
# class vgg19_gray_conv(torch.nn.Module):
|
||||
# def __init__(self, requires_grad=False):
|
||||
# super(vgg19_gray_conv, self).__init__()
|
||||
# vgg_pretrained_features = vgg19_gray_net
|
||||
# self.slice0 = torch.nn.Sequential()
|
||||
# self.slice1 = torch.nn.Sequential()
|
||||
# self.slice2 = torch.nn.Sequential()
|
||||
# self.slice3 = torch.nn.Sequential()
|
||||
# for x in range(6):
|
||||
# self.slice0.add_module(layer_names[x], vgg_pretrained_features[x])
|
||||
# for x in range(6, 11):
|
||||
# self.slice1.add_module(layer_names[x], vgg_pretrained_features[x])
|
||||
# for x in range(11, 20):
|
||||
# self.slice2.add_module(layer_names[x], vgg_pretrained_features[x])
|
||||
# for x in range(20, 29):
|
||||
# self.slice3.add_module(layer_names[x], vgg_pretrained_features[x])
|
||||
# if not requires_grad:
|
||||
# for param in self.parameters():
|
||||
# param.requires_grad = False
|
||||
|
||||
# def forward(self, X):
|
||||
# h = self.slice0(X)
|
||||
# h_relu2_1 = h
|
||||
# h = self.slice1(h)
|
||||
# h_relu3_1 = h
|
||||
# h = self.slice2(h)
|
||||
# h_relu4_1 = h
|
||||
# h = self.slice3(h)
|
||||
# h_relu5_1 = h
|
||||
# # vgg_outputs = namedtuple("VggOutputs", ['h_relu3_1', 'h_relu4_1', 'h_relu5_1'])
|
||||
# # out = vgg_outputs(h_relu3_1, h_relu4_1, h_relu5_1)
|
||||
# return h_relu2_1, h_relu3_1, h_relu4_1, h_relu5_1
|
||||
|
||||
Reference in New Issue
Block a user