def generate_by_multiple_models(self,
                                    keywords,
                                    epoch=0,
                                    img_save_path='./result',
                                    model_path='',
                                    name=''):
        pron_dict = PronDict()
        fig = plt.figure()
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            context = '^'
            i = 0
            for j, keyword in enumerate(keywords):
                model_path = model_save_path[j + 1]
                ckpt_state = tf.train.get_checkpoint_state(model_save_path[1])
                module_file = tf.train.latest_checkpoint(model_path)
                '''path = ckpt_state.model_checkpoint_path
                path = path.replace('\\','/')'''
                saver = tf.train.Saver()
                saver.restore(sess, module_file)
                i += 1
                keyword_id, keyword_length = self.get_id_length([keyword] *
                                                                BATCH_SIZE)
                context_id, context_length = self.get_id_length([context] *
                                                                BATCH_SIZE)
                y_id, y_prob, score = sess.run(
                    [
                        self.id_inference_in_sum, self.prob_inference_in_sum,
                        self.score
                    ],
                    feed_dict={
                        self.keyword_id: keyword_id,
                        self.keyword_length: keyword_length,
                        self.context_id: context_id,
                        self.context_length: context_length
                    })
                self.draw(score, 220 + i, fig)
                if i == 2:
                    memo_word = self.char_dict.int2word(y_id[0][4])
                if i == 4:
                    temp = y_prob[4]
                    argmax = -1
                    tempMax = 0
                    for j in range(WORD_DICT_SIZE):
                        word = self.char_dict.int2word(j)
                        if word == '^' or word == '$':
                            continue
                        if pron_dict.co_rhyme(
                                word, memo_word) and y_prob[0][4][j] > tempMax:
                            argmax = j
                            tempMax = y_prob[0][4][j]
                    y_id[0][4] = argmax

                context += ' ' + ' '.join(
                    [self.char_dict.int2word(i) for i in list(y_id[0])])
            plt.savefig(img_save_path + f'/attention_at_epoch{epoch}' + name +
                        '.png')
            return context
    def generate(self,
                 keywords,
                 epoch=0,
                 img_save_path='./result',
                 model_path='',
                 name=''):
        pron_dict = PronDict()  # 读音表
        fig = plt.figure()  # 图表
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())  # 初始化全局变量
            saver = tf.train.Saver()
            saver.restore(sess,
                          tf.train.latest_checkpoint(model_path))  # 加载上次训练的模型
            context = '^'
            i = 0
            for keyword in keywords:
                i += 1
                keyword_id, keyword_length = self.get_id_length([keyword] *
                                                                BATCH_SIZE)
                context_id, context_length = self.get_id_length([context] *
                                                                BATCH_SIZE)
                y_id, y_prob, score = sess.run(
                    [
                        self.id_inference_in_sum, self.prob_inference_in_sum,
                        self.score
                    ],
                    feed_dict={
                        self.keyword_id: keyword_id,
                        self.keyword_length: keyword_length,
                        self.context_id: context_id,
                        self.context_length: context_length
                    })
                self.draw(score, 220 + i, fig)
                if i == 2:
                    memo_word = self.char_dict.int2word(y_id[0][4])
                if i == 4:
                    temp = y_prob[4]
                    argmax = -1
                    tempMax = 0
                    for j in range(WORD_DICT_SIZE):
                        word = self.char_dict.int2word(j)
                        if word == '^' or word == '$':
                            continue
                        if pron_dict.co_rhyme(
                                word, memo_word) and y_prob[0][4][j] > tempMax:
                            argmax = j
                            tempMax = y_prob[0][4][j]
                    y_id[0][4] = argmax

                context += ' ' + ' '.join(
                    [self.char_dict.int2word(i) for i in list(y_id[0])])
            plt.savefig(img_save_path + f'/attention_at_epoch{epoch}' + name +
                        '.png')
            return context
