# HG changeset patch # User Olivier Delalleau # Date 1243307498 14400 # Node ID 0594cba02fa8a9d57e591856edcb958beb3c5c9c # Parent 573e3370d0fa7c415a9f62fe708e4b75b4b8de0e Some fixes to FillMissing, and added MaskGradient (another Op to move elsewhere later) diff -r 573e3370d0fa -r 0594cba02fa8 pylearn/sandbox/scan_inputs_groups.py --- a/pylearn/sandbox/scan_inputs_groups.py Mon May 25 11:45:37 2009 -0400 +++ b/pylearn/sandbox/scan_inputs_groups.py Mon May 25 23:11:38 2009 -0400 @@ -568,8 +568,13 @@ Given an input, output two elements: - a copy of the input where missing values (NaN) are replaced by some constant (zero by default) - - a boolean (actually int8) mask of the same size as input, where each - element is True (i.e. 1) iff the corresponding input is not missing + - a mask of the same size and type as input, where each element is zero + iff the corresponding input is missing + Currently, the gradient is computed as if the input value was really zero. + It may be safer to replace the gradient w.r.t. missing values with either + zeros or missing values (?). + ***NOTE*** This is a debug implementation using a special code for missing + values (-123456) """ def __init__(self, constant_val=0): @@ -583,7 +588,7 @@ return hash(type(self))^hash(self.constant_val) def make_node(self, input): - return Apply(self, [input], [input.type(), T.bmatrix()]) + return Apply(self, [input], [input.type(), input.type()]) def perform(self, node, inputs, output_storage): input = inputs[0] @@ -591,15 +596,41 @@ out[0] = input.copy() out = out[0] mask = output_storage[1] - mask[0] = numpy.ones(input.shape, dtype = numpy.int8) + mask[0] = numpy.ones(input.shape) mask = mask[0] for (idx, v) in numpy.ndenumerate(out): - if numpy.isnan(v): + if v == -123456: out[idx] = self.constant_val mask[idx] = 0 + def grad(self, inputs, (out_grad, mask_grad, )): + return [out_grad] + fill_missing_with_zeros = FillMissing(0) +class MaskGradient(Op): + """ + Takes as input a tensor and a mask. Outputs the same tensor, but setting + to zero the gradient for all elements where the mask's value is zero. + """ + + def __eq__(self, other): + return type(self) == type(other) + + def __hash__(self): + return hash(type(self)) + + def make_node(self, input, mask): + return Apply(self, [input, mask], [input.type()]) + + def perform(self, node, (input, mask), (output, )): + output[0] = input.copy() + + def grad(self, (input, mask), (out_grad, )): + return [out_grad * T.neq(mask, 0), None] + +mask_gradient = MaskGradient() + class MaskSelect(Op): """ Given an input x and a mask m (both vectors), outputs a vector that