@ -8,23 +8,24 @@ from pathlib import Path
from . import hdblut
from common import layers
from itertools import cycle
from models . base import SRNetBase
class HDBNet ( nn. Modul e) :
class HDBNet ( SRNetBas e) :
def __init__ ( self , hidden_dim = 64 , layers_count = 4 , scale = 4 ) :
super ( HDBNet , self ) . __init__ ( )
assert scale == 4
self . scale = scale
self . stage1_3H = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 * 2 )
self . stage1_3D = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 * 2 )
self . stage1_3B = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 * 2 )
self . stage1_2H = layers . UpscaleBlock ( in_features = 2 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 * 2 )
self . stage1_2D = layers . UpscaleBlock ( in_features = 2 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 * 2 )
# self.stage2_3H = layers.UpscaleBlock(in_features=3, hidden_dim=hidden_dim, layers_count=layers_count, upscale_factor=2 )
# self.stage2_3D = layers.UpscaleBlock(in_features=3, hidden_dim=hidden_dim, layers_count=layers_count, upscale_factor=2 )
# self.stage2_3B = layers.UpscaleBlock(in_features=3, hidden_dim=hidden_dim, layers_count=layers_count, upscale_factor=2 )
# self.stage2_2H = layers.UpscaleBlock(in_features=2, hidden_dim=hidden_dim, layers_count=layers_count, upscale_factor=2 )
# self.stage2_2D = layers.UpscaleBlock(in_features=2, hidden_dim=hidden_dim, layers_count=layers_count, upscale_factor=2 )
self . stage1_3H = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 255 , output_max_value = 255 )
self . stage1_3D = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 255 , output_max_value = 255 )
self . stage1_3B = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 255 , output_max_value = 255 )
self . stage1_2H = layers . UpscaleBlock ( in_features = 2 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 15 , output_max_value = 255 )
self . stage1_2D = layers . UpscaleBlock ( in_features = 2 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 15 , output_max_value = 255 )
self . stage2_3H = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 255 , output_max_value = 255 )
self . stage2_3D = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 255 , output_max_value = 255 )
self . stage2_3B = layers . UpscaleBlock ( in_features = 3 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 255 , output_max_value = 255 )
self . stage2_2H = layers . UpscaleBlock ( in_features = 2 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 15 , output_max_value = 255 )
self . stage2_2D = layers . UpscaleBlock ( in_features = 2 , hidden_dim = hidden_dim , layers_count = layers_count , upscale_factor = 2 , input_max_value = 15 , output_max_value = 255 )
self . _extract_pattern_3H = layers . PercievePattern ( receptive_field_idxes = [ [ 0 , 0 ] , [ 0 , 1 ] , [ 0 , 2 ] ] , center = [ 0 , 0 ] , window_size = 3 )
self . _extract_pattern_3D = layers . PercievePattern ( receptive_field_idxes = [ [ 0 , 0 ] , [ 1 , 1 ] , [ 2 , 2 ] ] , center = [ 0 , 0 ] , window_size = 3 )
@ -32,6 +33,8 @@ class HDBNet(nn.Module):
self . _extract_pattern_2H = layers . PercievePattern ( receptive_field_idxes = [ [ 0 , 0 ] , [ 0 , 1 ] ] , center = [ 0 , 0 ] , window_size = 2 )
self . _extract_pattern_2D = layers . PercievePattern ( receptive_field_idxes = [ [ 0 , 0 ] , [ 1 , 1 ] ] , center = [ 0 , 0 ] , window_size = 2 )
self . rotations = 4
def forward_stage ( self , x , scale , percieve_pattern , stage ) :
b , c , h , w = x . shape
x = percieve_pattern ( x )
@ -47,41 +50,42 @@ class HDBNet(nn.Module):
x = x . reshape ( b * c , 1 , h , w )
lsb = x % 16
msb = x - lsb
output_msb = torch . zeros ( [ b * c , 1 , h * 2 * 2 , w * 2 * 2 ] , dtype = x . dtype , device = x . device )
output_lsb = torch . zeros ( [ b * c , 1 , h * 2 * 2 , w * 2 * 2 ] , dtype = x . dtype , device = x . device )
for rotations_count in range ( 4 ) :
output = torch . zeros ( [ b * c , 1 , h * 2 , w * 2 ] , dtype = x . dtype , device = x . device )
for rotations_count in range ( self . rotations ) :
rotated_msb = torch . rot90 ( msb , k = rotations_count , dims = [ 2 , 3 ] )
rotated_lsb = torch . rot90 ( lsb , k = rotations_count , dims = [ 2 , 3 ] )
output_msb + = torch . rot90 ( self . forward_stage ( rotated_msb , 2 * 2 , self . _extract_pattern_3H , self . stage1_3H ) , k = - rotations_count , dims = [ 2 , 3 ] )
output_msb + = torch . rot90 ( self . forward_stage ( rotated_msb , 2 * 2 , self . _extract_pattern_3D , self . stage1_3D ) , k = - rotations_count , dims = [ 2 , 3 ] )
output_msb + = torch . rot90 ( self . forward_stage ( rotated_msb , 2 * 2 , self . _extract_pattern_3B , self . stage1_3B ) , k = - rotations_count , dims = [ 2 , 3 ] )
output_lsb + = torch . rot90 ( self . forward_stage ( rotated_lsb , 2 * 2 , self . _extract_pattern_2H , self . stage1_2H ) , k = - rotations_count , dims = [ 2 , 3 ] )
output_lsb + = torch . rot90 ( self . forward_stage ( rotated_lsb , 2 * 2 , self . _extract_pattern_2D , self . stage1_2D ) , k = - rotations_count , dims = [ 2 , 3 ] )
output_msb / = 4 * 3
output_lsb / = 4 * 2
output_msb = round_func ( ( output_msb / 255 ) * 16 ) * 15
output_lsb = ( output_lsb / 255 ) * 15
# print(output_msb.min(), output_msb.max(), output_lsb.min(), output_lsb.max())
x = output_msb + output_lsb
# lsb = x % 16
# msb = x - lsb
# output_msb = torch.zeros([b*c, 1, h*4, w*4], dtype=x.dtype, device=x.device)
# output_lsb = torch.zeros([b*c, 1, h*4, w*4], dtype=x.dtype, device=x.device)
# for rotations_count in range(4):
# rotated_msb = torch.rot90(msb, k=rotations_count, dims=[2, 3])
# rotated_lsb = torch.rot90(lsb, k=rotations_count, dims=[2, 3])
# output_msb += torch.rot90(self.forward_stage(rotated_msb, 2, self._extract_pattern_3H, self.stage2_3H), k=-rotations_count, dims=[2, 3])
# output_msb += torch.rot90(self.forward_stage(rotated_msb, 2, self._extract_pattern_3D, self.stage2_3D), k=-rotations_count, dims=[2, 3])
# output_msb += torch.rot90(self.forward_stage(rotated_msb, 2, self._extract_pattern_3B, self.stage2_3B), k=-rotations_count, dims=[2, 3])
# output_lsb += torch.rot90(self.forward_stage(rotated_lsb, 2, self._extract_pattern_2H, self.stage2_2H), k=-rotations_count, dims=[2, 3])
# output_lsb += torch.rot90(self.forward_stage(rotated_lsb, 2, self._extract_pattern_2D, self.stage2_2D), k=-rotations_count, dims=[2, 3])
# output_msb /= 4*3
# output_lsb /= 4*2
# output_msb = round_func((output_msb / 255) * 16) * 15
# output_lsb = (output_lsb / 255) * 15
# # print(output_msb.min(), output_msb.max(), output_lsb.min(), output_lsb.max())
# x = output_msb + output_lsb
output_msb = self . forward_stage ( rotated_msb , 2 , self . _extract_pattern_3H , self . stage1_3H ) + \
self . forward_stage ( rotated_msb , 2 , self . _extract_pattern_3D , self . stage1_3D ) + \
self . forward_stage ( rotated_msb , 2 , self . _extract_pattern_3B , self . stage1_3B )
output_msb / = 3
output_lsb = self . forward_stage ( rotated_lsb , 2 , self . _extract_pattern_2H , self . stage1_2H ) + \
self . forward_stage ( rotated_lsb , 2 , self . _extract_pattern_2D , self . stage1_2D )
output_lsb / = 2
if not config is None and config . current_iter % config . display_step == 0 :
config . writer . add_histogram ( ' s1_output_lsb ' , output_lsb . detach ( ) . cpu ( ) . numpy ( ) , config . current_iter )
config . writer . add_histogram ( ' s1_output_msb ' , output_msb . detach ( ) . cpu ( ) . numpy ( ) , config . current_iter )
output + = torch . rot90 ( output_msb + output_lsb , k = - rotations_count , dims = [ 2 , 3 ] ) . clamp ( 0 , 255 )
output / = self . rotations
x = output
lsb = x % 16
msb = x - lsb
output = torch . zeros ( [ b * c , 1 , h * 4 , w * 4 ] , dtype = x . dtype , device = x . device )
for rotations_count in range ( self . rotations ) :
rotated_msb = torch . rot90 ( msb , k = rotations_count , dims = [ 2 , 3 ] )
rotated_lsb = torch . rot90 ( lsb , k = rotations_count , dims = [ 2 , 3 ] )
output_msb = self . forward_stage ( rotated_msb , 2 , self . _extract_pattern_3H , self . stage2_3H ) + \
self . forward_stage ( rotated_msb , 2 , self . _extract_pattern_3D , self . stage2_3D ) + \
self . forward_stage ( rotated_msb , 2 , self . _extract_pattern_3B , self . stage2_3B )
output_msb / = 3
output_lsb = self . forward_stage ( rotated_lsb , 2 , self . _extract_pattern_2H , self . stage2_2H ) + \
self . forward_stage ( rotated_lsb , 2 , self . _extract_pattern_2D , self . stage2_2D )
output_lsb / = 2
if not config is None and config . current_iter % config . display_step == 0 :
config . writer . add_histogram ( ' s2_output_lsb ' , output_lsb . detach ( ) . cpu ( ) . numpy ( ) , config . current_iter )
config . writer . add_histogram ( ' s2_output_msb ' , output_msb . detach ( ) . cpu ( ) . numpy ( ) , config . current_iter )
output + = torch . rot90 ( output_msb + output_lsb , k = - rotations_count , dims = [ 2 , 3 ] ) . clamp ( 0 , 255 )
output / = self . rotations
x = output
x = x . reshape ( b , c , h * self . scale , w * self . scale )
return x