예제 #3
0
def generate(funcutils,generator,keywords):

    assert NUM_OF_SENTENCES == len(keywords)
    pron_dict = PronDict()
    saver = tf.train.Saver()
    context = start_of_sentence()
    with tf.Session() as session:
        flag_trained = generator.initialize_session(session, saver)
        if not flag_trained:
            print("Please train the model first! (./train.py -g)")
            sys.exit(1)
        for keyword in keywords:
            ##为何 [keyword*_batch_size?  keyword_data 都是一样的
            keyword_data, keyword_length = funcutils.fill_np_matrix(
                [keyword] * _BATCH_SIZE)
            context_data, context_length = funcutils.fill_np_matrix(
                [context] * _BATCH_SIZE)
            char = start_of_sentence()
            for _ in range(7):
                # print('char==>', char)
                decoder_input, decoder_input_length = \
                    funcutils.fill_np_matrix([char])
                encoder_feed_dict = {
                    generator.keywords: keyword_data,
                    generator.length_keywords: keyword_length,
                    generator.context: context_data,
                    generator.context_length: context_length,
                    generator.sequence_decoder: decoder_input,
                    generator.length_decoder: decoder_input_length
                }
                if char == start_of_sentence():
                    pass
                else:
                    encoder_feed_dict[generator.initial_decode_state] = state
                # do = session.run([self.decoder_outputs], feed_dict=encoder_feed_dict)
                # print(do)
                # print(do[0].shape)
                probs, state = session.run(
                    [generator.logits, generator.decoder_final_state],
                    feed_dict=encoder_feed_dict)
                prob_list = _gen_prob_list(funcutils,probs, context, pron_dict)
                id_probmax = np.argmax(prob_list, axis=0)
                char = funcutils.char_dict.id2char(id_probmax)
                # prob_sums = np.cumsum(prob_list)
                # rand_val = prob_sums[-1] * random()
                # for i, prob_sum in enumerate(prob_sums):
                #     if rand_val < prob_sum:
                #         char = self.char_dict.int2char(i)
                #         break
                context += char
            context += end_of_sentence()
    return context[1:].split(end_of_sentence())
