def __init__(self, input_node, output_format, filter_shape=None): assert_equal(output_format.axes, ('b', 'c', '0', '1')) if filter_shape is None: filter_shape = (1, 1) else: assert_equal(len(filter_shape), 2) filter_shape = numpy.asarray(filter_shape) assert_equal(input_node.output_format.axes, ('b', 'c', '0', '1')) input_shape = numpy.asarray(input_node.output_format.shape)[2:] assert_equal(tuple(output_format.shape[2:]), tuple(input_shape - filter_shape + 1)) channel_axis = 'c' def get_num_filters(): c_index = output_format.axes.index(channel_axis) return output_format.shape[c_index] # def get_filter_shape(): # fmt = input_node.output_format # assert_equal(fmt.axes, ('b', 'c', '0', '1')) # return fmt.shape[2:] # if filter_shape is None: # filter_shape = get_filter_shape() self.conv2d_node = CuDnnConv2d(input_node=input_node, filter_shape=filter_shape, num_filters=get_num_filters(), pads='valid') non_channel_axes = tuple(axis for axis in self.conv2d_node.output_format.axes if axis != channel_axis) self.bias_node = Bias(self.conv2d_node, output_format=self.conv2d_node.output_format, input_to_bf_map={non_channel_axes: 'b', channel_axis: 'f'}, bf_to_output_map={'b': non_channel_axes, 'f': channel_axis}) # input_to_bf_map={('c', '0', '1'): 'f'}, # bf_to_output_map={'f': ('c', '0', '1')}) assert_equal(self.bias_node.output_format.axes, output_format.axes) assert_equal(self.bias_node.output_format.shape, output_format.shape) super(Conv11AffineTransform, self).__init__( input_node, self.bias_node.output_symbol, output_format)
class Conv11AffineTransform(Node): ''' Equivalent to an AffineTransform, except the output is a 1x1 feature map. A sequence of conv2d -> channel-wise bias Unlike a Conv2dLayer, this does not pool the ReLU output. Output format is bc01, (B, C, 1, 1), where C is the number of output ''' def __init__(self, input_node, output_format, filter_shape=None): assert_equal(output_format.axes, ('b', 'c', '0', '1')) if filter_shape is None: filter_shape = (1, 1) else: assert_equal(len(filter_shape), 2) filter_shape = numpy.asarray(filter_shape) assert_equal(input_node.output_format.axes, ('b', 'c', '0', '1')) input_shape = numpy.asarray(input_node.output_format.shape)[2:] assert_equal(tuple(output_format.shape[2:]), tuple(input_shape - filter_shape + 1)) channel_axis = 'c' def get_num_filters(): c_index = output_format.axes.index(channel_axis) return output_format.shape[c_index] # def get_filter_shape(): # fmt = input_node.output_format # assert_equal(fmt.axes, ('b', 'c', '0', '1')) # return fmt.shape[2:] # if filter_shape is None: # filter_shape = get_filter_shape() self.conv2d_node = CuDnnConv2d(input_node=input_node, filter_shape=filter_shape, num_filters=get_num_filters(), pads='valid') non_channel_axes = tuple(axis for axis in self.conv2d_node.output_format.axes if axis != channel_axis) self.bias_node = Bias(self.conv2d_node, output_format=self.conv2d_node.output_format, input_to_bf_map={non_channel_axes: 'b', channel_axis: 'f'}, bf_to_output_map={'b': non_channel_axes, 'f': channel_axis}) # input_to_bf_map={('c', '0', '1'): 'f'}, # bf_to_output_map={'f': ('c', '0', '1')}) assert_equal(self.bias_node.output_format.axes, output_format.axes) assert_equal(self.bias_node.output_format.shape, output_format.shape) super(Conv11AffineTransform, self).__init__( input_node, self.bias_node.output_symbol, output_format) def _save_to_h5(self, group): self.conv2d_node.save_to_h5(group.create_group('conv2d_node')) self.bias_node.save_to_h5(group.create_group('bias_node')) def _load_from_h5(self, group, **kwargs): self.conv2d_node.load_from_h5(group['conv2d_node'], **kwargs) self.bias_node.load_from_h5(group['bias_node'], **kwargs) def _get_shared_vars(self): return (self.conv2d_node.get_shared_vars() + self.bias_node.get_shared_vars())