예제 #1
0
    def sampling(self, inputs, sampling_type):
        decode_len = inputs['decode_len']
        user_feature = self.user_encode(inputs)
        item_embedding = self._build_embeddings(inputs, self.item_slot_names)
        item_fc = self.item_fc_op(item_embedding)
        pos = fluid_sequence_get_pos(item_fc)
        pos_embed = self.dict_data_embed_op['pos'](pos)

        if self._candidate_encode:
            cand_encoding = self.candidate_encode(item_fc)
            init_hidden = self.candidate_encode_fc_op(
                layers.concat([user_feature, cand_encoding], 1))
        else:
            init_hidden = user_feature
        eps = inputs['eps'] if sampling_type == 'eps_greedy' else None
        eta = inputs['eta'] if sampling_type == 'softmax' else None
        sampled_id = self.sampling_rnn(item_fc,
                                       h_0=init_hidden,
                                       pos_embed=pos_embed,
                                       forward_func=self.sampling_rnn_forward,
                                       sampling_type=sampling_type,
                                       eps=eps,
                                       eta=eta)
        sampled_id = self._cut_by_decode_len(
            layers.lod_reset(sampled_id, item_fc), decode_len)
        return sampled_id
예제 #2
0
    def forward(self, inputs, mode):
        """
        don't use sequence_expand for backward
        """
        is_test = True if (mode in ['test', 'inference']) else False

        # encode
        user_embedding = self._build_embeddings(inputs, self.user_slot_names)
        user_feature = self.user_feature_fc_op(user_embedding)

        # item embed and pos embed
        item_embedding = self._build_embeddings(inputs, self.item_slot_names)
        item_fc = self.item_fc_op(item_embedding)
        pos = fluid_sequence_get_pos(item_fc)
        pos_embed = self.dict_data_embed_op['pos'](pos)
        input_embed = layers.concat([
            item_fc, pos_embed,
            layers.sequence_expand_as(user_feature, item_fc)
        ], 1)

        # transformer
        trans_in = self.input_embed_fc_op(input_embed)
        decoding = self.transformer_decode(is_test, trans_in)
        click_prob = self.output_fc2_op(self.output_fc1_op(decoding))
        return click_prob
예제 #3
0
    def dynamic_rnn(self, item_fc, h_0, output_type=None, double_type=None, double_id=None):
        drnn = fluid.layers.DynamicRNN()
        pos = fluid_sequence_get_pos(item_fc)
        with drnn.block():
            cur_item_fc = drnn.step_input(item_fc)
            cur_h_0 = drnn.memory(init=h_0, need_reorder=True)

            cur_item_fc = layers.lod_reset(cur_item_fc, cur_h_0)
            next_h_0 = self.simple_step_rnn(cur_item_fc, h_0=cur_h_0)

            if output_type == 'c_Q':
                Q = self.out_Q_fc2_op(self.out_Q_fc1_op(next_h_0))
                drnn.output(Q)

            elif output_type in ['max_Q', 'double_Q']:
                # batch_size = 2
                # item_fc: lod = [0,4,7]
                # cur_h_0: lod = [0,1,2]
                item_fc = drnn.static_input(item_fc)
                pos = drnn.static_input(pos)
                cur_step = drnn.memory(shape=[1], dtype='int64', value=0)

                expand_h_0 = layers.sequence_expand(cur_h_0, item_fc)               # lod = [0,1,2,3,4,5,6,7]
                new_item_fc = layers.lod_reset(item_fc, expand_h_0)                 # lod = [0,1,2,3,4,5,6,7]
                next_expand_h_0 = self.simple_step_rnn(new_item_fc, expand_h_0)     # lod = [0,1,2,3,4,5,6,7]
                next_expand_h_0 = layers.lod_reset(next_expand_h_0, item_fc)        # lod = [0,4,7]

                expand_Q = self.out_Q_fc2_op(self.out_Q_fc1_op(next_expand_h_0))
                cur_step_id = layers.slice(cur_step, axes=[0, 1], starts=[0, 0], ends=[1, 1])
                mask = layers.cast(pos >= cur_step_id, 'float32')
                expand_Q = expand_Q * mask

                if output_type == 'max_Q':
                    max_Q = layers.sequence_pool(expand_Q, 'max')                       # lod = [0,1,2]
                    drnn.output(max_Q)
                elif output_type == 'double_Q':
                    if double_type == 'max_id':
                        max_id = self.eps_greedy_sampling(expand_Q, mask, eps=0)
                        drnn.output(max_id)
                    elif double_type == 'double_Q':
                        cur_double_id = drnn.step_input(double_id)

                        double_Q = fluid_sequence_index(expand_Q, cur_double_id)
                        drnn.output(double_Q)

                # update
                next_step = cur_step + 1
                drnn.update_memory(cur_step, next_step)

            elif output_type == 'hidden':
                drnn.output(next_h_0)                

            else:
                raise NotImplementedError(output_type)

            # update
            drnn.update_memory(cur_h_0, next_h_0)

        drnn_output = drnn()
        return drnn_output
