class NaiveConvolutionalFeatureMap(BaseBPropComponent): """ One way to implement a standard feature map that takes input from a single lower-level image. This serves two purposes: to demonstrate how to write new learning modules by composing two existing modules, and to serve as a sanity check for the more efficient implementation, ConvolutionalFeatureMap. Has, as members, a ConvolutionalPlane with standard bias configuration and a TanhSigmoid object that does the squashing. This is a little wasteful since each of the modules has separate output array members. See FeatureMap for a slightly more memory efficient implementation that uses subclassing. """ def __init__(self, fsize, imsize): """Construct a feature map with given filter size and image size.""" super(NaiveConvolutionalFeatureMap, self).__init__() self.convolution = ConvolutionalPlane(fsize, imsize) self.nonlinearity = TanhSigmoid(self.convolution.outsize) def fprop(self, inputs): """Forward propagate input through this module.""" return self.nonlinearity.fprop(self.convolution.fprop(inputs)) def bprop(self, dout, inputs): """ Backpropagate derivatives through this module to get derivatives with respect to this module's input. """ squash_inputs = self.convolution.fprop(inputs) squash_derivs = self.nonlinearity.bprop(dout, squash_inputs) return self.convolution.bprop(squash_derivs, inputs) def grad(self, dout, inputs): """ Gradient of the error with respect to the parameters of this module. Parameters: * dout -- derivative of the outputs of this module (will be size of input - size of filter + 1, elementwise) * inputs -- inputs to this module """ squash_inputs = self.convolution.fprop(inputs) squash_derivs = self.nonlinearity.bprop(dout, squash_inputs) return self.convolution.grad(squash_derivs, inputs) def initialize(self): """Initialize the module's weights.""" self.convolution.initialize() @property def outsize(self): """Output size.""" return self.convolution.outsize @property def imsize(self): """Image input size.""" return self.convolution.imsize @property def fsize(self): """Filter shape.""" return self.convolution.filter.shape