Pytorch加载txt格式的数据集文件(以PTB数据集为例)

前言

这篇博客以PTB数据集为例,详细讲解了如何将txt格式的数据集文件,转换为pytorch框架可以直接处理的tensor变量,并附上相应代码


1. PTB 数据集

PTB数据集含有三个txt文件,分别作为训练集(train),验证集(valid)和测试集(test);这三个txt文件分别包含42000,3000和3000句英文;
我们要将其转化为pytorch可处理的tensor类型数据集,需要以下几步:

  • 依次读取每一行的训练集文件(train.txt),为每一个读到的单词分配序号,构建词汇表
    • 出现频率低于min_ooc(通常默认为3)次的词汇,单词一率变为未知单词 < unk > ,分配序号1
    • < sos >为每句话的起始信号,分配序号2
    • < eos >为每句话的结束信号,分配序号3
    • 由于每句话长度不一样,而pytorch批处理数据,需要统一句子长度,因此长度较短的句子用 < pad > 填充,分配序号0
  • 统一句子长度为max_sentence_length(默认50)
    • 高于50个单词的句子,只保留前50个单词;
    • 低于50个单词的句子,用 < pad > 信号填充到50
  • 根据训练集构建的词汇表,将训练集,验证集和测试集都变成数字序号表示的句子,如 a cat not is dog变成 2 25 54 12 0 0
  • 构建三个数据集加载转换后的用数字序号表示的句子,并将其错位句子作为该句子的标签(target),例如, a cat not is dog变成 2 25 54 12 0 0, 那它对应的target就是 25 54 12 3 0 0 了 (2 3 分别为起始,末尾信号)
  • 将其转换为批处理的tensor变量

这样我们就能得到pytorch可以直接加载处理的tensor类型数据集了

2. 构建词汇表

我们先定义一个字典类型的变量,该字典类型变量,会将输入的句子里的新单词添加到字典中,并记录该单词的出现次数
引入库文件:

import json
import torch
import numpy as np
from nltk.tokenize import TweetTokenizer
from collections import Counter, OrderedDict,defaultdict
import io
import os
from torch.utils.data import DataLoader
class OrderedCounter(Counter, OrderedDict): #这样定义的字典类型变量,会将输入的句子里的新单词添加到字典中,并记录该单词的出现次数
    """Counter that remembers the order elements are first encountered"""
    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

    def __reduce__(self):
        return self.__class__, (OrderedDict(self),)

依次读入ptb.train.txt的每一句话,并对其进行分词,不区分大小写;

  • 分词:由于默认可以通过空格来分开每个单词,但专业的分词函数更好些
def create_vocab(split):
    tokenizer = TweetTokenizer(preserve_case=False) #分词,不区分大小写
    w2c = OrderedCounter()          
    w2i = dict()
    i2w = dict()
    special_tokens = ['<pad>', '<unk>', '<sos>', '<eos>']
    for st in special_tokens:
        i2w[len(w2i)] = st
        w2i[st] = len(w2i)
    with open(split, 'r') as file:
        for i, line in enumerate(file):
            words = tokenizer.tokenize(line)
            w2c.update(words)                     #这段程序将文件中出现过的所有单词加载到字典类型变量w2c中,并存储了他们出现的次数
        for w, c in w2c.items():
            if c > 3 and w not in special_tokens: #依次为出现次数大于3,且不是那4种特殊信号的单词分配序号
                i2w[len(w2i)] = w                
                w2i[w] = len(w2i)                #w2i格式为'cat':50这种,i2w为50:'cat'这种
    return w2i,i2w

实例化一下试试:
词汇表

3. 将训练集,验证集和测试集根据词汇表转换为数字序号,并转换为tensor

def create_data(split,w2i): #split为待转换的txt文件地址
    tokenizer = TweetTokenizer(preserve_case=False) #分词,不区分大小写
    data = defaultdict(dict)
    with open(split, 'r') as file:    #读取该文件的每一行
        for i, line in enumerate(file):
            words = tokenizer.tokenize(line) #分词
            input = ['<sos>'] + words    #输入的开头增加<sos>信号
            input = input[:50]           #只保留前50个(起始信号<sos> + 文本的前49个单词)
            target = words[:50-1]        #输入对应的target,也只保留50个(取文本的前49个单词+ 结束信号<eos>)
            target = target + ['<eos>']
            length = len(input)
            input.extend(['<pad>'] * (50-length))     #输入和target,不足50个的,用<pad>补足50个
            target.extend(['<pad>'] * (50-length))
            input = [w2i.get(w, w2i['<unk>']) for w in input]
            target = [w2i.get(w, w2i['<unk>']) for w in target]
            id = len(data)                            #id表示该数据集的第id句话
            inpu_t = torch.from_numpy(np.asarray(input))              #转换为tensor形式
            targe_t = torch.from_numpy(np.asarray(target))
            data[id]['input'] = inpu_t
            data[id]['target'] = targe_t
            data[id]['length'] = length
    return data

实例化一下试试:
ptb

3. 转换为批处理的tensor变量

data_loader = DataLoader(
                dataset= data,
                batch_size= 64,#批处理大小
                shuffle=True #是否打乱排序
            )

实例化试试:
批处理

总结

这篇博客以PTB数据集为例,介绍了如何将txt形式的数据集转换为pytorch框架中可以使用的,批处理的tensor形式
(评论区留邮箱发PTB数据集)
参考项目:github上以PTB数据集训练的一个语言模型的项目

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值