Пример #1
0
def playGreedySearch(numTrials, depth):
    with open("output", "a") as output:
        output.write("running " + str(numTrials) + " greedy search games with depth " + str(depth) + "\n")
        tile = DataGroup()
        score = DataGroup()
        
        for x in range(0, numTrials):
            solver = GreedySearch(depth)
            solver.playGame()
            recordData(solver, tile, score)
            solver = None
        
        printRunData(tile, score, output)
    pass
def objectiveFunc(x, *args):
    # do 10 runs
    # average the results
    # return 100 / avg (function is minimizing, we want max)
    allScores = 0

    setWeights(x)

    for i in range(numTrialsPerCall):
        solver = GreedySearch(searchDepth)
        solver.playGame()
        allScores += solver.getScore()

    scoreAvg = allScores / numTrialsPerCall

    if scoreAvg == 0:
        return [np.float(100)]

    return [np.float(100 / scoreAvg)]
    def generate(self):
        temp_cost = 0
        temp_route = []

        # GREEDY SOLUTION
        if self.__gen_type == Type.Greedy:
            greedy = GreedySearch(self.__file)
            temp_cost, temp_route = greedy.calculate()

        elif self.__gen_type == Type.GreedyOne:
            greedy = GreedySearch(self.__file)
            temp_cost, temp_route = greedy.calculate_one(
                random.randrange(self.__data.__len__()))

        # RANDOM SOLUTION
        elif self.__gen_type == Type.Random:
            cities = list(range(self.__data.__len__()))
            first_index = random.randrange(self.__data.__len__())
            temp_route.append(cities.pop(first_index))
            while cities:
                index = random.randrange(cities.__len__())
                temp_route.append(cities.pop(index))
            temp_route.append(temp_route[0])
            for i in range(1, temp_route.__len__()):
                temp_cost += self.__data[temp_route[i - 1]][temp_route[i]]

        return [temp_route, round(temp_cost, 2)]
