AGNews数据集汇集了100多万篇新闻文章。ComeToMyHead在一年多的活动中从2000多个新闻来源收集了新闻文章。ComeToMyHead是一个学术新闻搜索引擎,自2004年7月开始运行。该数据集由学术团体提供,用于数据挖掘(聚类、分类等)、信息检索(排名、搜索等)、xml、数据压缩、数据流和任何其他非商业活动的研究目的。
我们使用AGNews dataset数据集,通过fine-tuning GPT进行情感分类任务。
如下分类:
- World
- Sports
- Business
- Sci/Tech
自定义数据集
mindspore.dataset提供了一些常见数据集和标准格式数据集的加载API。GeneratorDataset可以帮助基于这些类/函数内部的逻辑加载数据集
选取test.csv作为验证集,train.csv数据作为训练集
加载GPT tokenizer,并添加上述使用到的<bos>, <eos>, <pad>占位符。
由于AGnews数据集本身不验证集, 我们手动将其分割为训练和验证两部分, 比例取0.8, 0.2
我们需要对数据进行如下处理:
- 将文本内容进行分词, 并映射为对应的数字索引;
- 统一序列长度:超过进行截断, 不足通过占位符进行补全;
- 按照分类任务的输入要求, 在句首和句末分别添加Start与Extract占位符 (此处用与表示);
- 批处理
另外需要注意的一点是, 由于在前序数据处理中 我们添加了3个特殊占位符, 所以在token embedding中需要调整词典的大小(vocab_size + 3)。
模型评估
AGNews数据集汇集了100多万篇新闻文章。ComeToMyHead在一年多的活动中从2000多个新闻来源收集了新闻文章。ComeToMyHead是一个学术新闻搜索引擎,自2004年7月开始运行。该数据集由学术团体提供,用于数据挖掘(聚类、分类等)、信息检索(排名、搜索等)、xml、数据压缩、数据流和任何其他非商业活动的研究目的。
我们使用AGNews dataset数据集,通过fine-tuning GPT进行情感分类任务。
URL = { "train": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/train.csv", "test": "https://raw.githubusercontent.com/mhjabreel/CharCnn_Keras/master/data/ag_news_csv/test.csv", }如下分类:
{ "label": 3, "text": "New iPad released Just like every other September, this one is no different. Apple is planning to release a bigger, heavier, fatter iPad that..." }自定义数据集
mindspore.dataset提供了一些常见数据集和标准格式数据集的加载API。GeneratorDataset可以帮助基于这些类/函数内部的逻辑加载数据集
class RandomAccessDataset: def __init__(self, filepath): self._data, self._label = self._load_data(filepath) def _load_data(self, filepath): data, labels = [], [] with open(filepath, encoding="utf-8") as csv_file: csv_reader = csv.reader(csv_file) next(csv_reader) # Skip the header row if present for row in csv_reader: label, title, description = row label = int(label) - 1 # Adjust label to 0-indexed text = " ".join((title, description)) # Concatenate title and description labels.append(label) data.append(text) return data, labels def __getitem__(self, index): return self._data[index], self._label[index] def __len__(self): return len(self._data)选取test.csv作为验证集,train.csv数据作为训练集
train_path = 'train.csv' test_path = 'test.csv' train_loader = RandomAccessDataset(train_path) test_loader = RandomAccessDataset(test_path) train_dataset = GeneratorDataset(source=train_loader, column_names=["text", "label"]) test_dataset = GeneratorDataset(source=test_loader, column_names=["text", "label"]) for data in train_dataset: print(data) break加载GPT tokenizer,并添加上述使用到的
<bos>,<eos>,<pad>占位符。# tokenizer from mindnlp.transforms import GPTTokenizer gpt_tokenizer = GPTTokenizer.from_pretrained('./openai-gpt', from_pt=True) # add sepcial token: <PAD> special_tokens_dict = { "bos_token": "<bos>", "eos_token": "<eos>", "pad_token": "<pad>", } num_added_toks = gpt_tokenizer.add_special_tokens(special_tokens_dict)由于AGnews数据集本身不验证集, 我们手动将其分割为训练和验证两部分, 比例取0.8, 0.2
我们需要对数据进行如下处理:
def process_dataset(dataset, tokenizer, max_seq_len=512, batch_size=16, shuffle=False): def tokenize(text): tokenized = tokenizer(text, truncation=True, max_length=max_seq_len) return tokenized[0], tokenized[1] if shuffle: dataset = dataset.shuffle(batch_size) # map dataset dataset = dataset.map(operations=[tokenize], input_columns="text", output_columns=['input_ids', 'attention_mask']) dataset = dataset.map(operations=transforms.TypeCast(mindspore.int32), input_columns="label", output_columns="labels") # batch dataset dataset = dataset.padded_batch(batch_size, pad_info={'input_ids': (None, tokenizer.pad_token_id), 'attention_mask': (None, 0)}) return dataset dataset_train = process_dataset(ds_train, gpt_tokenizer, shuffle=True) dataset_val = process_dataset(ds_val, gpt_tokenizer) dataset_test = process_dataset(test_dataset, gpt_tokenizer) next(dataset_train.create_tuple_iterator())另外需要注意的一点是, 由于在前序数据处理中 我们添加了3个特殊占位符, 所以在token embedding中需要调整词典的大小(vocab_size + 3)。
# set bert config and define parameters for training model = GPTForSequenceClassification.from_pretrained('openai-gpt', from_pt=True, num_labels=4) model.config.pad_token_id = gpt_tokenizer.pad_token_id model.resize_token_embeddings(model.config.vocab_size + 3) optimizer = nn.Adam(model.trainable_params(), learning_rate=2e-5) metric = Accuracy() # define callbacks to save checkpoints ckpoint_cb = CheckpointCallback(save_path='checkpoint', ckpt_name='gpt_agenews_finetune', epochs=1, keep_checkpoint_max=2) best_model_cb = BestModelCallback(save_path='checkpoint', ckpt_name='gpt_agenews_finetune_best', auto_load=True) trainer = Trainer(network=model, train_dataset=dataset_train, eval_dataset=dataset_train, metrics=metric, epochs=3, optimizer=optimizer, callbacks=[ckpoint_cb, best_model_cb], jit=False) trainer.run(tgt_columns="labels")模型评估