3 from __future__ 
import absolute_import
     4 from __future__ 
import division
     5 from __future__ 
import print_function
     6 from __future__ 
import unicode_literals
     8 from caffe2.python import core, model_helper, schema, scope, utils, muji
    13     parameter_sharing_context,
    20 from caffe2.proto 
import caffe2_pb2
    21 from future.utils 
import viewitems, viewvalues
    27 logger = logging.getLogger(__name__)
    32     Model helper for building models on top of layers abstractions.    34     Each layer is the abstraction that is higher level than Operator. Layer    35     is responsible for ownership of it's own parameters and can easily be    36     instantiated in multiple nets possible with different sets of ops.    37     As an example: one can easily instantiate predict and train nets from    38     the same set of layers, where predict net will have subset of the    39     operators from train net.    42     def __init__(self, name, input_feature_schema, trainer_extra_schema,
    44         ''' TODO(amalevich): more documnetation on input args    47         super(LayerModelHelper, self).
__init__(name=name)
    78         ) 
if not keep_blobs 
else input_feature_schema.clone()
    82         ) 
if not keep_blobs 
else trainer_extra_schema.clone()
    96     def clear_output_schema(self):
    99     def set_initialize_params(self, initialize_params):
   102     def add_metric_field(self, name, value):
   103         assert name 
not in self._metrics_schema.fields, (
   104             "Try to add metric field twice: {}".format(name))
   109     def add_ad_hoc_plot_blob(self, blob, dtype=None):
   112         ), 
"expect type str or BlobReference, but got {}".format(type(blob))
   113         dtype = dtype 
or (np.float, (1, ))
   115         self.ad_hoc_plot_blobs.append(blob)
   118     def _get_global_constant_initializer_op(
   119         blob_name, array=
None, dtype=
None, initializer=
None   123         if array 
is not None:
   124             assert initializer 
is None,\
   125                 "Only one from array and initializer should be specified"   127                 array = np.array(array)
   129                 array = np.array(array, dtype=dtype)
   133             if array.dtype == np.int32:
   134                 op_name = 
'GivenTensorIntFill'   135             elif array.dtype == np.int64:
   136                 op_name = 
'GivenTensorInt64Fill'   137             elif array.dtype == np.str:
   138                 op_name = 
'GivenTensorStringFill'   139             elif array.dtype == np.bool:
   140                 op_name = 
'GivenTensorBoolFill'   142                 op_name = 
'GivenTensorFill'   144             def initializer(blob_name):
   145                 return core.CreateOperator(
   149                     values=array.flatten().tolist()
   152             assert initializer 
is not None   153         initializer_op = initializer(blob_name)
   154         return initializer_op
   156     def add_global_constant(
   157         self, name, array=
None, dtype=
None, initializer=
None   159         assert isinstance(name, six.string_types), (
   160             'name should be a string as we are using it as map key')
   164             "%s already added in global_constants" % name
   165         blob_name = self.net.NextBlob(name)
   167         initializer_op = LayerModelHelper._get_global_constant_initializer_op(
   168             blob_name, array, dtype, initializer
   171             "there is already a initializer op associated with blob %s" % \
   176     def maybe_add_global_constant(self, name, *args, **kwargs):
   184                 LayerModelHelper._get_global_constant_initializer_op(
   185                     blob_name, *args, **kwargs
   189             assert utils.OpAlmostEqual(
   194                 "conflict initializers for global constant %s, " \
   195                 "previous %s, now %s" % (
   196                     blob_name, str(initializer_op),
   201     def _init_global_constants(self):
   208     def _add_global_constants(self, init_net):
   210             init_net._net.op.extend([initializer_op])
   212     def create_init_net(self, name):
   217     def _validate_param_shape(self, param_name, shape):
   223         if shape != ref_shape:
   225                 "Got inconsistent shapes between shared parameters "   226                 "when trying to map a blob in scope {0} to {1}. ref_shape : "   227                 " {2}, shape : {3}".format(
   228                     scope.CurrentNameScope(), param_name, ref_shape, shape)
   231     def create_param(self, param_name, shape, initializer, optimizer=None,
   232                      ps_param=
None, regularizer=
None):
   234             param_name = str(param_name)
   235         elif isinstance(param_name, six.string_types):
   238             param_name = parameter_sharing_context.get_parameter_name(
   241             raise ValueError(
"Unsupported type for param_name")
   245         if len(initializer) == 1:
   248             assert len(initializer) == 2
   249             init_op_args = copy.deepcopy(initializer[1])
   250         if shape 
is not None:
   251             assert 'shape' not in init_op_args
   252             init_op_args.update({
'shape': shape})
   254         initializer_op = 
None   256             initializer_op = core.CreateOperator(
   263         param = layers.LayerParameter(
   264             parameter=param_blob,
   265             initializer=initializer_op,
   268             regularizer=regularizer
   277     def next_layer_name(self, prefix):
   278         base_name = core.ScopedName(prefix)
   282             name = base_name + 
'_auto_' + str(index)
   285         self._layer_names.add(name)
   288     def add_layer(self, layer):
   289         self._layers.append(layer)
   290         for param 
in layer.get_parameters():
   296             self.params.append(param.parameter)
   297             if isinstance(param, layers.LayerParameter):
   299             elif isinstance(param, ParameterInfo):
   306                 logger.info(
'regularization is unsupported for ParameterInfo object')
   309                     'unknown object type besides ParameterInfo and LayerParameter: {}'   317         return layer.output_schema
   319     def get_parameter_blobs(self):
   322             for param 
in layer.get_parameters():
   323                 param_blobs.append(param.parameter)
   327     def add_post_grad_net_modifiers(self, modifier):
   330         assert isinstance(modifier, NetModifier),\
   331             "{} has to be a NetModifier instance".format(modifier)
   332         self._post_grad_net_modifiers.append(modifier)
   334     def add_final_net_modifiers(self, modifier):
   337         assert isinstance(modifier, NetModifier),\
   338             "{} has to be a NetModifier instance".format(modifier)
   339         self._final_net_modifiers.append(modifier)
   346     def sequence_seed(self):
   349     def store_seed(self, seed, sequence_seed=True):
   355     def apply_seed(self, net):
   360     def default_optimizer(self):
   363     @default_optimizer.setter
   364     def default_optimizer(self, optimizer):
   368     def input_feature_schema(self):
   372     def trainer_extra_schema(self):
   378         Returns the schema that represents model output that should be used for   381         During the training/evaluation this schema will be appended to the   382         schema that represents model output.   387     def output_schema(self):
   391     @output_schema.setter
   392     def output_schema(self, schema):
   397     def preproc_output_schema(self):
   401     @preproc_output_schema.setter
   402     def preproc_output_schema(self, schema):
   407     def prediction(self):
   408         assert self.
_prediction, 
"model prediction is empty"   411     def add_prediction(self, prediction, weight=1.0):
   412         assert prediction 
is not None, 
"Added prediction should not be None"   413         self._prediction.append((prediction, weight))
   417         assert self.
_loss is not None   421     def loss(self, loss):
   422         assert self.
_loss is None   426         return self.
_loss is not None   428     def add_loss(self, loss, name='unnamed'):
   429         assert loss 
is not None, 
"Added loss should not be None"   432         ), 
"Added loss should be a scalar or a struct"   433         if self.
_loss is None:
   441             prefix_base = name + 
'_auto_'   444             while prefix 
in self.
_loss:
   445                 prefix = prefix_base + str(index)
   450     def add_output_schema(self, name, value):
   451         assert value 
is not None, \
   452             'Added output schema {} should not be None'.format(name)
   455             'Added output schema {} should be a scalar or a struct.\n\   456             Now it is {}.'.format(name, type(value))
   460             assert name 
not in self._output_schema.fields, \
   461                 'Output Schema Field {} already exists'.format(name)
   465     def add_trainer_extra_schema(self, trainer_extra_schema):
   466         trainer_extra_record = schema.NewRecord(self.
net, trainer_extra_schema)
   469     def __getattr__(self, layer):
   470         def is_functional_layer(layer):
   471             if core.IsOperator(layer):
   473             elif layer.startswith(
'FunctionalLayer'):
   478         def resolve_functional_layer(layer):
   479             if core.IsOperator(layer):
   481             elif layer.startswith(
'FunctionalLayer'):
   482                 return layer[len(
'FunctionalLayer'):]
   485                     '%s cannot be resolved as functional layer' % layer
   488         if layer.startswith(
'__'):
   489             raise AttributeError(layer)
   492         if layers.layer_exists(layer):
   493             def wrapper(*args, **kwargs):
   494                 new_layer = layers.create_layer(layer, self, *args, **kwargs)
   495                 if kwargs.get(
"output_to_metrics", 
False):
   496                     new_layer.export_output_for_metrics()
   497                 if kwargs.get(
"params_to_metrics", 
False):
   498                     new_layer.export_params_for_metrics()
   501         elif is_functional_layer(layer):
   505             layer = resolve_functional_layer(layer)
   507             def wrapper(*args, **kwargs):
   508                 def apply_operator(net, in_record, out_record, **kwargs):
   511                     net.__getattr__(layer)(in_record.field_blobs(),
   512                                            out_record.field_blobs(),
   515                 if 'name' not in kwargs:
   516                     kwargs[
'name'] = layer
   518                 new_layer = layers.create_layer(
   520                     self, *args, function=apply_operator,
   524                 if kwargs.get(
"output_to_metrics", 
False):
   525                     new_layer.export_output_for_metrics()
   526                 if kwargs.get(
"params_to_metrics", 
False):
   527                     new_layer.export_params_for_metrics()
   533             raise AttributeError(
   534                 "Trying to create non-registered layer: {}".format(layer))
   540     def apply_regularizers_on_loss(
   547             if regularizer 
is None:
   549             assert isinstance(regularizer, Regularizer)
   550             added_loss_blob = regularizer(train_net, train_init_net, param, grad=
None,
   551                                           by=RegularizationBy.ON_LOSS)
   552             if added_loss_blob 
is not None:
   558     def apply_regularizers_after_optimizer(
   567         blob_to_device = blob_to_device 
or {}
   569             if regularizer 
is None:
   571             assert isinstance(regularizer, Regularizer)
   572             device = get_param_device(
   574                 grad_map.get(str(param)),
   575                 param_to_device=blob_to_device,
   578             with core.DeviceScope(device):
   580                     train_net, train_init_net, param, grad=grad_map.get(str(param)),
   581                     by=RegularizationBy.AFTER_OPTIMIZER
   584     def apply_post_grad_net_modifiers(
   590         modify_output_record=
False,
   592         param_grad_map = {param: grad_map[param]
   593                           for param 
in self.param_to_optim.keys() 
if param 
in grad_map}
   596             modifier(trainer_net, trainer_init_net, param_grad_map,
   597                      blob_to_device=blob_to_device,
   598                      modify_output_record=modify_output_record)
   600     def apply_final_net_modifiers(
   606         modify_output_record=
False,
   609             modifier(trainer_net, trainer_init_net, grad_map,
   610                      blob_to_device=blob_to_device,
   611                      modify_output_record=modify_output_record)
   613     def apply_optimizers(
   622         blob_to_device = blob_to_device 
or {}
   624             assert optimizer 
is not None, \
   625                 "default optimizer must have been set in add_layer"   628             device = get_param_device(
   630                 grad_map.get(str(param)),
   631                 param_to_device=blob_to_device,
   634             if device 
is not None:
   636                 del device.extra_info[:]
   638             with core.DeviceScope(device):
   640                     train_net, train_init_net, param, grad_map.get(str(param)))
   646     def NoOptim(self, *args, **kwargs):
   650     def breakdown_map(self):
   653     @breakdown_map.setter
   654     def breakdown_map(self, breakdown_map):
   657         assert isinstance(breakdown_map, dict)
   658         assert all(isinstance(k, six.string_types) 
for k 
in breakdown_map)
   659         assert sorted(breakdown_map.values()) == list(range(len(breakdown_map)))
 
def default_optimizer(self)
 
def add_global_constant(self, name, array=None, dtype=None, initializer=None)
 
def add_metric_field(self, name, value)
 
def _validate_param_shape(self, param_name, shape)
 
global_constant_initializers
 
Module caffe2.python.layers.layers. 
 
def _init_global_constants(self)
 
def add_loss(self, loss, name='unnamed')
 
ad_hoc_diagnose_blobs_and_operations
 
def add_layer(self, layer)
 
def _add_global_constants(self, init_net)
 
def __init__(self, name, input_feature_schema, trainer_extra_schema, keep_blobs=False)
 
def create_init_net(self, name)