| 84 | |
| 85 | |
| 86 | class DeepFM(): |
| 87 | def __init__(self, |
| 88 | wide_column=None, |
| 89 | fm_column=None, |
| 90 | deep_column=None, |
| 91 | dnn_hidden_units=[1024, 256, 32], |
| 92 | final_hidden_units=[128, 64], |
| 93 | optimizer_type='adam', |
| 94 | learning_rate=0.001, |
| 95 | use_bn=True, |
| 96 | bf16=False, |
| 97 | stock_tf=None, |
| 98 | adaptive_emb=False, |
| 99 | input_layer_partitioner=None, |
| 100 | dense_layer_partitioner=None, |
| 101 | strategy=None): |
| 102 | |
| 103 | self._wide_column = wide_column |
| 104 | self._deep_column = deep_column |
| 105 | self._fm_column = fm_column |
| 106 | if not wide_column or not fm_column or not deep_column: |
| 107 | raise ValueError( |
| 108 | 'Wide column, FM column or Deep column is not defined.') |
| 109 | |
| 110 | self.tf = stock_tf |
| 111 | self.bf16 = False if self.tf else bf16 |
| 112 | self.is_training = True |
| 113 | self.use_bn = use_bn |
| 114 | self._adaptive_emb = adaptive_emb |
| 115 | |
| 116 | self._dnn_hidden_units = dnn_hidden_units |
| 117 | self._final_hidden_units = final_hidden_units |
| 118 | self._optimizer_type = optimizer_type |
| 119 | self._learning_rate = learning_rate |
| 120 | self._input_layer_partitioner = input_layer_partitioner |
| 121 | self._dense_layer_partitioner = dense_layer_partitioner |
| 122 | self._strategy = strategy |
| 123 | |
| 124 | # used to add summary in tensorboard |
| 125 | def _add_layer_summary(self, value, tag): |
| 126 | tf.summary.scalar('%s/fraction_of_zero_values' % tag, |
| 127 | tf.nn.zero_fraction(value)) |
| 128 | tf.summary.histogram('%s/activation' % tag, value) |
| 129 | |
| 130 | def _dnn(self, dnn_input, dnn_hidden_units=None, layer_name=''): |
| 131 | for layer_id, num_hidden_units in enumerate(dnn_hidden_units): |
| 132 | with tf.variable_scope(layer_name + '_%d' % layer_id, |
| 133 | partitioner=self._dense_layer_partitioner, |
| 134 | reuse=tf.AUTO_REUSE) as dnn_layer_scope: |
| 135 | dnn_input = tf.layers.dense( |
| 136 | dnn_input, |
| 137 | num_hidden_units, |
| 138 | activation=tf.nn.relu, |
| 139 | name=dnn_layer_scope) |
| 140 | if self.use_bn: |
| 141 | dnn_input = tf.layers.batch_normalization( |
| 142 | dnn_input, training=self.is_training, trainable=True) |
| 143 | # self._add_layer_summary(dnn_input, dnn_layer_scope.name) |