| 106 | |
| 107 | |
| 108 | class DeepFM(): |
| 109 | def __init__(self, |
| 110 | wide_column=None, |
| 111 | fm_column=None, |
| 112 | deep_column=None, |
| 113 | dnn_hidden_units=[1024, 256, 32], |
| 114 | final_hidden_units=[128, 64], |
| 115 | optimizer_type='adam', |
| 116 | learning_rate=0.001, |
| 117 | inputs=None, |
| 118 | use_bn=True, |
| 119 | bf16=False, |
| 120 | input_layer_partitioner=None, |
| 121 | dense_layer_partitioner=None): |
| 122 | if not inputs: |
| 123 | raise ValueError('Dataset is not defined.') |
| 124 | self.wide_column = wide_column |
| 125 | self.deep_column = deep_column |
| 126 | self.fm_column = fm_column |
| 127 | if not wide_column or not fm_column or not deep_column: |
| 128 | raise ValueError( |
| 129 | 'Wide column, FM column or Deep column is not defined.') |
| 130 | self.dnn_hidden_units = dnn_hidden_units |
| 131 | self.final_hidden_units = final_hidden_units |
| 132 | self.optimizer_type = optimizer_type |
| 133 | self.learning_rate = learning_rate |
| 134 | self.input_layer_partitioner = input_layer_partitioner |
| 135 | self.dense_layer_partitioner = dense_layer_partitioner |
| 136 | |
| 137 | self.feature = inputs[0] |
| 138 | self.label = inputs[1] |
| 139 | self.bf16 = bf16 |
| 140 | |
| 141 | self._is_training = True |
| 142 | self.use_bn = use_bn |
| 143 | |
| 144 | self.predict = self.prediction() |
| 145 | with tf.name_scope('head'): |
| 146 | self.train_op, self.loss = self.optimizer() |
| 147 | self.acc, self.acc_op = tf.metrics.accuracy(labels=self.label, |
| 148 | predictions=self.predict) |
| 149 | self.auc, self.auc_op = tf.metrics.auc(labels=self.label, |
| 150 | predictions=self.predict, |
| 151 | num_thresholds=1000) |
| 152 | tf.summary.scalar('eval_acc', self.acc) |
| 153 | tf.summary.scalar('eval_auc', self.auc) |
| 154 | |
| 155 | def dnn(self, dnn_input, dnn_hidden_units=None, layer_name=''): |
| 156 | for layer_id, num_hidden_units in enumerate(dnn_hidden_units): |
| 157 | with tf.variable_scope(layer_name + "_%d" % layer_id, |
| 158 | partitioner=self.dense_layer_partitioner, |
| 159 | reuse=tf.AUTO_REUSE) as dnn_layer_scope: |
| 160 | dnn_input = tf.layers.dense(dnn_input, |
| 161 | units=num_hidden_units, |
| 162 | activation=tf.nn.relu, |
| 163 | name=dnn_layer_scope) |
| 164 | if self.use_bn: |
| 165 | dnn_input = tf.layers.batch_normalization( |