예제 #4
0
 def generate(self, keywords):
     if NUM_OF_SENTENCES < len(keywords):
         keywords = keywords[:4]
     pron_dict = PronDict()
     context = start_of_sentence()
     with tf.Session() as session:
         self._initialize_session(session)
         if not self.trained:
             print("Please train the model first! (./train.py -g)")
             sys.exit(1)
         for keyword in keywords:
             keyword_data, keyword_length = self._fill_np_matrix(
                 [keyword] * _BATCH_SIZE)
             context_data, context_length = self._fill_np_matrix(
                 [context] * _BATCH_SIZE)
             char = start_of_sentence()
             for _ in range(7):
                 decoder_input, decoder_input_length = \
                         self._fill_np_matrix([char])
                 encoder_feed_dict = {
                     self.keyword: keyword_data,
                     self.keyword_length: keyword_length,
                     self.context: context_data,
                     self.context_length: context_length,
                     self.decoder_inputs: decoder_input,
                     self.decoder_input_length: decoder_input_length
                 }
                 if char == start_of_sentence():
                     pass
                 else:
                     encoder_feed_dict[self.decoder_init_state] = state
                 probs, state = session.run(
                     [self.probs, self.decoder_final_state],
                     feed_dict=encoder_feed_dict)
                 prob_list = self._gen_prob_list(probs, context, pron_dict)
                 prob_sums = np.cumsum(prob_list)
                 rand_val = prob_sums[-1] * random()
                 for i, prob_sum in enumerate(prob_sums):
                     if rand_val < prob_sum:
                         char = self.char_dict.int2char(i)
                         break
                 context += char
             context += end_of_sentence()
     return context[1:].split(end_of_sentence())
    def generate(self, keywords):
        if not tf.train.get_checkpoint_state(save_dir):
            print("Please train the model first! (./train.py -g)")
            sys.exit(1)

        self.checkpoint.restore(self.manager.latest_checkpoint)
        print("Checkpoint is loaded successfully !")
        assert NUM_OF_SENTENCES == len(keywords)
        context = start_of_sentence()
        pron_dict = PronDict()
        for keyword in keywords:
            keyword_data, keyword_length = self._fill_np_matrix([keyword] *
                                                                _BATCH_SIZE)
            context_data, context_length = self._fill_np_matrix([context] *
                                                                _BATCH_SIZE)

            keyword_state, context_output, final_output, final_state, context_state = self.encoder(
                keyword_data, context_data)
            char = start_of_sentence()
            for _ in range(7):
                decoder_input, decoder_input_length = \
                    self._fill_np_matrix([char])
                if char == start_of_sentence():
                    pass
                else:
                    keyword_state = final_state
                probs, final_state, _ = self.decoder(keyword_state,
                                                     context_output,
                                                     decoder_input,
                                                     decoder_input_length,
                                                     final_output, final_state,
                                                     context_state)
                prob_list = self._gen_prob_list(probs, context, pron_dict)
                prob_sums = np.cumsum(prob_list)
                rand_val = prob_sums[-1] * random()
                for i, prob_sum in enumerate(prob_sums):
                    if rand_val < prob_sum:
                        char = self.char_dict.int2char(i)
                        break
                context += char
            context += end_of_sentence()
        return context[1:].split(end_of_sentence())
    def generate_by_multiple_models(self,
                                    keywords,
                                    epoch=0,
                                    img_save_path='./result',
                                    model_path='',
                                    name=''):  # 区别于generator, 每个句子都有专门对应的model
        pron_dict = PronDict()
        fig = plt.figure()
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            context = '^'
            i = 0
            for j, keyword in enumerate(keywords):
                model_path = model_save_path[j + 1]
                ckpt_state = tf.train.get_checkpoint_state(model_save_path[1])
                module_file = tf.train.latest_checkpoint(model_path)
                '''path = ckpt_state.model_checkpoint_path
                path = path.replace('\\','/')'''
                saver = tf.train.Saver()
                saver.restore(sess, module_file)  # 加载最新模型
                i += 1  # 当前在处理第i句诗
                keyword_id, keyword_length = self.get_id_length(
                    [keyword] * BATCH_SIZE)  #把字转成字典里对应的int, 对齐
                context_id, context_length = self.get_id_length([context] *
                                                                BATCH_SIZE)
                y_id, y_prob, score = sess.run(
                    [
                        self.id_inference_in_sum, self.prob_inference_in_sum,
                        self.score
                    ],
                    feed_dict={
                        self.keyword_id:
                        keyword_id,  # shape: batch_size * 单行关键字
                        self.keyword_length:
                        keyword_length,  # shape: batch_size
                        self.context_id: context_id,
                        self.context_length: context_length
                    })  # y_id为字对应的字典号, y_prob每个位置每个字出现的概率, score
                self.draw(score, 220 + i, fig)  # 可视化工作
                if i == 2:
                    memo_word = self.char_dict.int2word(y_id[0][4])  # 记下颔联的末字
                if i == 4:
                    temp = y_prob[4]
                    argmax = -1
                    tempMax = 0
                    for j in range(WORD_DICT_SIZE):
                        word = self.char_dict.int2word(j)
                        if word == '^' or word == '$':
                            continue
                        if pron_dict.co_rhyme(
                                word, memo_word
                        ) and y_prob[0][4][j] > tempMax:  # 强制押韵
                            argmax = j
                            tempMax = y_prob[0][4][j]
                    y_id[0][4] = argmax

                context += ' ' + ' '.join(
                    [self.char_dict.int2word(i)
                     for i in list(y_id[0])])  # 上下文以用空格隔开的文字表示
            plt.savefig(img_save_path + f'/attention_at_epoch{epoch}' + name +
                        '.png')
            return context
