def getCompletion_beam(self, stop='</S>', beam_size=100, branching_factor=8): nodes = self.initBeam() for i in range(36): new_nodes = BeamQueue(max_size=beam_size) current_nodes = [] for node in nodes: # print("node.words",node.words) if i > 0 and node.words[ -1] == stop: # don't extend past the stop token new_nodes.Insert(node) # copy over finished beams else: current_nodes.append(node) # these ones will get extended if len(current_nodes) == 0: return new_nodes # all beams have finished # group together all the nodes in the queue for efficient computation prev_hidden = np.vstack( [item.prev_hidden for item in current_nodes]) prev_words = np.array([ self.vocab_char.word_to_idx[item.words[-1]] for item in current_nodes ]) # print("prev_words ",prev_words) print("prev_hidden shape ", prev_hidden.shape, " prev_hidden : ") print("prev_words shape ", prev_words.shape, " prev_words : ", prev_words) # 喂到解码器里 feed_dict = { self.prev_word: prev_words, self.prev_hidden_state: prev_hidden, self.beam_size: branching_factor } current_char, current_char_p, prev_hidden = self.sess.run( [self.beam_chars, self.top_k, self.next_hidden_state], feed_dict) current_char_p = -current_char_p print(current_char[0][1]) print(current_char, current_char.shape) # (1, 4),(4, 4) ==>(?,4) print(current_char_p, current_char_p.shape) # (1, 4),(4, 4)==>(?,4) print(prev_hidden, prev_hidden.shape) # (1,1024),(4, 1024)==>(?,1024) for i, node in enumerate(current_nodes): for new_word, top_value in zip(current_char[i, :], current_char_p[i, :]): new_cost = top_value + node.log_probs if new_nodes.CheckBound( new_cost ): # only create a new object if it fits in beam new_beam = BeamItem(node.words + [new_word], prev_hidden[i, :], log_prob=new_cost) new_nodes.Insert(new_beam) # print("node.words end. ") nodes = new_nodes return nodes
def BeamSearch(expdir): saver.restore(session, os.path.join(expdir, 'model.bin')) context = {'rating': random.choice(['5_stars', '1_stars', '2_stars', '4_stars']), 'subreddit': '5_stars', 'offering': random.choice(['loc_76049', 'loc_1218737', 'loc_77094', 'loc_1776857'])} context = {} settings = GetRandomSetting(None, context, print_it=True) # initalize beam starting_phrase = random.choice([ '<S> the bed was', '<S> the location was', '<S> i stayed here on a business trip and', '<S> our room was', '<S> we could not believe', '<S> when i arrived at the hotel']).split() beam_size = 8 total_beam_size = 200 init_c, init_h = InitBeam(starting_phrase, settings) nodes = [BeamItem(starting_phrase, init_c, init_h)] for i in xrange(80): new_nodes = BeamQueue(max_size=total_beam_size) for node in nodes: if node.words[-1] == '</S>': # don't extend past end-of-sentence token new_nodes.Insert(node) continue feed_dict = { model.prev_word: vocab[node.words[-1]], model.prev_c: node.prev_c, model.prev_h: node.prev_h, model.beam_size: beam_size, } GetRandomSetting(feed_dict, settings, print_it=False) current_word_id, current_word_p, node.prev_c, node.prev_h = session.run( [model.selected, model.selected_p, model.next_c, model.next_h], feed_dict) current_word_p = np.squeeze(current_word_p) if len(current_word_p.shape) == 0: current_word_p = [float(current_word_p)] for top_entry, top_value in zip(current_word_id, current_word_p): new_word = vocab[top_entry] if new_word != '<UNK>' and node.IsEligible(new_word): log_p = -np.log(top_value) # check the bound to see if we can avoid adding this to the queue if new_nodes.CheckBound(log_p + node.Cost()): new_beam = copy.deepcopy(node) new_beam.Update(log_p, vocab[top_entry]) new_nodes.Insert(new_beam) nodes = new_nodes for item in reversed([b for b in nodes][-4:]): print item.Cost(), SEPERATOR.join(item.words)
def initBeam(self): phrase = self.feed_dict[self.querys] # 前缀 prev_hidden = np.zeros((1, 2 * 512)) for word in phrase[:]: feed_dict = { self.prev_hidden_state: prev_hidden, self.prev_word: [self.vocab_char.word_to_idx[word]], self.beam_size: 4 } prev_hidden = self.sess.run(self.next_hidden_state, feed_dict) nodes = [BeamItem(phrase, prev_hidden)] return nodes