# copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import paddle import paddle.nn as nn import math class _SpectralNorm(nn.SpectralNorm): def __init__(self, weight_shape, dim=0, power_iters=1, eps=1e-12, dtype='float32'): super(_SpectralNorm, self).__init__(weight_shape, dim, power_iters, eps, dtype) def forward(self, weight): inputs = {'Weight': weight, 'U': self.weight_u, 'V': self.weight_v} out = self._helper.create_variable_for_type_inference(self._dtype) _power_iters = self._power_iters if self.training else 0 self._helper.append_op(type="spectral_norm", inputs=inputs, outputs={ "Out": out, }, attrs={ "dim": self._dim, "power_iters": _power_iters, "eps": self._eps, }) return out class Spectralnorm(paddle.nn.Layer): def __init__(self, layer, dim=0, power_iters=1, eps=1e-12, dtype='float32'): super(Spectralnorm, self).__init__() self.spectral_norm = _SpectralNorm(layer.weight.shape, dim, power_iters, eps, dtype) self.dim = dim self.power_iters = power_iters self.eps = eps self.layer = layer weight = layer._parameters['weight'] del layer._parameters['weight'] self.weight_orig = self.create_parameter(weight.shape, dtype=weight.dtype) self.weight_orig.set_value(weight) def forward(self, x): weight = self.spectral_norm(self.weight_orig) self.layer.weight = weight out = self.layer(x) return out