Pytorch學習記錄-torchtext數(shù)據(jù)預處理

Pytorch學習記錄-torchtext學習Field

重新又看了一遍,這東西還得實際做,具體內(nèi)容看注釋。
等會還會用中文分詞試一下,希望之后文本處理可以使用torchtext做預處理。

和 torchvision 類似 torchtext 是為了處理特定的數(shù)據(jù)和數(shù)據(jù)集而存在的。
正如 NLP和 CV的熱度一樣, torchtext的熱度也較 torchvision 少了許多,至今還在積極開發(fā)中,甚至在使用過程中你可能會遇見一些 bug。但是, torchtext 的可用性是肯定的,它提供了一整套文本數(shù)據(jù)處理流程。

本文使用的數(shù)據(jù)集也是Kaggle的情感分類數(shù)據(jù)集。

import pandas as pd
import numpy as np
import torch
import random
import os
import torchtext
from torchtext import data
from torchtext.vocab import Vectors
from torch.nn import init
from tqdm import tqdm
tokenize=lambda x:x.split()
# sequential數(shù)據(jù)是不是按順序來
# tokenize傳入剛才切分好的數(shù)據(jù)
# lower小寫
# fix_length補齊最大長度
# use_vocab是否使用Vocab對象。如果為False,則此字段中的數(shù)據(jù)應已為數(shù)字。默認值:True。
# 在這里其實就是獲取分詞后的文本和標簽
TEXT=data.Field(sequential=True, tokenize=tokenize,lower=True,fix_length=200)
LABEL=data.Field(sequential=False, use_vocab=False)
# train_path='./data/train_one_label.csv'
# valid_path='./data/valid_one_label.csv'
# test_path='./data/test.csv'
# data=pd.read_csv(train_path)
# data.head()
# for text , label in tqdm(zip(data['comment_text'],data['toxic'])):
#     print(text)
# 構(gòu)建數(shù)據(jù)集-自定義類
# 可以使用繼承Dataset類的MyDatase
# 訓練集、驗證集、測試集的路徑
train_path='./data/train_one_label.csv'
valid_path='./data/valid_one_label.csv'
test_path='./data/test.csv'

# 定義Dataset
class MyDataset(data.Dataset):
    name="Grand Dataset"
    @staticmethod
    def sort_key(ex):
        return len(ex.text)
    def __init__(self,path,text_field,label_field,test=False,aug=False):
        # 將文本中id、評論、標簽放入field中
        fields=[("id",None),
               ("comment_text",text_field),
               ("toxic",label_field)]
        examples=[]
        # 使用pandas讀取數(shù)據(jù),在這里傳入的是一個path
        csv_data=pd.read_csv(path)
        print('read data from {}'.format(path))
        # 對數(shù)據(jù)進行判斷,如果是test數(shù)據(jù),就不包含label內(nèi)容,如果不是,就要讀取toxic
        if test:
            for text in tqdm(csv_data['comment_text']):
                examples.append(data.Example.fromlist([None, text, None], fields))
        else:
            for text , label in tqdm(zip(csv_data['comment_text'], csv_data['toxic'])):
                # 判定是否要增強,就是是否要做隨機刪除處理,大于0.5,隨機刪除;其余打亂
                if aug:
                    rate=random.random()
                    if rate>0.5:
                        text=self.dropout(text)
                    else:
                        text=self.shuffle(text)
                examples.append(data.Example.fromlist([None, text, label], fields))
        # 之前是一些預處理操作,調(diào)用super調(diào)用父類構(gòu)造方法,產(chǎn)生標準Dataset
        super(MyDataset,self).__init__(examples,fields)
        
    def shuffle(self, text):
        # 使用permutation來打亂數(shù)據(jù),但是shuffle會更快一些
        text=np.random.permutation(text.strip().split())
        return ' '.join(text)
    def dropout(self, text,p=0.5):
        # 隨機刪除一些文本
        text = text.strip().split()
        len_ = len(text)
        indexs = np.random.choice(len_, int(len_ * p))
        for i in indexs:
            text[i] = ''
        return ' '.join(text)
        
# 構(gòu)建數(shù)據(jù)集-構(gòu)建數(shù)據(jù)集
train=MyDataset(train_path,text_field=TEXT,label_field=LABEL,test=False,aug=1)
valid=MyDataset(valid_path,text_field=TEXT,label_field=LABEL,test=False,aug=1)
test=MyDataset(test_path,text_field=TEXT,label_field=None,test=True,aug=1)
print(train[0].__dict__.keys())
print(valid[0].__dict__.keys())
print(test[0].__dict__.keys())
read data from ./data/train_one_label.csv


