(self, bst_fea, seq_size, head_count, name)
| 193 | return att_res_net |
| 194 | |
| 195 | def _bst_tower(self, bst_fea, seq_size, head_count, name): |
| 196 | cur_id, hist_id_col, seq_len = bst_fea['key'], bst_fea[ |
| 197 | 'hist_seq_emb'], bst_fea['hist_seq_len'] |
| 198 | cur_batch_max_seq_len = tf.shape(hist_id_col)[1] |
| 199 | # seq_size: max length |
| 200 | # seq_len: a [B] vector to represent the length of history col |
| 201 | # cur_batch_max_seq_len: the max length of seq_len |
| 202 | # sequence padding/slice in the dimension of sequence_size |
| 203 | # hist_id_col: (batch_size, max_sequence_size, embedding_size) |
| 204 | hist_id_col = tf.cond( |
| 205 | tf.constant(seq_size) > cur_batch_max_seq_len, |
| 206 | lambda: tf.pad(hist_id_col, |
| 207 | [[0, 0], [0, seq_size - cur_batch_max_seq_len - 1], |
| 208 | [0, 0]], 'CONSTANT'), |
| 209 | lambda: tf.slice(hist_id_col, [0, 0, 0], [-1, seq_size - 1, -1])) |
| 210 | # expand to same shape |
| 211 | # (batch_size, seq_size, emb_dim) |
| 212 | all_ids = tf.concat([hist_id_col, tf.expand_dims(cur_id, 1)], axis=1) |
| 213 | emb_dim = int(all_ids.shape[2]) |
| 214 | |
| 215 | attention_net = self._multihead_attention(all_ids, head_count, emb_dim, |
| 216 | seq_len, seq_size) |
| 217 | tmp_net = self._add_and_norm(all_ids, |
| 218 | attention_net, |
| 219 | emb_dim, |
| 220 | name='add_and_norm_1') |
| 221 | feed_forward_net_1 = tf.layers.dense(tmp_net, |
| 222 | units=emb_dim, |
| 223 | activation=tf.nn.relu, |
| 224 | name='feed_forward_net_1') |
| 225 | feed_forward_net = tf.layers.dense(feed_forward_net_1, |
| 226 | units=emb_dim, |
| 227 | activation=None, |
| 228 | name='feed_forward_net_2') |
| 229 | net = self._add_and_norm(tmp_net, |
| 230 | feed_forward_net, |
| 231 | emb_dim, |
| 232 | name='add_and_norm_2') |
| 233 | bst_output = tf.reshape(net, [-1, seq_size * emb_dim]) |
| 234 | return bst_output |
| 235 | |
| 236 | # create model |
| 237 | def _create_model(self): |
no test coverage detected