Пример #1
0
    def svd_affine(x, n_outputs, cr):
        W = get_parameter('affine/W')

        if W is None:
            UV = None
        else:
            UV = W.d
        b = get_parameter('affine/b')
        # compute rank (size of intermediate activations)
        # to obtained desired reduction
        inshape = np.prod(x.shape[1:])
        outshape = np.prod(n_outputs)
        rank = int(
            np.floor((1 - cr) * inshape * outshape / (inshape + outshape)))

        # Initialize bias to existing b in affine if exists
        if b is not None:
            b_new = get_parameter_or_create('svd_affine/b',
                                            b.d.shape,
                                            need_grad=b.need_grad)
            b_new.d = b.d.copy()
        logger.info(
            "SVD affine created: input_shape = {}; output_shape = {}; compression = {}; rank = {};"
            .format(inshape, outshape, cr, rank))

        # create svd_affine initialized from W in current context if it exists
        return PF.svd_affine(x, n_outputs, rank, uv_init=UV)
Пример #2
0
    def svd_convolution(x, n_outputs, kernel, pad, with_bias, cr):
        W = get_parameter('conv/W')

        if W is None:
            UV = None
        else:
            UV = W.d
        b = get_parameter('conv/b')
        # compute rank (size of intermediate activations)
        # to obtained desired reduction
        inmaps = x.shape[1]
        outmaps = n_outputs
        Ksize = np.prod(kernel)
        rank = int(
            np.floor((1 - cr) * inmaps * outmaps * Ksize /
                     (inmaps * Ksize + inmaps * outmaps)))

        # Initialize bias to existing b in affine if exists
        if b is not None:
            b_new = get_parameter_or_create('svd_conv/b',
                                            b.d.shape,
                                            need_grad=b.need_grad)
            b_new.d = b.d.copy()
        logger.info(
            "SVD convolution created: inmaps = {}; outmaps = {}; compression = {}; rank = {};"
            .format(inmaps, outmaps, cr, rank))

        # create svd_convolution initialized from W in current context if it exists
        return PF.svd_convolution(x,
                                  n_outputs,
                                  kernel=kernel,
                                  r=rank,
                                  pad=pad,
                                  with_bias=with_bias,
                                  uv_init=UV)
Пример #3
0
def test_get_set_pop_parameter():
    import nnabla as nn
    from nnabla.parameter import set_parameter, pop_parameter, get_parameter
    nn.clear_parameters()
    x = nn.Variable((2, 3, 4, 5))
    key = 'a/b/c'
    set_parameter(key, x)
    x2 = get_parameter(key)
    assert x is x2
    x3 = pop_parameter(key)
    assert x is x3
    x4 = get_parameter(key)
    assert x4 is None
Пример #4
0
    def _get_variable_or_create(self, name, shape, var_type):

        # The variable is a parameter, then get from parameter registry.
        if var_type == 'Parameter':
            try:
                param = get_parameter(name)
                assert param is not None, \
                    "A parameter `{}` is not found.".format(name)
            except:
                import sys
                import traceback
                raise ValueError(
                    'An error occurs during creation of a variable `{}` as a'
                    ' parameter variable. The error was:\n----\n{}\n----\n'
                    'The parameters registered was {}'.format(
                        name, traceback.format_exc(),
                        '\n'.join(
                            list(nn.get_parameters(grad_only=False).keys()))))
            assert shape == param.shape
            return param

        # Returns if variable is already created.
        try:
            var, count = self.vseen[name]
            count[0] += 1
        except:
            # Create a new one and returns.
            var = nn.Variable(shape)
            self.vseen[name] = (var, [1])
            return var

        # Found already created variable.
        assert var.shape == shape
        return var