25it [00:00, 5013.27it/s]


read data from ./data/valid_one_label.csv


25it [00:00, 4177.59it/s]


read data from ./data/test.csv


100%|██████████| 33/33 [00:00<00:00, 16598.16it/s]


dict_keys(['comment_text', 'toxic'])
dict_keys(['comment_text', 'toxic'])
dict_keys(['comment_text'])
# 構(gòu)建詞表
TEXT.build_vocab(train)

# 構(gòu)建數(shù)據(jù)集迭代器

from torchtext.data import Iterator,BucketIterator
# train_iter,valid_iter=BucketIterator.splits(
#     (train,valid),
#     batch_size=(8,8),
#     device=-1,
#     sort_key=lambda x: len(x.comment_text),
#     sort_within_batch=False,
#     repeat=False
# )
# 好吧,源代碼中是上面那么寫的,在pycharm里面可以運行,但是在jupyter中報錯,這里拆開來寫了,效果一樣
train_iter = data.BucketIterator(dataset=train, batch_size=8, shuffle=True, sort_within_batch=False, repeat=False)
valid_iter = data.BucketIterator(dataset=valid, batch_size=8, shuffle=True, sort_within_batch=False, repeat=False)

test_iter=Iterator(test,batch_size=8,device=-1,sort=False,sort_within_batch=False,repeat=False)
The `device` argument should be set by using `torch.device` or passing a string as an argument. This behavior will be deprecated soon and currently defaults to cpu.
for idx, batch in enumerate(train_iter):
    print(batch)
    text, label = batch.comment_text, batch.toxic
    print(text.shape, label.shape)
[torchtext.data.batch.Batch of size 8 from GRAND DATASET]
    [.comment_text]:[torch.LongTensor of size 200x8]
    [.toxic]:[torch.LongTensor of size 8]
torch.Size([200, 8]) torch.Size([8])

[torchtext.data.batch.Batch of size 8 from GRAND DATASET]
    [.comment_text]:[torch.LongTensor of size 200x8]
    [.toxic]:[torch.LongTensor of size 8]
torch.Size([200, 8]) torch.Size([8])

[torchtext.data.batch.Batch of size 1 from GRAND DATASET]
    [.comment_text]:[torch.LongTensor of size 200x1]
    [.toxic]:[torch.LongTensor of size 1]
torch.Size([200, 1]) torch.Size([1])

[torchtext.data.batch.Batch of size 8 from GRAND DATASET]
    [.comment_text]:[torch.LongTensor of size 200x8]
    [.toxic]:[torch.LongTensor of size 8]
torch.Size([200, 8]) torch.Size([8])
# 接下來就是構(gòu)造一個LSTM模型,然后訓練一下
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

weight_matrix=TEXT.vocab.vectors
class LSTM(nn.Module):
    def __init__(self):
        super(LSTM,self).__init__()
        self.word_embedding=nn.Embedding(len(TEXT.vocab),300)
        self.lstm=nn.LSTM(input_size=300,hidden_size=128,num_layers=1)
        self.decoder=nn.Linear(128,2)
    def forward(self, sentence):
        embeds=self.word_embedding(sentence)
        print(embeds.shape)
        lstm_out=self.lstm(embeds)[0]
        print(lstm_out.shape)
        final=lstm_out[-1]
        y=self.decoder(final)
        return y
model=LSTM()
model.train()
optimizer=optim.Adam(filter(lambda p:p.requires_grad,model.parameters()),lr=0.01)
crition=F.cross_entropy

for epoch , batch in enumerate(train_iter):
    optimizer.zero_grad()
    predicted=model(batch.comment_text)
    loss=crition(predicted,batch.toxic)
    loss.backward()
    optimizer.step()
    print(loss.item())
torch.Size([200, 8, 300])
torch.Size([200, 8, 128])
0.8496901392936707
torch.Size([200, 8, 300])
torch.Size([200, 8, 128])
0.5025582909584045
torch.Size([200, 1, 300])
torch.Size([200, 1, 128])
3.7277133464813232
torch.Size([200, 8, 300])
torch.Size([200, 8, 128])
0.1662883162498474
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容