예제 #4
0
    def forward(self, inputs):
        """forward"""
        user_feature = self.user_encode(inputs)
        item_embedding = self._build_embeddings(inputs, self.item_slot_names)
        item_fc = self.item_fc_op(item_embedding)
        pos = fluid_sequence_get_pos(item_fc)
        pos_embed = self.dict_data_embed_op['pos'](pos)

        gru_input = self.item_gru_fc_op(layers.concat([item_fc, pos_embed], 1))
        item_gru = self.item_gru_op(gru_input, h_0=user_feature)
        click_prob = self.out_fc2_op(self.out_fc1_op(item_gru))
        return click_prob
예제 #5
0
    def forward(self, inputs):
        """forward"""
        user_feature = self.user_encode(inputs)
        item_embedding = self._build_embeddings(inputs, self.item_slot_names)
        item_fc = self.item_fc_op(item_embedding)
        pos = fluid_sequence_get_pos(item_fc)
        pos_embed = self.dict_data_embed_op['pos'](pos)

        item_concat = layers.concat([
            item_fc, pos_embed,
            layers.sequence_expand_as(user_feature, item_fc)
        ], 1)
        item_concat_fc = self.item_concat_fc_op(item_concat)
        click_prob = self.out_fc2_op(self.out_fc1_op(item_concat_fc))
        return click_prob
예제 #6
0
    def forward(self, inputs, mode):
        """forward"""
        # encode
        user_embedding = self._build_embeddings(inputs, self.user_slot_names)
        user_feature = self.user_feature_fc_op(user_embedding)
        # item embed + pos embed
        item_embedding = self._build_embeddings(inputs, self.item_slot_names)
        item_fc = self.item_fc_op(item_embedding)
        pos = fluid_sequence_get_pos(item_fc)
        pos_embed = self.dict_data_embed_op['pos'](pos)

        # item gru
        gru_input = self.item_gru_fc_op(layers.concat([item_fc, pos_embed], 1))
        item_gru_forward = self.item_gru_forward_op(gru_input,
                                                    h_0=user_feature)
        item_gru_backward = self.item_gru_backward_op(gru_input,
                                                      h_0=user_feature)
        item_gru = layers.concat([item_gru_forward, item_gru_backward], axis=1)
        click_prob = self.out_click_fc2_op(self.out_click_fc1_op(item_gru))
        return click_prob
예제 #7
0
    def forward(self, inputs, output_type):
        """forward"""
        decode_len = inputs['decode_len']
        user_feature = self.user_encode(inputs)
        item_embedding = self._build_embeddings(inputs, self.item_slot_names)
        item_fc = self.item_fc_op(item_embedding)
        atten_item_fc = self.atten_item_fc_op(item_embedding)
        cand_encoding = self.candidate_encode(item_fc)
        pos = fluid_sequence_get_pos(item_fc)
        pos_embed = self.dict_data_embed_op['pos'](pos)

        init_hidden = self.candidate_encode_fc_op(
            layers.concat([user_feature, cand_encoding], 1))
        item_Q = self.train_rnn(item_fc,
                                atten_item_fc,
                                init_hidden,
                                pos,
                                pos_embed,
                                output_type=output_type)
        item_Q = self._cut_by_decode_len(layers.lod_reset(item_Q, item_fc),
                                         decode_len)
        return item_Q