|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- #! /usr/bin/python
- # -*- coding: utf-8 -*-
-
- import numpy as np
- import tensorlayer as tl
- from mindspore import Tensor
- from mindspore.common import initializer
-
- __all__ = [
- 'Initializer', 'Zeros', 'Ones', 'Constant', 'RandomUniform', 'RandomNormal', 'TruncatedNormal',
- 'deconv2d_bilinear_upsampling_initializer', 'HeNormal'
- ]
-
-
- class Initializer(object):
- """Initializer base class: all initializers inherit from this class.
- """
-
- def __call__(self, shape, dtype=None):
- """Returns a tensor object initialized as specified by the initializer.
-
- Parameters
- ----------
- shape : tuple of int.
- The shape of the tensor.
- dtype : Optional dtype of the tensor.
- If not provided will return tensor of `tl.float32`.
-
- Returns
- -------
-
- """
- raise NotImplementedError
-
- def get_config(self):
- """Returns the configuration of the initializer as a JSON-serializable dict.
-
- Returns
- -------
- A JSON-serializable Python dict.
- """
- return {}
-
- @classmethod
- def from_config(cls, config):
- """Instantiates an initializer from a configuration dictionary.
-
- Parameters
- ----------
- config : A python dictionary.
- It will typically be the output of `get_config`.
-
- Returns
- -------
- An Initializer instance.
- """
- if 'dtype' in config:
- config.pop('dtype')
- return cls(**config)
-
-
- class Zeros(Initializer):
- """Initializer that generates tensors initialized to 0.
- """
-
- def __init__(self):
- self.zero = initializer.Zero()
-
- def __call__(self, shape, dtype=tl.float32):
- arr = np.ndarray(shape)
- self.zero(arr)
- return Tensor(arr, dtype=dtype)
-
-
- class Ones(Initializer):
- """Initializer that generates tensors initialized to 1.
- """
-
- def __init__(self):
- self.one = initializer.One()
-
- def __call__(self, shape, dtype=tl.float32):
- arr = np.ndarray(shape)
- self.one(arr)
- return Tensor(arr, dtype=dtype)
-
-
- class Constant(Initializer):
- """Initializer that generates tensors initialized to a constant value.
-
- Parameters
- ----------
- value : A python scalar or a numpy array.
- The assigned value.
-
- """
-
- def __init__(self, value=0):
- self.value = value
- self.constant = initializer.Constant(value=value)
-
- def __call__(self, shape, dtype=tl.float32):
- arr = np.ndarray(shape)
- self.constant(arr)
- return Tensor(arr, dtype=dtype)
-
- def get_config(self):
- return {"value": self.value}
-
-
- class RandomUniform(Initializer):
- """Initializer that generates tensors with a uniform distribution.
-
- Parameters
- ----------
- minval : A python scalar or a scalar tensor.
- Lower bound of the range of random values to generate.
- maxval : A python scalar or a scalar tensor.
- Upper bound of the range of random values to generate.
- seed : A Python integer.
- Used to seed the random generator.
-
- """
-
- def __init__(self, minval=-0.05, maxval=0.05, seed=None):
- self.minval = minval
- self.maxval = maxval
- self.seed = seed
-
- def __call__(self, shape, dtype=tl.float32):
- return tl.random_uniform(shape, self.minval, self.maxval, dtype=dtype, seed=self.seed)
-
- def get_config(self):
- return {"minval": self.minval, "maxval": self.maxval, "seed": self.seed}
-
-
- class RandomNormal(Initializer):
- """Initializer that generates tensors with a normal distribution.
-
- Parameters
- ----------
- mean : A python scalar or a scalar tensor.
- Mean of the random values to generate.
- stddev : A python scalar or a scalar tensor.
- Standard deviation of the random values to generate.
- seed : A Python integer.
- Used to seed the random generator.
- """
-
- def __init__(self, mean=0.0, stddev=0.05, seed=None):
- self.mean = mean
- self.stddev = stddev
- self.seed = seed
-
- def __call__(self, shape, dtype=tl.float32):
- return tl.random_normal(shape, self.mean, self.stddev, dtype=dtype, seed=self.seed)
-
- def get_config(self):
- return {"mean": self.mean, "stddev": self.stddev, "seed": self.seed}
-
-
- class TruncatedNormal(Initializer):
- """Initializer that generates a truncated normal distribution.
-
- These values are similar to values from a `RandomNormal`
- except that values more than two standard deviations from the mean
- are discarded and re-drawn. This is the recommended initializer for
- neural network weights and filters.
-
-
- Parameters
- ----------
- mean : A python scalar or a scalar tensor.
- Mean of the random values to generate.
- stddev : A python scalar or a scalar tensor.
- Standard deviation of the andom values to generate.
- seed : A Python integer.
- Used to seed the random generator.
- """
-
- def __init__(self, mean=0.0, stddev=0.05, seed=None):
- self.mean = mean
- self.stddev = stddev
- self.seed = seed
-
- def __call__(self, shape, dtype=tl.float32):
- return tl.truncated_normal(shape, self.mean, self.stddev, dtype=dtype, seed=self.seed)
-
- def get_config(self):
- return {"mean": self.mean, "stddev": self.stddev, "seed": self.seed}
-
-
- class HeNormal(Initializer):
- """He normal initializer.
-
- Parameters
- ----------
- seed : A Python integer.
- Used to seed the random generator.
-
- """
-
- def __init__(self, seed=None):
- self.seed = seed
-
- def __call__(self, shape, dtype=tl.float32):
- return tl.he_normal(seed=self.seed, shape=shape, dtype=dtype)
-
- def get_config(self):
- return {"seed", self.seed}
-
-
- def deconv2d_bilinear_upsampling_initializer(shape):
- """Returns the initializer that can be passed to DeConv2dLayer for initializing the
- weights in correspondence to channel-wise bilinear up-sampling.
- Used in segmentation approaches such as [FCN](https://arxiv.org/abs/1605.06211)
-
- Parameters
- ----------
- shape : tuple of int
- The shape of the filters, [height, width, output_channels, in_channels].
- It must match the shape passed to DeConv2dLayer.
-
- Returns
- -------
- ``tf.constant_initializer``
- A constant initializer with weights set to correspond to per channel bilinear upsampling
- when passed as W_int in DeConv2dLayer
-
- """
- if shape[0] != shape[1]:
- raise Exception('deconv2d_bilinear_upsampling_initializer only supports symmetrical filter sizes')
-
- if shape[3] < shape[2]:
- raise Exception(
- 'deconv2d_bilinear_upsampling_initializer behaviour is not defined for num_in_channels < num_out_channels '
- )
-
- filter_size = shape[0]
- num_out_channels = shape[2]
- num_in_channels = shape[3]
-
- # Create bilinear filter kernel as numpy array
- bilinear_kernel = np.zeros([filter_size, filter_size], dtype=np.float32)
- scale_factor = (filter_size + 1) // 2
- if filter_size % 2 == 1:
- center = scale_factor - 1
- else:
- center = scale_factor - 0.5
- for x in range(filter_size):
- for y in range(filter_size):
- bilinear_kernel[x, y] = (1 - abs(x - center) / scale_factor) * (1 - abs(y - center) / scale_factor)
- weights = np.zeros((filter_size, filter_size, num_out_channels, num_in_channels), dtype=np.float32)
- for i in range(num_out_channels):
- weights[:, :, i, i] = bilinear_kernel
-
- # assign numpy array to constant_initalizer and pass to get_variable
- return Constant(value=weights)
|