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形式
參考項目:github上以PTB數據集訓練的一個語言模型的項目


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM