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 schema, scope
9 from caffe2.python.layers.tags
import TagContext
11 from collections
import namedtuple
19 def get_categorical_limit(record):
25 raise NotImplementedError()
26 assert record[key].metadata
is not None, (
27 "Blob {} doesn't have metadata".format(str(record[key]())))
28 return record[key].metadata.categorical_limit
33 List of contexts where layer could be instantitated 35 CALIBRATION =
'calibration' 37 PREDICTION =
'prediction' 44 def register_layer(name, layer):
45 assert name
not in _LAYER_REGISTRY,
"{0} already exists".format(name)
46 _LAYER_REGISTRY[name] = layer
49 def layer_exists(name):
50 return name
in _LAYER_REGISTRY
53 def get_layer_class(name):
54 return _LAYER_REGISTRY[name]
57 def create_layer(layer_name, *args, **kwargs):
58 return _LAYER_REGISTRY[layer_name](*args, **kwargs)
61 LayerPsParam = namedtuple(
'LayerPsParam', [
'sparse_key',
'average_length'])
66 LayerParameter = namedtuple(
68 [
'parameter',
'optimizer',
'initializer',
'ps_param'])
69 LayerParameter.__new__.__defaults__ = (
None,
None,
None,
None)
72 def _is_request_only_scalar(scalar):
73 if len(scalar.field_metadata()) == 0:
75 for metadata
in scalar.field_metadata():
76 if not (metadata
and metadata.feature_specs
and getattr(
77 metadata.feature_specs,
'feature_is_request_only',
False)):
84 def __init__(self, model, prefix, input_record,
85 predict_input_record_fields=None, tags=None, **kwargs):
87 Base class for model layers. Layer is an abstraction that allows to 88 provide model description in terms of meta-operators, where each of the 89 meta-operators can have different implementations for training, 90 evaluation and prediction, that are instantiated later. As an example 91 SampledSoftmax can do something related to sampling depending on 92 supervision during the training and just apply softmax if it's used for 93 prediction/evaluation. 95 All inputs/outputs from layers are represented as a record (instance of 96 schema bounded to blobs) and are accessible through input_record and 97 output_schema. If Layer needs to have only a subset of inputs/provides 98 subset of outputs during the inference - it should provide 99 predict_input_record and predict_output_schema correspondingly (those 100 records are expected to be a subset of input_record/output_schema). 102 Each layer is also have list of Tags associated with it, that depends on 103 current context and arguments. It's possible to use those tags during 104 the instantiation time. 107 self.
name = model.next_layer_name(prefix)
111 if predict_input_record_fields:
112 if not isinstance(predict_input_record_fields, list):
113 predict_input_record_fields = [predict_input_record_fields]
115 predict_input_record_fields]
120 if len(input_record.all_scalars()) == 0:
122 for scalar
in input_record.all_scalars():
123 if not _is_request_only_scalar(scalar):
130 self.
tags = set(tags
or [])
131 self.
tags.update(TagContext.current().tags)
135 return self.__class__.__name__
137 def _check_output_schema(self):
138 assert self.
_output_schema is not None,
"Schema is not initialized" 142 "predict_output_schema is not a subset of the output_schema")
145 def predict_input_record(self):
149 def input_record(self):
153 def predict_output_schema(self):
157 @predict_output_schema.setter
158 def predict_output_schema(self, output_schema):
163 def output_schema(self):
167 @output_schema.setter
168 def output_schema(self, output_schema):
172 def get_parameters(self):
176 """Return a subset of parameters which can be converted to fp16""" 179 def get_memory_usage(self):
182 def add_operators(self, net, init_net=None,
183 context=InstantiationContext.TRAINING):
187 if context
not in {InstantiationContext.PREDICTION,
188 InstantiationContext.EVAL,
189 InstantiationContext.CALIBRATION}:
191 "Only prediction and eval context don't need init_net")
198 init_net._net.op.extend([param.initializer])
199 if context == InstantiationContext.TRAINING:
201 elif context == InstantiationContext.EVAL:
203 elif context == InstantiationContext.CALIBRATION:
208 def add_ops(self, net):
209 raise NotImplementedError
211 def add_eval_ops(self, net):
216 def add_train_ops(self, net):
221 def add_calibration_ops(self, net):
def add_train_ops(self, net)
def add_eval_ops(self, net)
def get_fp16_compatible_parameters(self)
def NameScope(prefix, reset=False)
def equal_schemas(schema, original_schema)
def Map(keys, values, keys_name='keys', values_name='values', lengths_blob=None)
def __init__(self, model, prefix, input_record, predict_input_record_fields=None, tags=None, kwargs)
def is_schema_subset(schema, original_schema)
def add_calibration_ops(self, net)
def _check_output_schema(self)