neural_filter_1L.py 2.34 KB
Newer Older
Francois Marelli's avatar
Francois Marelli committed
1 2 3 4
"""
NeuralFilter1P
**************

5
This module implements a trainable all-pole first order with linear combination input filter using pyTorch
Francois Marelli's avatar
Francois Marelli committed
6 7 8


Copyright (c) 2018 Idiap Research Institute, http://www.idiap.ch/
Francois Marelli's avatar
Francois Marelli committed
9

Francois Marelli's avatar
Francois Marelli committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Written by Francois Marelli <Francois.Marelli@idiap.ch>

This file is part of neural_filters.

neural_filters is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.

neural_filters is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with neural_filters. If not, see <http://www.gnu.org/licenses/>.

"""

import torch
from torch.nn import Parameter
from torch.nn import functional as F
import math
Francois Marelli's avatar
Francois Marelli committed
32
from . import NeuralFilter
Francois Marelli's avatar
Francois Marelli committed
33

Francois Marelli's avatar
Francois Marelli committed
34
class NeuralFilter1L(NeuralFilter):
Francois Marelli's avatar
Francois Marelli committed
35
    """
36
    A trainable first-order all-pole filter :math:`\\frac{K}{1 - P z^{-1}}` with bias on the input
Francois Marelli's avatar
Francois Marelli committed
37 38 39 40 41 42

    * **input_size** (int) - the size of the input vector
    * **hidden_size** (int) - the size of the output vector
    """

    def __init__(self, input_size, hidden_size):
Francois Marelli's avatar
Francois Marelli committed
43
        super(NeuralFilter1L, self).__init__(hidden_size)
Francois Marelli's avatar
Francois Marelli committed
44 45 46

        self.input_size = input_size

Francois Marelli's avatar
Francois Marelli committed
47 48 49
        self.weight_in = Parameter(torch.Tensor(hidden_size, input_size))
        self.bias_in = Parameter(torch.Tensor(hidden_size))

Francois Marelli's avatar
Francois Marelli committed
50 51
        self.reset_parameters()

52 53 54 55
    def __repr__(self):
        s = '{name}({input_size},{hidden_size})'
        return s.format(name=self.__class__.__name__, **self.__dict__)

Francois Marelli's avatar
Francois Marelli committed
56
    def reset_parameters(self, init=None):
Francois Marelli's avatar
Francois Marelli committed
57 58 59 60
        stdv = 1.0 / math.sqrt(self.hidden_size)
        for weight in self.parameters():
            weight.data.uniform_(-stdv, stdv)

Francois Marelli's avatar
Francois Marelli committed
61
        super(NeuralFilter1L, self).reset_parameters(init)
Francois Marelli's avatar
Francois Marelli committed
62 63 64 65 66 67 68 69

    def check_forward_input(self, input):
        if input.size(-1) != self.input_size:
            raise RuntimeError(
                "input has inconsistent input_size(-1): got {}, expected {}".format(
                    input.size(1), self.input_size))

    def step(self, input, hidden):
Francois Marelli's avatar
Francois Marelli committed
70
        in_gate = F.linear(input, self.weight_in, self.bias_in)
Francois Marelli's avatar
Francois Marelli committed
71
        next = super(NeuralFilter1L, self).step(in_gate, hidden)
Francois Marelli's avatar
Francois Marelli committed
72
        return next