Пример #5
0
    def _get_variable_or_create(self, v, callback, current_scope):

        if v.variable is not None:
            return v.variable

        v = callback._apply_generate_variable(v)

        if v.variable is not None:
            return v.variable

        pvar = v.proto
        name = pvar.name
        shape = list(pvar.shape.dim)
        if shape[0] < 0:
            shape[0] = self.batch_size
        shape = tuple(shape)
        assert np.all(np.array(shape) > 0
                      ), "Shape must be positive. Given {}.".format(shape)

        if pvar.type != 'Parameter':
            # Create a new variable and returns.
            var = nn.Variable(shape)
            v.variable = var
            var.name = name
            return var

        # Trying to load the parameter from .nnp file.
        callback.verbose('Loading parameter `{}` from .nnp.'.format(name))
        try:
            param = get_parameter(name)
            if param is None:
                logger.info(
                    'Parameter `{}` is not found. Initializing.'.format(name))
                tmp = _create_variable(pvar, name, shape, self.rng)
                param = tmp.variable_instance
                set_parameter(name, param)
            # Always copy param to current scope even if it already exists.
            with nn.parameter_scope('', current_scope):
                set_parameter(name, param)
        except:
            import sys
            import traceback
            raise ValueError(
                'An error occurs during creation of a variable `{}` as a'
                ' parameter variable. The error was:\n----\n{}\n----\n'
                'The parameters registered was {}'.format(
                    name, traceback.format_exc(), '\n'.join(
                        list(nn.get_parameters(grad_only=False).keys()))))
        assert shape == param.shape
        param = param.get_unlinked_variable(need_grad=v.need_grad)
        v.variable = param
        param.name = name
        return param
Пример #6
0
    def _get_variable_or_create(self, name, shape):
        # Returns if name found in parameter.
        param = get_parameter(name)
        if param is not None:
            assert shape == param.shape
            return param

        # Returns if variable is already created.
        try:
            var, count = self.vseen[name]
            count[0] += 1
        except:
            # Create a new one and returns.
            var = nn.Variable(shape)
            self.vseen[name] = (var, [1])
            return var

        # Found already created variable.
        assert var.shape == shape
        return var
