Skip to content

Commit

Permalink
Merge pull request #1108 from davidbau/tied_biases
Browse files Browse the repository at this point in the history
Convolutions should default to tied_biases=True.
  • Loading branch information
dwf committed Jun 3, 2016
2 parents de0dbfc + 10be468 commit 9d32e57
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
8 changes: 4 additions & 4 deletions blocks/bricks/conv.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class Convolutional(LinearLike):
The border mode to use, see :func:`scipy.signal.convolve2d` for
details. Defaults to 'valid'.
tied_biases : bool
If ``True``, it indicates that the biases of every filter in this
layer should be shared amongst all applications of that filter.
Setting this to ``False`` will untie the biases, yielding a
separate bias for every location at which the filter is applied.
Defaults to ``False``.
If ``True``, it indicates that the biases of every filter in this
layer should be shared amongst all applications of that filter.
Defaults to ``True``.
"""
# Make it possible to override the implementation of conv2d that gets
Expand All @@ -71,7 +71,7 @@ class Convolutional(LinearLike):
@lazy(allocation=['filter_size', 'num_filters', 'num_channels'])
def __init__(self, filter_size, num_filters, num_channels, batch_size=None,
image_size=(None, None), step=(1, 1), border_mode='valid',
tied_biases=False, **kwargs):
tied_biases=True, **kwargs):
super(Convolutional, self).__init__(**kwargs)

self.filter_size = filter_size
Expand Down
43 changes: 41 additions & 2 deletions tests/bricks/test_conv.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,58 @@ def test_no_input_size():
c.initialize)


def test_tied_biases():
def test_untied_biases():
x = tensor.tensor4('x')
num_channels = 4
num_filters = 3
batch_size = 5
filter_size = (3, 3)
conv = Convolutional(filter_size, num_filters, num_channels,
weights_init=Constant(1.), biases_init=Constant(2.),
tied_biases=True)
image_size=(28, 30), tied_biases=False)
conv.initialize()

y = conv.apply(x)
func = function([x], y)

# Untied biases provide a bias for every individual output
assert_allclose(conv.b.eval().shape, (3, 26, 28))

# Untied biases require images of a specific size
x_val_1 = numpy.ones((batch_size, num_channels, 28, 30),
dtype=theano.config.floatX)

assert_allclose(func(x_val_1),
numpy.prod(filter_size) * num_channels *
numpy.ones((batch_size, num_filters, 26, 28)) + 2)

x_val_2 = numpy.ones((batch_size, num_channels, 23, 19),
dtype=theano.config.floatX)

def wrongsize():
func(x_val_2)

assert_raises_regexp(ValueError, 'Input dimension mis-match.*',
wrongsize)


def test_tied_biases():
x = tensor.tensor4('x')
num_channels = 4
num_filters = 3
batch_size = 5
filter_size = (3, 3)

# Tied biases are the default
conv = Convolutional(filter_size, num_filters, num_channels,
weights_init=Constant(1.), biases_init=Constant(2.))
conv.initialize()
y = conv.apply(x)
func = function([x], y)

# Tied biases only provide one bias for each filter
assert_allclose(conv.b.eval().shape, (3,))

# Tied biases allows to pass images of different sizes
x_val_1 = numpy.ones((batch_size, num_channels, 10,
12), dtype=theano.config.floatX)
Expand Down

0 comments on commit 9d32e57

Please sign in to comment.