Source code for easy_rec.python.layers.seq_input_layer

# -*- encoding: utf-8 -*-
# Copyright (c) Alibaba, Inc. and its affiliates.

import logging

import tensorflow as tf

from easy_rec.python.compat.feature_column import feature_column
from easy_rec.python.feature_column.feature_column import FeatureColumnParser
from easy_rec.python.protos.feature_config_pb2 import WideOrDeep

if tf.__version__ >= '2.0':
  tf = tf.compat.v1


[docs]class SeqInputLayer(object):
[docs] def __init__(self, feature_configs, feature_groups_config, use_embedding_variable=False): self._feature_groups_config = { x.group_name: x for x in feature_groups_config } wide_and_deep_dict = self.get_wide_deep_dict() self._fc_parser = FeatureColumnParser( feature_configs, wide_and_deep_dict, use_embedding_variable=use_embedding_variable)
def __call__(self, features, group_name, feature_name_to_output_tensors={}, allow_key_search=True): feature_column_dict = self._fc_parser.deep_columns feature_column_dict.update(self._fc_parser.sequence_columns) builder = feature_column._LazyBuilder(features) feature_dict = self._feature_groups_config[group_name] tf_summary = feature_dict.tf_summary if tf_summary: logging.info('Write sequence feature to tensorflow summary.') def _seq_embed_summary_name(input_name): input_name = input_name.split(':')[0] input_name = input_name.split('/')[:2] return 'sequence_feature/' + '/'.join(input_name) with tf.variable_scope(group_name, reuse=tf.AUTO_REUSE): key_tensors = [] hist_tensors = [] for x in feature_dict.seq_att_map: for key in x.key: if key not in feature_name_to_output_tensors or ( feature_name_to_output_tensors[key] is None and allow_key_search): qfc = feature_column_dict[key] with tf.variable_scope(qfc._var_scope_name): key_tensors.append( feature_column_dict[key]._get_dense_tensor(builder)) elif feature_name_to_output_tensors[key] is None: assert feature_name_to_output_tensors[ key] is not None, 'When allow_key_search is False, key: %s should defined in same feature group.' % key else: key_tensors.append(feature_name_to_output_tensors[key]) if tf_summary: for key_tensor in key_tensors: tf.summary.histogram( _seq_embed_summary_name(key_tensor.name), key_tensor) for hist_seq in x.hist_seq: seq_fc = feature_column_dict[hist_seq] with tf.variable_scope(seq_fc._var_scope_name): hist_tensors.append( feature_column_dict[hist_seq]._get_sequence_dense_tensor( builder)) if tf_summary: for hist_embed, hist_seq_len in hist_tensors: tf.summary.histogram( _seq_embed_summary_name(hist_embed.name), hist_embed) tf.summary.histogram( _seq_embed_summary_name(hist_seq_len.name), hist_seq_len) features = { 'key': tf.concat(key_tensors, axis=-1), 'hist_seq_emb': tf.concat([x[0] for x in hist_tensors], axis=-1), 'hist_seq_len': hist_tensors[0][1] } return features
[docs] def get_wide_deep_dict(self): wide_and_deep_dict = {} for group_name_config in self._feature_groups_config.values(): for x in group_name_config.seq_att_map: for key in x.key: wide_and_deep_dict[key] = WideOrDeep.DEEP for hist_seq in x.hist_seq: wide_and_deep_dict[hist_seq] = WideOrDeep.DEEP return wide_and_deep_dict