Пример #4
0
    def forward(self,source,source_lens,target,keywords,keywords_len,teacher_forcing_ratio=0.5):
        '''
        :param source: [batch_size,max_time_step]
        :param source_lens: [batch_size]
        :param target: [batch_size,max_time_step]
        :param keywords: [batch_size,max_words_num,max_word_len],关键词序列
        :param keywords_len: [batch_size],每条数据真实的关键词个数
        :param teacher_forcing_ratio: 使用TeacherForcing训练的数据比例
        :return:outputs: [target_len,batch_size,vocab_size] # 各个时刻的解码结果,保持概率分布的形式
        '''
        target_len = target.size(1) # target的序列长度
        batch_size = target.size(0) # 当前批次大小
        max_time_step = source.size(1)  # 输入序列source的最大长度
        max_words_num = keywords.size(1) # 关键词序列中关键词的最大个数

        # Encoder source
        # 输入端各个时刻的字符的wordEmbeddings: [batch_size,max_time_step,embedding_size]
        # 表示输入端文本的句向量documentEmbedding: [batch_size,1,embedding_size]
        wordEmbeddings,documentEmbedding = self.BertEncoder(source)

        # Encoder keywords
        # [batch_size,max_words_num,embedding_size]
        keywordEmbeddings = self.KeywordEncoder(keywords)

        # 将输入序列source中的PAD位的wordEmbedding置为0,关键词序列中的PAD位的wordEmbedding置为0
        for i in range(batch_size):
            # source
            mask = torch.zeros((max_time_step,self.embedding_size),dtype=torch.float32).cuda() # [max_time_step,embedding_size]
            index = torch.arange(source_lens[i]).cuda()
            mask[index] = torch.tensor(1,dtype=torch.float32).cuda()
            wordEmbeddings[i] = wordEmbeddings[i] * mask # [max_time_step,embedding_size]

            # keywords
            mask = torch.zeros((max_words_num,self.embedding_size),dtype=torch.float32).cuda()  # [max_words_num,embedding_size]
            index = torch.arange(keywords_len[i]).cuda()
            mask[index] = torch.tensor(1, dtype=torch.float32).cuda()
            keywordEmbeddings[i] = keywordEmbeddings[i] * mask  # [max_time_step,embedding_size]

        # Encoder target
        # [batch_size,time_step,embedding_size]
        target,_ = self.BertEncoder(target)


        # Decoder
        # 以输出的各单元概率的形式,存储预测序列,便于交叉熵计算
        outputs = torch.zeros((target_len,batch_size,self.output_size),dtype=torch.float32).cuda()
        # 输入解码起始符_GO开始解码,需要给batch中每条数据都输入
        # 用[unused1]表示GO符号,[unused1]:1
        GO_token = torch.tensor([[1]]*batch_size).cuda() # [batch_size,1]
        GO_token,_ = self.BertModel(GO_token)
        # GO_token: [batch_size,1,embedding_size]
        # 将wordEmbeddings,documentEmbedding 与 GO_token拼接在一起,作为Decoder初始时刻的输入
        # [batch_size,(max_time_step-1)+1+1,embedding_size]
        decoder_input = torch.cat((wordEmbeddings,documentEmbedding,GO_token),1)

        # ---------------------------------------   Global Coverage  -----------------------------------------------
        # Coverage vector 覆盖向量,初始为0,用来累加解码过程各个时刻的注意力权重
        # CopyCoverageVector: [batch_size,max_time_step,1],max_time_step表示输入序列最大的长度
        # KeywordCoverageVector: [batch_size,max_words_num,1],max_words_num表示关键词序列中关键词的个数
        CopyCoverageVector = torch.zeros((batch_size,max_time_step,1),dtype=torch.float32).cuda()
        KeywordCoverageVector = torch.zeros((batch_size,max_words_num,1),dtype=torch.float32).cuda()
        # Coverage损失: CopyCoverageLoss+KeywordCoverageLoss
        GlobalCoverageLoss = torch.tensor(0,dtype=torch.float32).cuda()

        # 解码长度为 batch中的序列长度
        for step in range(target_len):
            decoderResult,CopyCoverageVector,KeywordCoverageVector,CoverageLoss = \
                self.Decoder(source,decoder_input,wordEmbeddings,documentEmbedding,keywordEmbeddings,
                             CopyCoverageVector,KeywordCoverageVector,flag=True)
            # 判断当前时刻解码结果的类型,即判断是TransformerDecoder模块、Copy Attention Distribution 模块
            # Keyword Attention Distribution 模块 哪个模块预测的结果,以方便输出对应的ID

            # batch_word_probDistribution: [batch_size,output_size]
            # batch_word_Embedding: [batch_size,1,embedding_size]
            batch_word_probDistribution, batch_word_Embedding = GreedySearch(decoderResult,self.output_size,self.BertModel,
                                                                   keywords,keywordEmbeddings,flag=True)
            outputs[step] = batch_word_probDistribution
            # 如果为True,则TeacherForcing
            TeacherForcing = random.random() < teacher_forcing_ratio # 随机生成[0,1)之间的数
            # target: [batch_size,max_time_step,embedding_size] ,取出下一时刻的一个batch的target
            next_target = target[:,step].unsqueeze(1) # [batch_size,1,embedding_size]
            next_decoder_input = next_target if TeacherForcing else batch_word_Embedding
            # 将当前解码的结果或下一时刻真实的target拼接到Decoder的输入中,作为下一时刻Decoder的输入
            decoder_input = torch.cat((decoder_input,next_decoder_input),1)
            GlobalCoverageLoss += CoverageLoss

        GlobalCoverageLoss = Variable(GlobalCoverageLoss, requires_grad=True).cuda()  # Coverage 损失

        return outputs,GlobalCoverageLoss # [max_time,batch_size,vocab_size],tensor标量
