## @package BlobWeightedSum # Module caffe2.python.layers.blob_weighted_sum from caffe2.python import schema from caffe2.python.layers.layers import ModelLayer class BlobWeightedSum(ModelLayer): """ This layer implements the weighted sum: weighted element-wise sum of input blobs. """ def __init__( self, model, input_record, init_weights=None, weight_optim=None, name='blob_weighted_sum', **kwargs ): super(BlobWeightedSum, self).__init__(model, name, input_record, **kwargs) self.blobs = self.input_record.field_blobs() self.num_weights = len(self.blobs) assert self.num_weights > 1, ( "BlobWeightedSum expects more than one input blobs" ) assert len(input_record.field_types()[0].shape) > 0, ( "BlobWeightedSum expects limited dimensions of the input tensor" ) assert all( input_record.field_types()[0].shape == input_record.field_types()[i].shape for i in range(1, self.num_weights) ), "Shape of input blobs should be the same shape {}".format( input_record.field_types()[0].shape ) if init_weights: assert self.num_weights == len(init_weights), ( "the size of init_weights should be the same as input blobs, " "expects {}, got {}".format(self.num_weights, len(init_weights)) ) else: init_weights = [1.0] * self.num_weights self.weights = [ self.create_param( param_name="w_{}".format(idx), shape=[1], initializer=('ConstantFill', {'value': float(init_weights[idx])}), optimizer=weight_optim ) for idx in range(self.num_weights) ] self.output_schema = schema.Scalar( input_record.field_types()[0], self.get_next_blob_reference('blob_weighted_sum_out') ) def add_ops(self, net): net.WeightedSum( [x for pair in zip(self.blobs, self.weights) for x in pair], self.output_schema(), grad_on_w=True, )