Capricorn / Baselines /Models /HiCNN.py
chnftq's picture
Upload folder using huggingface_hub
e3814d7 verified
Raw
History Blame Contribute Delete
3.74 kB
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
# --------------------------------------------------------
# References:
# HiCNN: http://dna.cs.miami.edu/HiCNN2/ (in paper: https://www.mdpi.com/2073-4425/10/11/862)
# --------------------------------------------------------
import torch
import torch.nn as nn
import torch.nn.functional as F
class Conv_ReLU_Block(nn.Module):
def __init__(self):
super(Conv_ReLU_Block, self).__init__()
self.conv = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=1, padding=1, bias=False)
self.relu = nn.ReLU(inplace=True)
def forward(self, x):
return self.relu(self.conv(x))
class Generator(nn.Module):
def __init__(self, input_channels=1, out_channels=None):
super(Generator, self).__init__()
if not out_channels:
out_channels = input_channels
self.net1_conv1 = nn.Conv2d(input_channels, 64, 13)
self.net1_conv2 = nn.Conv2d(64, 64, 1)
self.net1_conv3 = nn.Conv2d(64, 128, 3, padding=1, bias=False)
self.net1_conv4R = nn.Conv2d(128, 128, 3, padding=1, bias=False)
self.net1_conv5 = nn.Conv2d(128 * 25, 1000, 1, padding=0, bias=True)
self.net1_conv6 = nn.Conv2d(1000, 64, 1, padding=0, bias=True)
self.net1_conv7 = nn.Conv2d(64, out_channels, 3, padding=1, bias=False)
self.net2_conv1 = nn.Conv2d(input_channels, 8, 13)
self.net2_conv2 = nn.Conv2d(8, out_channels, 1)
self.residual_layer_vdsr = self.make_layer(Conv_ReLU_Block, 18)
self.input_vdsr = nn.Conv2d(in_channels=out_channels, out_channels=64, kernel_size=3, stride=1, padding=1, bias=False)
self.output_vdsr = nn.Conv2d(in_channels=64, out_channels=out_channels, kernel_size=3, stride=1, padding=1, bias=False)
self.net3_conv1 = nn.Conv2d(input_channels, 8, 9)
self.net3_conv2 = nn.Conv2d(8, 8, 1)
self.net3_conv3 = nn.Conv2d(8, out_channels, 5)
self.relu = nn.ReLU(inplace=True)
self.weights = nn.Parameter((torch.ones(1, 3) / 3), requires_grad=True)
# He initialization
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
def make_layer(self, block, num_of_layer):
layers = []
for _ in range(num_of_layer):
layers.append(block())
return nn.Sequential(*layers)
def forward(self, input):
# ConvNet1
x = self.relu(self.net1_conv1(input))
x = self.relu(self.net1_conv2(x))
residual = x
x2 = self.net1_conv3(x)
output1 = x2
outtmp = []
for i in range(25):
output1 = self.net1_conv4R(self.relu(self.net1_conv4R(self.relu(output1))))
output1 = torch.add(output1, x2)
outtmp.append(output1)
output1 = torch.cat(outtmp, 1)
output1 = self.net1_conv5(output1)
output1 = self.net1_conv6(output1)
output1 = torch.add(output1, residual)
output1 = self.net1_conv7(output1)
# ConvNet2
x_vdsr = self.relu(self.net2_conv1(input))
x_vdsr = self.relu(self.net2_conv2(x_vdsr))
residual2 = x_vdsr
output2 = self.relu(self.input_vdsr(x_vdsr))
output2 = self.residual_layer_vdsr(output2)
output2 = self.output_vdsr(output2)
output2 = torch.add(output2, residual2)
# ConvNet3
output3 = self.net3_conv1(input)
output3 = F.relu(output3)
output3 = self.net3_conv2(output3)
output3 = F.relu(output3)
output3 = self.net3_conv3(output3)
output3 = F.relu(output3)
# w1*output1 + w2*output2 + w3*output3
w_sum = self.weights.sum(1)
output = (output1 * self.weights.data[0][0] / w_sum) + (output2 * self.weights.data[0][1] / w_sum) + (
output3 * self.weights.data[0][2] / w_sum)
return output