예제 #7
0
    def generate(self, keywords):
        assert NUM_OF_SENTENCES + 1 == len(keywords)
        pron_dict = PronDict()
        context = start_of_sentence()
        with tf.Session() as session:
            self._initialize_session(session)
            if not self.trained:
                print("Please train the model first! (./train.py -g)")
                sys.exit(1)
            # iterate through all keyword, which means iterate through all four sentences

            # provide a random hint to the first sentence to avoid generating the same thing
            hint = keywords.pop(randrange(len(keywords)))

            first_line = True
            for keyword in keywords:
                if first_line:
                    context += hint
                    first_line = False

                keyword_data, keyword_length = self._fill_np_matrix(
                        [keyword] * _BATCH_SIZE)
                context_data, context_length = self._fill_np_matrix(
                        [context] * _BATCH_SIZE)
                char = start_of_sentence()

                word_count = 0
                state = ''
                while word_count < 7:
                    prob_list, state = self._compute_prob_list(char,keyword_data,keyword_length,\
                        context_data,context_length,context,state,session,pron_dict)
                    
                    # randomly sample BEAM_SIZE number of characters and choose the highest probability
                    # generates different poems when given different keywords
                    if word_count == 0:
                        prob_sums = np.cumsum(prob_list)
                        # the array which store the first char

                        char_array = []
                        score_array = []
                        for i in range(BEAM_SIZE):
                            char_array.append('')
                            score_array.append(1)

                        for i in range(BEAM_SIZE):
                            rand_val = prob_sums[-1] * random()
                            for j, prob_sum in enumerate(prob_sums):
                                if rand_val < prob_sum:
                                    char_array[i] = self.char_dict.int2char(j)
                                    score_array[i] *= -math.log(prob_list[j])
                                    break
                        # because we took the negative log we need the minimum prob
                        min_value = 1000
                        min_index = 0
                        for k in range(len(score_array)):
                            if score_array[k] < min_value:
                                min_index = k
                                min_value = score_array[k]
                        char = char_array[min_index]
                        
                        # generates the same poem for the same keywords
                        '''
                        max_value = prob_list[0]
                        max_index = 0
                        for k in range(len(prob_list)):
                            if prob_list[k] > max_value:
                                max_index = k
                                max_value = prob_list[k]
                        char = self.char_dict.int2char(max_index)
                        '''
                        context += char
                        word_count += 1
                        # end of first word

                    else:
                        # perform beam search for two chars
                        char_array = []
                        second_char_array = []
                        score_array = []

                        for i in range(BEAM_SIZE):
                            char_array.append('')
                            second_char_array.append('')
                            score_array.append(1)
                        
                        max = 0

                        # choose the BEAM_SIZE most possible choices
                        for i in range(BEAM_SIZE):
                            char_array[i], score, used_index = self._return_n_most_likely(prob_list,i+1)
                            score_array[i] *= score
                            # make sure that the same thing is not selected again
                            prob_list[used_index] = 0


                        # choose the most possible choice based on the current choice
                        for i in range(BEAM_SIZE):
                            current_context = context + char_array[i]
                            prob_list, state = self._compute_prob_list(char_array[i],keyword_data,keyword_length,\
                                context_data,context_length,current_context,state,session,pron_dict)
                            second_char_array[i], score, used_index = self._return_n_most_likely(prob_list,1)
                            # randomly sample second array and make sure it does not repeat
                            # random_sample = second_char_array[randrange(len(second_char_array))]
                            random_sample = second_char_array[i]
                            used_chars = set(ch for ch in context)

                            tmp = 2

                            while(random_sample == char_array[i] or random_sample in used_chars):
                                second_char_array[i], score, used_index = self._return_n_most_likely(prob_list,tmp)
                                random_sample = second_char_array[i]
                                tmp += 1
                            score_array[i] *= score

                        # because we took the negative log the minimum score is the best
                        min_value = 1000
                        min_index = 0
                        for i in range(len(score_array)):
                            if score_array[i] < min_value:
                                min_index = i
                                min_value = score_array[i]
                        
                        # adjust so that we prevent using the same character again and again
                        used_chars = set(ch for ch in context)
                        first_char = char_array[min_index]
                        in_loop = 0
                        
                        while first_char in used_chars and in_loop < len(char_array):
                            score_array[min_index] = 1000
                            min_value = 1000
                            for i in range(len(score_array)):
                                # find the minimum in the remaining
                                if score_array[i] < min_value:
                                    min_index = i
                                    min_value = score_array[i]
                            first_char = char_array[min_index]
                            in_loop += 1

                        first_char = char_array[min_index]
                        second_char = second_char_array[min_index]

                        context += first_char
                        context += second_char
                        char = second_char
                        word_count += 2
                # append the <END> label
                context += end_of_sentence()
            # remove the extra hint
            context = context[0] + context[len(hint) + 1:]
        return context[1:].split(end_of_sentence())