Почему и как сделать диапазон выходного изображения из нейронной сети [-1,1] в SRGAN?

Я работал над повторной реализацией фотореалистичного сверхвысокого разрешения одиночного изображения с использованием генеративно-состязательной сети (SRGAN), и теперь я застрял с данной информацией в разделе 3.2.введите здесь описание изображения Согласно статье, целевое значение HR должно быть в диапазоне [-1,1], входное значение LR должно быть в диапазоне [0,1], а потеря MSE была рассчитана для изображений в диапазоне [-1,1].

Последнее предложение подразумевает, что выход сети генератора должен быть в [-1,1]. Так что content_loss = MSELoss(генератор(выход), цель). Я правильно понимаю? Но когда я печатаю вывод из моей генераторной сети, последний из которых представляет собой просто conv2d, он дает мне изображения в ярости [0,1].

Я не получаю хорошего результата, запуская часть SRResNet-MSE, и я думаю, может быть, потому, что потеря MSE рассчитывается для разных диапазонов, а не только для одного [-1,1]?

Но как выход моего генератора может быть в диапазоне [-1,1], если я все еще хочу следовать архитектуре бумаги, в которой conv2d является последним слоем? введите здесь описание изображения

Я также включаю сюда свой генератор классов кода

class Generator(nn.Module):
    def __init__(self, scale_factor):
        upsample_block_num = int(math.log(scale_factor, 2))

        super(Generator, self).__init__()
        self.block1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=9, stride=1, padding=4, bias=False),
            nn.LeakyReLU(0.2, inplace=True)
        )
        self.block2 = self.make_layer(ResidualBlock, 16)
        self.block3 = nn.Sequential(
            nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1, bias=False),
            nn.InstanceNorm2d(64, affine=True)
        )
        block4 = [UpsampleBLock(64, 2) for _ in range(upsample_block_num)]
        block4.append(nn.Conv2d(64, 3, kernel_size=9, stride=1, padding=4, bias=False))
        self.block4 = nn.Sequential(*block4)

    def make_layer(self, block, num_of_layer):
        layers = []
        for _ in range(num_of_layer):
            layers.append(block(64))
        return nn.Sequential(*layers)

    def forward(self, x):
        block1 = self.block1(x)
        block2 = self.block2(block1)
        block3 = self.block3(block2)
        block4 = self.block4(block1 + block3)

        return block4

Большое спасибо за помощь!


person YIRAN JIA    schedule 23.07.2020    source источник


Ответы (1)


Учитывая, что вам нужен вывод в диапазоне [-1,1], и в настоящее время вы просто получаете вывод в [0,1].

output = (output*2)-1

должен сделать работу.

person Mohit Lamba    schedule 23.07.2020
comment
Более того, существует так много проверенных кодов популярного SRGAN (например, github.com/leftthomas/SRGAN ). Почему бы не построить над ними. - person Mohit Lamba; 23.07.2020
comment
Спасибо за предложение. В итоге я использовал функцию tanh, чтобы сделать вывод генератора равным [-1,1], как написано в руководстве Pytorch DCGAN. - person YIRAN JIA; 27.07.2020
comment
Просто хотел довести до вашего беспокойства следующее. Tanh может сжать в него любой диапазон данных за пределами [-1,1], но оставит [0,1] в диапазоне [0,1]. Таким образом, если выход вашей сети до того, как нелинейность tanh находится в основном в [0,1], tanh не является хорошим решением для доведения его до [-1,1]. - person Mohit Lamba; 27.07.2020
comment
Я понимаю. Спасибо! Я проверил, что большая часть выходных данных нашей модели действительно находится в диапазоне [0,1]. Попробую разрезать их строго по [0, 1], а потом применю предоставленный вами сдвиг и посмотрю, что получится. Спасибо еще раз. - person YIRAN JIA; 14.08.2020