Пример #7
0
def istft(y_r,
          y_i,
          window_size,
          stride,
          fft_size,
          window_type='hanning',
          center=True):
    '''Workaround wrapper of ISTFT for fixing a bug in nnabla<=1.15.0
    '''
    from utils import get_nnabla_version_integer
    if get_nnabla_version_integer() > 11500:
        return F.istft(**locals())
    import numpy as np
    from nnabla.parameter import get_parameter, get_parameter_or_create
    conv_cos = get_parameter('conv_cos')
    conv_sin = get_parameter('conv_sin')

    if conv_cos is None or conv_sin is None:
        if window_type == 'hanning':
            window_func = np.hanning(window_size + 1)[:-1]
        elif window_type == 'hamming':
            window_func = np.hamming(window_size + 1)[:-1]
        elif window_type == 'rectangular' or window_type is None:
            window_func = np.ones(window_size)
        else:
            raise ValueError("Unknown window type {}.".format(window_type))

        # pad window if `fft_size > window_size`
        if fft_size > window_size:
            diff = fft_size - window_size
            window_func = np.pad(window_func, (diff // 2, diff - diff // 2),
                                 mode='constant')
        elif fft_size < window_size:
            raise ValueError(
                "FFT size has to be as least as large as window size.")

        # compute inverse STFT filter coefficients
        if fft_size % stride != 0:
            raise ValueError("FFT size needs to be a multiple of stride.")

        inv_window_func = np.zeros_like(window_func)
        for s in range(0, fft_size, stride):
            inv_window_func += np.roll(np.square(window_func), s)

        mat_cos = np.zeros((fft_size // 2 + 1, 1, fft_size))
        mat_sin = np.zeros((fft_size // 2 + 1, 1, fft_size))

        for w in range(fft_size // 2 + 1):
            alpha = 1.0 if w == 0 or w == fft_size // 2 else 2.0
            alpha /= fft_size
            for t in range(fft_size):
                mat_cos[w, 0, t] = alpha * \
                    np.cos(2. * np.pi * w * t / fft_size)
                mat_sin[w, 0, t] = alpha * \
                    np.sin(2. * np.pi * w * t / fft_size)
        mat_cos = mat_cos * window_func / inv_window_func
        mat_sin = mat_sin * window_func / inv_window_func

        conv_cos = get_parameter_or_create('conv_cos',
                                           initializer=mat_cos,
                                           need_grad=False)
        conv_sin = get_parameter_or_create('conv_sin',
                                           initializer=mat_sin,
                                           need_grad=False)

    # compute inverse STFT
    x_cos = F.deconvolution(y_r, conv_cos, stride=(stride, ))
    x_sin = F.deconvolution(y_i, conv_sin, stride=(stride, ))

    x = F.reshape(x_cos - x_sin, (x_cos.shape[0], x_cos.shape[2]))

    if center:
        x = x[:, fft_size // 2:-fft_size // 2]

    return x
Пример #8
0
def istft(y_r,
          y_i,
          window_size,
          stride,
          fft_size,
          window_type='hanning',
          center=True):
    """Computes the inverse shoft-time Fourier transform

    Note: We use a constant square inverse window for the reconstruction
    of the time-domain signal, therefore, the first and last
    `window_size - stride` are not perfectly reconstructed.

    Args:
        y_r (~nnabla.Variable): Real part of STFT of size `batch_size x fft_size//2 + 1 x frame_size`.
        y_i (~nnabla.Variable): Imaginary part of STFT of size `batch_size x fft_size//2 + 1 x frame_size`.
        window_size (int): Size of STFT analysis window.
        stride (int): Number of samples that we shift the window, also called `hop size`.
        fft_size (int): Size of the FFT, (STFT has `fft_size // 2 + 1` frequency bins).
        window_type (str): Analysis window, can be either `hanning`, `hamming` or `rectangular`.
            For convenience, also `window_type=None` is supported which is equivalent to `window_type='rectangular'`.
        center (bool): If `True`, then it is assumed that the time-domain signal has centered frames.

    Returns:
        ~nnabla.Variable: Time domain sequence of size `batch_size x sample_size`.
    """
    from nnabla.parameter import get_parameter, get_parameter_or_create
    conv_cos = get_parameter('conv_cos')
    conv_sin = get_parameter('conv_sin')

    if conv_cos is None or conv_sin is None:
        if window_type == 'hanning':
            window_func = np.hanning(window_size + 1)[:-1]
        elif window_type == 'hamming':
            window_func = np.hamming(window_size + 1)[:-1]
        elif window_type == 'rectangular' or window_type is None:
            window_func = np.ones(window_size)
        else:
            raise ValueError("Unknown window type {}.".format(window_type))

        # pad window if `fft_size > window_size`
        if fft_size > window_size:
            diff = fft_size - window_size
            window_func = np.pad(window_func, (diff // 2, diff - diff // 2),
                                 mode='constant')
        elif fft_size < window_size:
            raise ValueError(
                "FFT size has to be as least as large as window size.")

        # compute inverse STFT filter coefficients
        if fft_size % stride != 0:
            raise ValueError("FFT size needs to be a multiple of stride.")

        inv_window_func = np.zeros_like(window_func)
        for s in range(0, fft_size, stride):
            inv_window_func += np.roll(np.square(window_func), s)

        mat_cos = np.zeros((fft_size // 2 + 1, 1, fft_size))
        mat_sin = np.zeros((fft_size // 2 + 1, 1, fft_size))

        for w in range(fft_size // 2 + 1):
            alpha = 1.0 if w == 0 or w == fft_size // 2 else 2.0
            alpha /= fft_size
            for t in range(fft_size):
                mat_cos[w, 0, t] = alpha * \
                    np.cos(2. * np.pi * w * t / fft_size)
                mat_sin[w, 0, t] = alpha * \
                    np.sin(2. * np.pi * w * t / fft_size)
        mat_cos = mat_cos * window_func / inv_window_func
        mat_sin = mat_sin * window_func / inv_window_func

        conv_cos = get_parameter_or_create('conv_sin',
                                           initializer=mat_cos,
                                           need_grad=False)
        conv_sin = get_parameter_or_create('conv_cos',
                                           initializer=mat_sin,
                                           need_grad=False)

    # compute inverse STFT
    x_cos = deconvolution(y_r, conv_cos, stride=(stride, ))
    x_sin = deconvolution(y_i, conv_sin, stride=(stride, ))

    x = reshape(x_cos - x_sin, (x_cos.shape[0], x_cos.shape[2]))

    if center:
        x = x[:, fft_size // 2:-fft_size // 2]

    return x
Пример #9
0
def stft(x,
         window_size,
         stride,
         fft_size,
         window_type='hanning',
         center=True,
         pad_mode='reflect'):
    """Computes the short-time Fourier transform

    Args:
        x (~nnabla.Variable): Time domain sequence of size `batch_size x sample_size`.
        window_size (int): Size of STFT analysis window.
        stride (int): Number of samples that we shift the window, also called `hop size`.
        fft_size (int): Size of the FFT, the output will have `fft_size // 2+ 1` frequency bins.
        window_type (str): Analysis window, can be either `hanning`, `hamming` or `rectangular`.
            For convenience, also `window_type=None` is supported which is equivalent to `window_type='rectangular'`.
        center (bool): If `True`, then the signal `x` is padded by half the FFT size using reflection padding.
        pad_mode (str): Padding mode, which can be `'constant'` or `'reflect'`. `'constant'` pads with `0`.

    Returns:
        Returns real and imaginary parts of STFT result.

        * :obj:`~nnabla.Variable`: Real part of STFT of size `batch_size x fft_size//2 + 1 x frame_size`.
        * :obj:`~nnabla.Variable`: Imaginary part of STFT of size `batch x fft_size//2 + 1 x frame_size`.
    """
    from nnabla.parameter import get_parameter, get_parameter_or_create
    conv_r = get_parameter('conv_r')
    conv_i = get_parameter('conv_i')

    if conv_r is None or conv_i is None:
        if window_type == 'hanning':
            window_func = np.hanning(window_size + 1)[:-1]
        elif window_type == 'hamming':
            window_func = np.hamming(window_size + 1)[:-1]
        elif window_type == 'rectangular' or window_type is None:
            window_func = np.ones(window_size)
        else:
            raise ValueError("Unknown window type {}.".format(window_type))

        # pad window if `fft_size > window_size`
        if fft_size > window_size:
            diff = fft_size - window_size
            window_func = np.pad(window_func, (diff // 2, diff - diff // 2),
                                 mode='constant')
        elif fft_size < window_size:
            raise ValueError(
                "FFT size has to be as least as large as window size.")

        # compute STFT filter coefficients
        mat_r = np.zeros((fft_size // 2 + 1, 1, fft_size))
        mat_i = np.zeros((fft_size // 2 + 1, 1, fft_size))

        for w in range(fft_size // 2 + 1):
            for t in range(fft_size):
                mat_r[w, 0, t] = np.cos(2. * np.pi * w * t / fft_size)
                mat_i[w, 0, t] = -np.sin(2. * np.pi * w * t / fft_size)
        mat_r = mat_r * window_func
        mat_i = mat_i * window_func

        conv_r = get_parameter_or_create('conv_r',
                                         initializer=mat_r,
                                         need_grad=False)
        conv_i = get_parameter_or_create('conv_i',
                                         initializer=mat_i,
                                         need_grad=False)

    if center:
        # pad at begin/end (per default this is a reflection padding)
        x = pad(x, (fft_size // 2, fft_size // 2), mode=pad_mode)

    # add channel dimension
    x = reshape(x, (x.shape[0], 1, x.shape[1]), inplace=False)

    # compute STFT
    y_r = convolution(x, conv_r, stride=(stride, ))
    y_i = convolution(x, conv_i, stride=(stride, ))

    return y_r, y_i