build_index.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import numpy as np
  2. from caffe2.python import core, schema
  3. from caffe2.python.layers.layers import ModelLayer
  4. class MapToRange(ModelLayer):
  5. """
  6. This layer aims to build a mapping from raw keys to indices within [0, max_index).
  7. The mapping is continuously built during training. The mapping will be frozen during
  8. evaluation and prediction. Unseen keys will be assigned to index 0.
  9. """
  10. def __init__(
  11. self, model,
  12. input_record,
  13. max_index,
  14. name='map_to_range',
  15. **kwargs
  16. ):
  17. super(MapToRange, self).__init__(model, name, input_record, **kwargs)
  18. assert max_index > 0
  19. assert isinstance(input_record, schema.Scalar)
  20. self.max_index = max_index
  21. self.handler = self.create_param(
  22. param_name='handler',
  23. shape=[],
  24. initializer=('LongIndexCreate', {'max_elements': self.max_index}),
  25. optimizer=model.NoOptim
  26. )
  27. self.output_schema = schema.Struct(
  28. ('indices', schema.Scalar(
  29. np.int64, self.get_next_blob_reference("indices")
  30. )),
  31. ('handler', schema.Scalar(
  32. np.void, self.handler
  33. )),
  34. )
  35. def add_train_ops(self, net):
  36. if self.input_record.field_type().base != np.int64:
  37. keys = net.Cast(
  38. self.input_record(),
  39. net.NextScopedBlob("indices_before_mapping"),
  40. to=core.DataType.INT64
  41. )
  42. else:
  43. keys = self.input_record()
  44. # Load keys into indices
  45. indices = net.IndexGet([self.handler, keys],
  46. self.output_schema.indices())
  47. net.StopGradient(indices, indices)
  48. def add_eval_ops(self, net):
  49. net.IndexFreeze(self.handler, self.handler)
  50. self.add_train_ops(net)
  51. def add_ops(self, net):
  52. self.add_eval_ops(net)