Пример #5
0
    def BatchSample(self,source,source_lens,keywords,keywords_len):
        '''
        批量预测
        :param source: batch输入,[batch,max_time_step]
        :param source_lens: [batch_size]
        :param keywords: [batch_size,max_words_num,max_word_len],关键词序列
        :param keywords_len: [batch_size],每条数据真实的关键词个数
        :return: 返回预测结果
        '''
        batch_size = source.size(0)  # 当前批次大小
        max_time_step = source.size(1)  # 输入序列source的最大长度
        max_words_num = keywords.size(1)  # 关键词序列中关键词的最大个数
        # Encoder source
        # 输入端各个时刻的字符的wordEmbeddings: [batch_size,max_time_step-1,embedding_size],去除了[CLS]的Embedding
        # 表示输入端文本的句向量: [batch_size,1,embedding_size]
        wordEmbeddings, documentEmbedding = self.BertEncoder(source)

        # Encoder keywords
        # [batch_size,max_words_num,embedding_size]
        keywordEmbeddings = self.KeywordEncoder(keywords)

        # 将输入序列source中的PAD位的wordEmbedding置为0,关键词序列中的PAD位的wordEmbedding置为0
        for i in range(batch_size):
            # source
            mask = torch.zeros((max_time_step,self.embedding_size),dtype=torch.float32).cuda()  # [max_time_step,embedding_size]
            index = torch.arange(source_lens[i]).cuda()
            mask[index] = torch.tensor(1,dtype=torch.float32).cuda()
            wordEmbeddings[i] = wordEmbeddings[i] * mask  # [max_time_step,embedding_size]

            # keywords
            mask = torch.zeros((max_words_num,self.embedding_size),dtype=torch.float32).cuda()  # [max_words_num,embedding_size]
            index = torch.arange(keywords_len[i]).cuda()
            mask[index] = torch.tensor(1,dtype=torch.float32).cuda()
            keywordEmbeddings[i] = keywordEmbeddings[i] * mask  # [max_time_step,embedding_size]

        # Decoder
        # 记录batch中,每条数据的各个时刻的预测结果,解码的最大长度为self.MAX_LENGTH
        results = []
        # 输入解码起始符_GO开始解码
        GO_token = torch.tensor([[1]]).cuda() # 用[unused1]表示GO,其在词典中索引为1
        GO_token, _ = self.BertModel(GO_token) # [1,1,embedding_size]
        # 解码终止符
        EOS_token = torch.tensor(2).cuda() # 用[unused2]表示EOS,其在词典中索引为2
        # 填充符
        PAD_token = torch.tensor(0).cuda() # [PAD]


        # 逐一对batch中的各条数据解码
        for i in range(batch_size):
            # 当前输入序列
            current_source = source[i].unsqueeze(0)
            # 存储当前序列的解码结果
            result = []
            # 当前序列bert编码后的结果
            wordEmbedding = wordEmbeddings[i].unsqueeze(0) # [1,max_time_step-1,embedding_size]
            document = documentEmbedding[i].unsqueeze(0) # [1,1,embedding_size]
            # 当前序列关键词bert编码后的结果
            keywordEmbedding = keywordEmbeddings[i].unsqueeze(0) # [1,max_words_num,embedding_size]
            # 当前序列的关键词序列
            current_keyword = keywords[i].unsqueeze(0)  # [1,max_words_num,max_word_len]
            # 解码起始符
            decoder_input = torch.cat((wordEmbedding,document,GO_token),1) # [1,some_time,embedding_size]

            # ---------------------------------------   Global Coverage  -----------------------------------------------
            # Coverage vector 覆盖向量,初始为0,用来累加解码过程各个时刻的注意力权重
            # CopyCoverageVector: [1,max_time_step,1],max_time_step表示输入序列最大的长度
            # KeywordCoverageVector: [1,max_words_num,1],max_words_num表示关键词序列中关键词的个数
            CopyCoverageVector = torch.zeros((1, max_time_step, 1),dtype=torch.float32).cuda()
            KeywordCoverageVector = torch.zeros((1, max_words_num, 1),dtype=torch.float32).cuda()

            for j in range(self.MAX_LENGTH):
                decoderResult,CopyCoverageVector,KeywordCoverageVector,_ = \
                    self.Decoder(current_source,decoder_input,wordEmbedding,document,keywordEmbedding,
                                 CopyCoverageVector,KeywordCoverageVector,flag=False)

                # 判断当前时刻解码结果的类型,即判断是TransformerDecoder模块、Copy Attention Distribution 模块
                # Keyword Attention Distribution 模块 哪个模块预测的结果,以方便输出对应的ID

                # batch_word_ID: [1,max_word_len]
                # batch_word_Embedding: [1,1,embedding_size]
                batch_word_ID,batch_word_Embedding = GreedySearch(decoderResult,self.output_size,self.BertModel,
                                                                                 current_keyword, keywordEmbeddings, flag=False)
                # 将当前解码的结果拼接到Decoder的输入中,作为下一时刻Decoder的输入
                decoder_input = torch.cat((decoder_input,batch_word_Embedding),1)

                # 去除batch_word_ID中的PAD
                wordID = torch.tensor([id for id in batch_word_ID[0] if id != PAD_token]).cuda()
                result.extend(wordID.tolist())
                if len(wordID) == 1:
                    if wordID[0] == EOS_token:
                        break
            results.append(result)
        return results # [batch_size,some_time_step]