Skip to content

Commit

Permalink
Merge pull request #921 from dwf/die_conv_layer_die
Browse files Browse the repository at this point in the history
Get rid of ConvolutionalLayer.
  • Loading branch information
rizar committed Nov 26, 2015
2 parents df5c55c + 589543e commit 3eddcf8
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 118 deletions.
73 changes: 2 additions & 71 deletions blocks/bricks/conv.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,83 +386,14 @@ def _push_allocation_config(self):
self.convolution.step = self.step


class ConvolutionalLayer(_AllocationMixin, Sequence, Initializable):
"""A complete convolutional layer: Convolution, nonlinearity, pooling.
.. todo::
Mean pooling.
Parameters
----------
activation : :class:`.BoundApplication`
The application method to apply in the detector stage (i.e. the
nonlinearity before pooling. Needed for ``__init__``.
See Also
--------
:class:`Convolutional` : Documentation of convolution arguments.
:class:`MaxPooling` : Documentation of pooling arguments.
Notes
-----
Uses max pooling.
"""
@lazy(allocation=['filter_size', 'num_filters', 'pooling_size',
'num_channels'])
def __init__(self, activation, filter_size, num_filters, pooling_size,
num_channels, conv_step=(1, 1), pooling_step=None,
batch_size=None, image_size=None, border_mode='valid',
tied_biases=False, **kwargs):
self.convolution = ConvolutionalActivation(activation)
self.pooling = MaxPooling()
super(ConvolutionalLayer, self).__init__(
application_methods=[self.convolution.apply,
self.pooling.apply], **kwargs)
self.convolution.name = self.name + '_convolution'
self.pooling.name = self.name + '_pooling'

self.filter_size = filter_size
self.num_filters = num_filters
self.num_channels = num_channels
self.pooling_size = pooling_size
self.conv_step = conv_step
self.pooling_step = pooling_step
self.batch_size = batch_size
self.border_mode = border_mode
self.image_size = image_size
self.tied_biases = tied_biases

def _push_allocation_config(self):
super(ConvolutionalLayer, self)._push_allocation_config()
self.convolution.step = self.conv_step
self.convolution._push_allocation_config()
if self.image_size is not None:
pooling_input_dim = self.convolution.get_dim('output')
else:
pooling_input_dim = None
self.pooling.input_dim = pooling_input_dim
self.pooling.pooling_size = self.pooling_size
self.pooling.step = self.pooling_step
self.pooling.batch_size = self.batch_size

def get_dim(self, name):
if name == 'input_':
return self.convolution.get_dim('input_')
if name == 'output':
return self.pooling.get_dim('output')
return super(ConvolutionalLayer, self).get_dim(name)


class ConvolutionalSequence(Sequence, Initializable, Feedforward):
"""A sequence of convolutional operations.
Parameters
----------
layers : list
List of convolutional bricks (i.e. :class:`ConvolutionalActivation`
or :class:`ConvolutionalLayer`)
List of convolutional bricks (i.e. :class:`Convolutional` or
:class:`ConvolutionalActivation`).
num_channels : int
Number of input channels in the image. For the first layer this is
normally 1 for grayscale images and 3 for color (RGB) images. For
Expand Down
56 changes: 9 additions & 47 deletions tests/bricks/test_conv.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
from nose.tools import assert_raises_regexp

import theano
from numpy.testing import assert_allclose, assert_equal
from numpy.testing import assert_allclose
from theano import tensor
from theano import function

from blocks.bricks import Rectifier
from blocks.bricks.conv import (Convolutional, ConvolutionalLayer, MaxPooling,
AveragePooling, ConvolutionalActivation,
ConvolutionalSequence)
from blocks.bricks.conv import (Convolutional, MaxPooling, AveragePooling,
ConvolutionalActivation, ConvolutionalSequence)
from blocks.initialization import Constant
from blocks.graph import ComputationGraph

Expand Down Expand Up @@ -42,7 +41,7 @@ def test_border_mode_not_pushed():
layers = [Convolutional(border_mode='full'),
ConvolutionalActivation(Rectifier().apply),
ConvolutionalActivation(Rectifier().apply, border_mode='valid'),
ConvolutionalLayer(Rectifier().apply, border_mode='full')]
ConvolutionalActivation(Rectifier().apply, border_mode='full')]
stack = ConvolutionalSequence(layers)
stack.push_allocation_config()
assert stack.children[0].border_mode == 'full'
Expand Down Expand Up @@ -223,50 +222,21 @@ def test_pooling_works_in_convolutional_sequence():
assert out.shape == (2, 3, 3, 7)


def test_convolutional_layer():
x = tensor.tensor4('x')
num_channels = 4
batch_size = 5
pooling_size = 3
num_filters = 3
filter_size = (3, 3)
activation = Rectifier().apply

conv = ConvolutionalLayer(activation, filter_size, num_filters,
(pooling_size, pooling_size),
num_channels, image_size=(17, 13),
batch_size=batch_size,
weights_init=Constant(1.),
biases_init=Constant(5.))
conv.initialize()

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

x_val = numpy.ones((batch_size, num_channels, 17, 13),
dtype=theano.config.floatX)
assert_allclose(func(x_val), numpy.prod(filter_size) * num_channels *
numpy.ones((batch_size, num_filters, 5, 3)) + 5)

assert_equal(conv.convolution.batch_size, batch_size)
assert_equal(conv.pooling.batch_size, batch_size)


def test_convolutional_sequence():
x = tensor.tensor4('x')
num_channels = 4
pooling_size = 3
batch_size = 5
activation = Rectifier().apply

conv = ConvolutionalLayer(activation, (3, 3), 5,
(pooling_size, pooling_size),
weights_init=Constant(1.),
biases_init=Constant(5.))
conv = ConvolutionalActivation(activation, (3, 3), 5,
weights_init=Constant(1.),
biases_init=Constant(5.))
pooling = MaxPooling(pooling_size=(pooling_size, pooling_size))
conv2 = ConvolutionalActivation(activation, (2, 2), 4,
weights_init=Constant(1.))

seq = ConvolutionalSequence([conv, conv2], num_channels,
seq = ConvolutionalSequence([conv, pooling, conv2], num_channels,
image_size=(17, 13))
seq.push_allocation_config()
assert conv.num_channels == 4
Expand All @@ -290,14 +260,6 @@ def test_convolutional_activation_use_bias():
assert len(ComputationGraph([act.apply(tensor.tensor4())]).parameters) == 1


def test_convolutional_layer_use_bias():
act = ConvolutionalLayer(Rectifier().apply, (3, 3), 5, (2, 2), 6,
image_size=(9, 9), use_bias=False)
act.allocate()
assert not act.convolution.use_bias
assert len(ComputationGraph([act.apply(tensor.tensor4())]).parameters) == 1


def test_convolutional_sequence_use_bias():
cnn = ConvolutionalSequence(
[ConvolutionalActivation(activation=Rectifier().apply,
Expand Down

0 comments on commit 3eddcf8

Please sign in to comment.