| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- from config import *
- from utils import *
- import torch.utils.data as data
- from torch.nn.utils.rnn import pad_sequence
- import json
- import torch
- from model import get_padding_mask,get_subsequent_mask
- class Dataset(data.Dataset):
- def __init__(self,type="train"):
- super().__init__()
- if type == 'train':
- file_path = TRAIN_SAMPLE_PATH
- elif type == 'val':
- file_path = VAL_SAMPLE_PATH
- # 读取文件
- with open(file_path, encoding='utf-8') as file:
- self.lines = json.loads(file.read())
- # 词表引入
- _, self.en_vocab2id = get_vocab('en')
- _, self.zh_vocab2id = get_vocab('zh')
- def __len__(self):
- return len(self.lines)
- def __getitem__(self, index):
- en_text, zh_text = self.lines[index]
- source = [self.en_vocab2id.get(v.lower(), UNK_ID) for v in divided_en(en_text)] # 英文转换成编号
- # 原代码没有过滤Jieba返回的纯空白token,空格不在中文词表中,
- # 因此会在训练和验证时被错误地转换为<unk>。
- # target = [self.zh_vocab2id.get(v.lower(), UNK_ID) for v in divided_zh(zh_text)]
- # 数据映射改进:与data_processor.py生成词表时的规则保持一致,
- # 只过滤空格、制表符等纯空白token,正常的中文、英文名称和标点均保留。
- target = [
- self.zh_vocab2id.get(v.lower(), UNK_ID)
- for v in divided_zh(zh_text)
- if v.strip()
- ] # 中文转换成编号
- return source, target, zh_text
-
- #数据对齐和整理
- #因为每个批次中不同的句子长度不一致,需要把一个批次中的所有句子的长度处理成一样的长度
- def collate_fn(self, batch):
- #利用 * 号操作符,可以将元组解压为列表
- batch_src, batch_tgt, tgt_text = zip(*batch)
- #处理encoder的输入
- src_x = pad_sequence([torch.LongTensor(src) for src in batch_src], True, PAD_ID)
- src_mask = get_padding_mask(src_x, PAD_ID)
- #处理decoder的输入
- tgt_x = [torch.LongTensor([SOS_ID] + tgt) for tgt in batch_tgt]
- tgt_x = pad_sequence(tgt_x, True, PAD_ID)
- tgt_pad_mask = get_padding_mask(tgt_x, PAD_ID)
- tgt_subsqueent_mask = get_subsequent_mask(tgt_x.size(1))
- tgt_mask = tgt_pad_mask | tgt_subsqueent_mask
- tgt_mask = tgt_mask != 0
- #处理标签
- tgt_y = [torch.LongTensor(tgt+[EOS_ID]) for tgt in batch_tgt]
- tgt_y = pad_sequence(tgt_y, True, PAD_ID)
- return src_x, src_mask, tgt_x, tgt_mask, tgt_y, tgt_text
-
- if __name__ == '__main__':
- val = Dataset('train')
- loader = data.DataLoader(val, batch_size=2, collate_fn=val.collate_fn)
- print(next(iter(loader)))
|