Merge pull request #684 from jmhessel/mergefixes

Added averaging support in merge and a TimeDistributedMerge layer
This commit is contained in:
François Chollet 2015-09-22 20:12:26 -07:00
commit c18a9cd405
2 changed files with 39 additions and 2 deletions

@ -161,11 +161,42 @@ class Masking(MaskedLayer):
return {"name": self.__class__.__name__,
"mask_value": self.mask_value}
class TimeDistributedMerge(Layer):
def __init__(self, mode='sum'):
'''
Sum/multiply/avearge over a time distributed layer's outputs.
mode: {'sum', 'mul', 'ave'}
Tensor input dimensions: (nb_sample, shared_dimension, input_dim)
Tensor output dimensions: (nb_sample, output_dim)
'''
self.mode = mode
self.params = []
self.regularizers = []
self.constraints = []
self.updates = []
def get_output(self, train=False):
X = self.get_input(train)
if self.mode == 'sum' or self.mode == 'ave':
s = theano.tensor.sum(X, axis=1)
if self.mode == 'ave':
s /= X.shape[1]
return s
elif self.mode == 'mul':
s = theano.tensor.mul(X, axis=1)
return s
else:
raise Exception('Unknown merge mode')
def get_config(self):
return {"name": self.__class__.__name__,
"mode": self.mode}
class Merge(Layer):
def __init__(self, layers, mode='sum', concat_axis=-1):
''' Merge the output of a list of layers or containers into a single tensor.
mode: {'sum', 'mul', 'concat'}
mode: {'sum', 'mul', 'concat', 'ave'}
'''
if len(layers) < 2:
raise Exception("Please specify two or more input layers (or containers) to merge")
@ -190,10 +221,12 @@ class Merge(Layer):
return self.params, self.regularizers, self.constraints, self.updates
def get_output(self, train=False):
if self.mode == 'sum':
if self.mode == 'sum' or self.mode == 'ave':
s = self.layers[0].get_output(train)
for i in range(1, len(self.layers)):
s += self.layers[i].get_output(train)
if self.mode == 'ave':
s /= len(self.layers)
return s
elif self.mode == 'concat':
inputs = [self.layers[i].get_output(train) for i in range(len(self.layers))]

@ -104,6 +104,10 @@ class TestConfigParams(unittest.TestCase):
layer = core.TimeDistributedDense(10, 10)
self._runner(layer)
def test_time_dist_merge(self):
layer = core.TimeDistributedMerge()
self._runner(layer)
def test_autoencoder(self):
layer_1 = core.Layer()
layer_2 = core.Layer()