nlp项目实践古诗创作tensorflow ---(2)reader类编写(获得训练数据batch)

之前介绍了数据集,接下来将数据集生成batch的训练数据,并增加一些符号以及转换成数字。

整体介绍

对于输入的中文,想要在模型中体现,必然不可能以汉字的形式呈现,而是使用embedding将这个字对应到一个n维的向量中去,而为了能够较快的完成这个对应任务,需要首先把汉字转换成一个序号,由于使用了别人训练好的embedding,因此也要使用别人的字符序号。
将一句话转换成序号后,还需要做一些“加减法“

  1. 对于同一个batch的数据,根据最长的句子长度做padding。
  2. target句子中要有特殊符号eos表示句子结束
  3. 对于不认识的字(别人的训练集中没有的字)要使用unk符号代替
    在这里插入图片描述
    上图展示了将诗句转化成序号列表的样式(最终输出的没有中文,那一栏是长度,这里是改了程序做示范),比如“妙吟难得”就变为[1264, 988, 320, 60, 0, 0, 0],这是因为这个batch中最大的句子是7个字,因此得到的长度也是7,而它不够长就要pad。而输出句子如’云屏一倍清寒’变成了[19, 1402, 22, 1648, 141, 211, 3]],可以发现长度多了一位,这是由于是target句子,多了一个终止符,终止符的id定义成3。

代码

直接看代码

import pandas as pd
import random
import pickle

def padding_seq(seq):
    results = []
    max_len = 0
    for s in seq:
        if max_len < len(s):
            max_len = len(s)
    for i in range(0, len(seq)):
        l = max_len - len(seq[i])
        results.append(seq[i] + [0 for j in range(l)])
    return results

class reader():
    def __init__(self, input_file, vocab_file, batch_size,memory_file_size=200000,
            end_token = '</s>',
            padding = True, max_len = 50):
        with open("word2int.txt", "rb+") as f:
            self.word2int=pickle.load(f)
        
        self.data_pos = 0
        self.memory_file_size = memory_file_size
        self.df = pd.DataFrame()
        self.input_file =input_file
        self.batch_size = batch_size
        self.padding = True
   
    def readfile(self):
        self.df = pd.read_csv(self.input_file,nrows = self.memory_file_size,sep = "\t",skiprows = random.randint(0,4400000))
       
    def read_single_data(self):
        if self.data_pos%self.memory_file_size==0:
            self.readfile()
            self.data_pos = 0
            
        up_sentence_w = self.df[self.df.columns[0]][self.data_pos]
        do_sentence_w = self.df[self.df.columns[1]][self.data_pos]
        up_sentence =[]
        do_sentence = []
        for word in up_sentence_w:
            if word in self.word2int:
                up_sentence.append(self.word2int[word])
            else:
                up_sentence.append(self.word2int["<unk>"])
        for word in do_sentence_w:
            if word in self.word2int:
                do_sentence.append(self.word2int[word])
            else:
                do_sentence.append(1)
        do_sentence.append(3)
        self.data_pos += 1
        
        return {"in_seq":up_sentence,"in_seq_len":len(up_sentence),"target_seq":do_sentence,"target_seq_len":len(do_sentence)}
        
    def read(self):
        while True:
            batch = {'in_seq': [],
                    'in_seq_len': [],
                    'target_seq': [],
                    'target_seq_len': []}
            
            for i in range(0, self.batch_size):
                item = self.read_single_data()
                batch['in_seq'].append(item['in_seq'])
                batch['in_seq_len'].append(item['in_seq_len'])
                batch['target_seq'].append(item['target_seq'])
                batch['target_seq_len'].append(item['target_seq_len'])
            if self.padding:
                batch['in_seq'] = padding_seq(batch['in_seq'])
                batch['target_seq'] = padding_seq(batch['target_seq'])
            yield batch 

padding_seq()

该函数是为batch中的seq做padding,没有什么难点

read()

可以看出read其实是调用了batch-size次read_single_data,生成了batch-size个数据,read用了yield,这样生成一个生成器,每一次需要新的batch就next()一下

read_single_data()

if self.data_pos%self.memory_file_size==0:
            self.readfile()
            self.data_pos = 0

这一段代码是因为有时候数据集可能过大一次读取太耗内存了,所以每一次读取self.memory_file_size行数据,每次生成一个data后就将data_pos+=1,这样当生成了self.memory_file_size个后,就会调用readfile,随机的再读取self.memory_file_size行数据。

这个函数就是做了生成单个数据的内容。

结果

在这里插入图片描述
输入r=reader(‘part-r-00000’,‘voc.txt’,10),第一个参数是数据集的文件,第二个参数是voc2int的文件,第三个是batch-size,调用next(r.read())得到上图输出,由于数据经过了mapreduce的处理,按照target-seq的长度排序了,因此输出的batch还是比较整齐的。在训练模型时只需要不断next就可以得到新的batch了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值