Conv1D.py 3.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# @author: Pavel Korshunov <pavel.korshunov@idiap.ch>
# @date: Wed 09 Nov 2016 13:55:22 CEST

import tensorflow as tf
from .Layer import Layer
from bob.learn.tensorflow.initialization import Xavier
from bob.learn.tensorflow.initialization import Constant


class Conv1D(Layer):

    """
    1D Convolution
    **Parameters**

    name: str
      The name of the layer

    activation:
     Tensor Flow activation

    kernel_size: int
      Size of the convolutional kernel

    filters: int
      Number of filters

    stride:
      Shape of the stride

    weights_initialization: py:class:`bob.learn.tensorflow.initialization.Initialization`
      Initialization type for the weights

    bias_initialization: py:class:`bob.learn.tensorflow.initialization.Initialization`
      Initialization type for the weights

    batch_norm: bool
      Do batch norm?

    use_gpu: bool
      Store data in the GPU

    """

    def __init__(self, name, activation=None,
                 kernel_size=300,
                 filters=20,
                 stride=100,
                 weights_initialization=Xavier(),
                 init_value=None,
                 bias_initialization=Constant(),
                 batch_norm=False,
                 use_gpu=False
                 ):
        super(Conv1D, self).__init__(name=name,
                                     activation=activation,
                                     weights_initialization=weights_initialization,
                                     bias_initialization=bias_initialization,
                                     batch_norm=batch_norm,
                                     use_gpu=use_gpu,
                                     )
        self.kernel_size = kernel_size
        self.filters = filters
        self.W = None
        self.b = None
        self.stride = stride
        self.init_value = init_value

    def create_variables(self, input_layer):
        self.input_layer = input_layer

        # TODO: Do an assert here
        if len(input_layer.get_shape().as_list()) != 3:
            raise ValueError("The input as a convolutional layer must have 3 dimensions, "
                             "but {0} were provided".format(len(input_layer.get_shape().as_list())))
        n_channels = input_layer.get_shape().as_list()[2]

        if self.W is None:
            if self.init_value is None:
                self.init_value = self.kernel_size * n_channels
            self.W = self.weights_initialization(shape=[self.kernel_size, n_channels, self.filters],
                                                 name="w_" + str(self.name),
                                                 scope="w_" + str(self.name),
                                                 init_value=self.init_value
                                                 )

            self.b = self.bias_initialization(shape=[self.filters],
                                              name="b_" + str(self.name) + "bias",
                                              scope="b_" + str(self.name),
                                              init_value=self.init_value
                                              )

    def get_graph(self, training_phase=True):

        with tf.name_scope(str(self.name)):
            conv1d = tf.nn.conv1d(self.input_layer, self.W, stride=self.stride, padding='VALID')

            if self.batch_norm:
                conv1d = self.batch_normalize(conv1d, training_phase)

            if self.activation is not None:
                output = self.activation(tf.nn.bias_add(conv1d, self.b))
            else:
                output = tf.nn.bias_add(conv1d, self.b)

            return output