You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.9 KiB
89 lines
2.9 KiB
import paddle |
|
import paddle.nn as nn |
|
import numpy as np |
|
from ppgan.utils.download import get_path_from_url |
|
|
|
model_urls = { |
|
'caffevgg19': ('https://paddlegan.bj.bcebos.com/models/vgg19_no_fc.npy', |
|
'8ea1ef2374f8684b6cea9f300849be81') |
|
} |
|
|
|
|
|
class CaffeVGG19(nn.Layer): |
|
cfg = [ |
|
64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, |
|
'M', 512, 512, 512, 512, 'M' |
|
] |
|
|
|
def __init__(self, output_index: int = 26) -> None: |
|
super().__init__() |
|
arch = 'caffevgg19' |
|
weights_path = get_path_from_url(model_urls[arch][0], |
|
model_urls[arch][1]) |
|
data_dict: dict = np.load(weights_path, |
|
encoding='latin1', |
|
allow_pickle=True).item() |
|
self.features = self.make_layers(self.cfg, data_dict) |
|
del data_dict |
|
self.features = nn.Sequential(*self.features.sublayers()[:output_index]) |
|
mean = paddle.to_tensor([103.939, 116.779, 123.68]) |
|
self.mean = mean.unsqueeze(0).unsqueeze(-1).unsqueeze(-1) |
|
|
|
def _process(self, x): |
|
# value to 255 |
|
rgb = (x * 0.5 + 0.5) * 255 |
|
# rgb to bgr |
|
bgr = paddle.stack((rgb[:, 2, :, :], rgb[:, 1, :, :], rgb[:, 0, :, :]), |
|
1) |
|
# vgg norm |
|
return bgr - self.mean |
|
|
|
def _forward_impl(self, x): |
|
x = self._process(x) |
|
# NOTE get output with out relu activation |
|
x = self.features(x) |
|
return x |
|
|
|
def forward(self, x): |
|
return self._forward_impl(x) |
|
|
|
@staticmethod |
|
def get_conv_filter(data_dict, name): |
|
return data_dict[name][0] |
|
|
|
@staticmethod |
|
def get_bias(data_dict, name): |
|
return data_dict[name][1] |
|
|
|
@staticmethod |
|
def get_fc_weight(data_dict, name): |
|
return data_dict[name][0] |
|
|
|
def make_layers(self, cfg, data_dict, batch_norm=False) -> nn.Sequential: |
|
layers = [] |
|
in_channels = 3 |
|
block = 1 |
|
number = 1 |
|
for v in cfg: |
|
if v == 'M': |
|
layers += [nn.MaxPool2D(kernel_size=2, stride=2)] |
|
block += 1 |
|
number = 1 |
|
else: |
|
conv2d = nn.Conv2D(in_channels, v, kernel_size=3, padding=1) |
|
""" set value """ |
|
weight = paddle.to_tensor( |
|
self.get_conv_filter(data_dict, f'conv{block}_{number}')) |
|
weight = weight.transpose((3, 2, 0, 1)) |
|
bias = paddle.to_tensor( |
|
self.get_bias(data_dict, f'conv{block}_{number}')) |
|
conv2d.weight.set_value(weight) |
|
conv2d.bias.set_value(bias) |
|
number += 1 |
|
if batch_norm: |
|
layers += [conv2d, nn.BatchNorm2D(v), nn.ReLU()] |
|
else: |
|
layers += [conv2d, nn.ReLU()] |
|
in_channels = v |
|
|
|
return nn.Sequential(*layers)
|
|
|