3 from __future__
import absolute_import
4 from __future__
import division
5 from __future__
import print_function
6 from __future__
import unicode_literals
17 def __init__(self, model, input_record, input_specs,
18 name=
'feature_sparse_to_dense', **kwargs):
20 `input_specs` follows the format of FeatureSpec from schema. To be more 21 precise it's a namedtuple that should have: 22 'feature_type', 'feature_names', 'feature_ids' 24 super(FeatureSparseToDense, self).
__init__(model, name,
25 input_record, **kwargs)
31 assert len(feature_specs.feature_names) ==\
32 len(feature_specs.feature_ids)
33 if feature_specs.feature_type ==
'FLOAT':
37 (np.float32, (len(feature_specs.feature_ids), )),
38 self.get_next_blob_reference(field +
'_output')
41 elif feature_specs.feature_type ==
'ID_LIST':
49 (len(feature_specs.feature_ids), 2)
51 self.get_next_blob_reference(
57 self.get_next_blob_reference(
63 elif feature_specs.feature_type ==
'ID_SCORE_LIST':
71 (len(feature_specs.feature_ids), 2)
73 self.get_next_blob_reference(
79 self.get_next_blob_reference(
85 self.get_next_blob_reference(
91 elif feature_specs.feature_type ==
'EMBEDDING':
102 (len(feature_specs.feature_ids), 2)
104 self.get_next_blob_reference(
110 self.get_next_blob_reference(
118 "Unsupported input type: {0}".
119 format(feature_specs.feature_type))
134 for field, feature_specs
in input_specs:
135 schema.attach_metadata_to_scalars(
138 feature_specs=feature_specs)
140 self.
zero = model.global_constants[
'ZERO']
141 self.
zero_range = model.global_constants[
'ZERO_RANGE']
144 def add_ops(self, net):
145 record = self.input_record
147 if feature_specs.feature_type ==
'FLOAT':
148 net.SparseToDenseMask(
150 record[field].keys(),
151 record[field].values(),
153 record[field].lengths(),
158 mask=feature_specs.feature_ids,
160 elif feature_specs.feature_type ==
'ID_LIST':
161 id_list_ranges = net.LengthsToRanges(
162 record[field].values.lengths(),
163 net.NextScopedBlob(
'id_list_ranges')
165 net.SparseToDenseMask(
167 record[field].keys(), id_list_ranges, self.
zero_range,
168 record[field].lengths()
171 mask=feature_specs.feature_ids,
178 net.Alias(record[field].values.items(),
180 elif feature_specs.feature_type ==
'ID_SCORE_LIST':
182 id_list_ranges = net.LengthsToRanges(
183 record[field].values.lengths(),
184 net.NextScopedBlob(
'id_score_list_ranges')
186 net.SparseToDenseMask(
188 record[field].keys(), id_list_ranges, self.
zero_range,
189 record[field].lengths()
192 mask=feature_specs.feature_ids,
199 net.Alias(record[field].values.keys(),
201 net.Alias(record[field].values.values(),
203 elif feature_specs.feature_type ==
'EMBEDDING':
204 ranges = net.LengthsToRanges(
205 record[field].values.lengths(),
206 net.NextScopedBlob(
'embeddings_ranges')
208 net.SparseToDenseMask(
210 record[field].keys(),
213 record[field].lengths()
216 mask=feature_specs.feature_ids,
223 net.Alias(record[field].values.items(),
226 def get_metadata(self):
232 'type': feature_specs.feature_type,
233 'names': feature_specs.feature_names,
234 'ids': feature_specs.feature_ids,
240 if feature_specs.feature_type ==
'FLOAT':
241 metadata[-1][0][
'cardinality'] = 1
def __init__(self, model, input_record, input_specs, name='feature_sparse_to_dense', kwargs)