{ "cells": [ { "cell_type": "markdown", "id": "6ba64bf2", "metadata": {}, "source": [ "# 6.1 训练工具介绍" ] }, { "cell_type": "code", "execution_count": 1, "id": "b910b829", "metadata": {}, "outputs": [], "source": [ "# HuggingFace提供了巨大的模型库,但这些模型往往是在广义的数据集上训练的,缺乏针对特定\n", "# 数据集的优化,所以在获得一个合适的模型之后,往往还要针对具体\n", "# 任务的特定数据集进行二次训练,这就是所谓的迁移学习。\n", "\n", "# HuggingFace提供了训练工具,统一了模型的再训练过程,使调\n", "# 用者无须了解具体模型的计算过程,只需针对具体的任务准备好数据\n", "# 集,便可以再训练模型。\n", "\n", "# 在本章中将使用一个情感分类任务的例子来再训练一个模型,以\n", "# 此来讲解HuggingFace训练工具的使用方法。" ] }, { "cell_type": "markdown", "id": "801df73f", "metadata": {}, "source": [ "# 6.2 使用训练工具" ] }, { "cell_type": "markdown", "id": "88b8d999", "metadata": {}, "source": [ "### 6.2.1 准备数据集" ] }, { "cell_type": "markdown", "id": "3afb1445", "metadata": {}, "source": [ "###### 1.加载编码工具" ] }, { "cell_type": "code", "execution_count": 2, "id": "719994c3", "metadata": {}, "outputs": [], "source": [ "# 首先加载一个编码工具,由于编码工具和模型往往是成对使用的,\n", "# 所以此处使用hfl/rbt3编码工具,因为要再训练的模型是hfl/rbt3\n", "# 模型,代码如下:\n", "from transformers import AutoTokenizer\n", "tokenizer = AutoTokenizer.from_pretrained('hfl/rbt3')\n", "from transformers import Trainer\n", "from transformers.data.data_collator import DataCollatorWithPadding\n", "from datasets import load_from_disk\n", "from datasets import Dataset, load_dataset\n", "from transformers import AutoModelForSequenceClassification\n", "import torch\n", "from datasets import load_metric\n", "# import evaluate\n", "import numpy as np\n", "from transformers.trainer_utils import EvalPrediction\n", "from transformers import TrainingArguments" ] }, { "cell_type": "code", "execution_count": 3, "id": "62786528", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Asking to truncate to max_length but no maximum length is provided and the model has no predefined maximum length. Default to no truncation.\n" ] }, { "data": { "text/plain": [ "{'input_ids': [[101, 3209, 3299, 6163, 7652, 749, 872, 4638, 4970, 2094, 102], [101, 872, 6163, 7652, 749, 1166, 782, 4638, 3457, 102]], 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 加载了编码工具之后不妨试算一下,观察一下输出,代码如下:\n", "#第6章/试编码句子\n", "tokenizer.batch_encode_plus(\n", "['明月装饰了你的窗子', '你装饰了别人的梦'],\n", "truncation=True,\n", ")\n" ] }, { "cell_type": "markdown", "id": "40bec444", "metadata": {}, "source": [ "###### 2.准备数据集" ] }, { "cell_type": "code", "execution_count": 4, "id": "59df104a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatasetDict({\n", " train: Dataset({\n", " features: ['text', 'label'],\n", " num_rows: 2000\n", " })\n", " test: Dataset({\n", " features: ['text', 'label'],\n", " num_rows: 100\n", " })\n", " validation: Dataset({\n", " features: ['text', 'label'],\n", " num_rows: 1200\n", " })\n", "})" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 加载数据集,使用该数据集来再训练模型,代码如下:\n", "#第6章/从磁盘加载数据集\n", "# 在这段代码中,对数据集进行了采样,目的有以下两方面:一是\n", "# 便于测试;二是模拟再训练集的体量较小的情况,以验证即使是小的\n", "# 数据集,也能通过迁移学习得到一个较好的训练结果。\n", "\n", "dataset = load_from_disk('./data/ChnSentiCorp')\n", "#缩小数据规模,便于测试\n", "dataset['train'] =dataset['train'].shuffle().select(range(2000))\n", "dataset['test'] = dataset['test'].shuffle().select(range(100))\n", "dataset" ] }, { "cell_type": "code", "execution_count": null, "id": "49812e02", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 5, "id": "fa11d2b7", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "31c7f6d1ecc84340b3446975eae1a5c9", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Map (num_proc=4): 0%| | 0/2000 [00:00), torch.Size([4, 2]))" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#第6章/模型试算\n", "#模拟一批数据\n", "data = {\n", "'input_ids': torch.ones(4, 10, dtype=torch.long),\n", "'token_type_ids': torch.ones(4, 10, dtype=torch.long),\n", "'attention_mask': torch.ones(4, 10, dtype=torch.long),\n", "'labels': torch.ones(4, dtype=torch.long)\n", "}\n", "#模型试算\n", "out = model(**data)\n", "out['loss'], out['logits'].shape" ] }, { "cell_type": "markdown", "id": "7c980044", "metadata": {}, "source": [ "### 2.定义评价函数" ] }, { "cell_type": "markdown", "id": "2dd6aee3", "metadata": {}, "source": [ "为了便于在训练过程中观察模型的性能变化,需要定义一个评价\n", "指标函数。对于情感分类任务往往关注正确率指标,所以此处加载正\n", "确率评价函数,代码如下:" ] }, { "cell_type": "code", "execution_count": null, "id": "d6543c75", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 14, "id": "8c3cfed2", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\Miao Jiangbei\\AppData\\Local\\Temp\\ipykernel_28560\\1499779853.py:4: FutureWarning: load_metric is deprecated and will be removed in the next major version of datasets. Use 'evaluate.load' instead, from the new library 🤗 Evaluate: https://huggingface.co/docs/evaluate\n", " metric = load_metric('accuracy')\n", "C:\\Users\\Miao Jiangbei\\AppData\\Roaming\\Python\\Python39\\site-packages\\datasets\\load.py:752: FutureWarning: The repository for accuracy contains custom code which must be executed to correctly load the metric. You can inspect the repository content at https://raw.githubusercontent.com/huggingface/datasets/2.16.1/metrics/accuracy/accuracy.py\n", "You can avoid this message in future by passing the argument `trust_remote_code=True`.\n", "Passing `trust_remote_code=True` will be mandatory to load this metric from the next major release of `datasets`.\n", " warnings.warn(\n" ] } ], "source": [ "#第6章/加载评价指标\n", "\n", "\n", "metric = load_metric('accuracy')\n", "# metric2 = evaluate.load('accuracy')" ] }, { "cell_type": "markdown", "id": "dcefc87d", "metadata": {}, "source": [ "由于模型计算的输出和评价指标要求的输入还有差别,所以需要\n", "定义一个转换函数,把模型计算的输出转换成评价指标可以计算的数\n", "据类型,这个函数就是在训练过程中真正要用到的评价函数,代码如\n", "下" ] }, { "cell_type": "code", "execution_count": 15, "id": "507408f7", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'accuracy': 0.75}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#第6章/定义评价函数\n", "\n", "def compute_metrics(eval_pred):\n", " logits, labels = eval_pred\n", " logits = logits.argmax(axis=1)\n", " return metric.compute(predictions=logits, references=labels)\n", "\n", "#模拟输出\n", "eval_pred = EvalPrediction(\n", "predictions=np.array([[0, 1], [2, 3], [4, 5], [6, 7]]),\n", "label_ids=np.array([1, 1, 0, 1]),\n", ")\n", "compute_metrics(eval_pred)" ] }, { "cell_type": "code", "execution_count": 16, "id": "9e4a265c", "metadata": {}, "outputs": [], "source": [ "# def compute_metrics2(eval_pred):\n", "# logits, labels = eval_pred\n", "# logits = logits.argmax(axis=1)\n", "# return metric2.compute(predictions=logits, references=labels)\n", "# eval_pred = EvalPrediction(\n", "# predictions=np.array([[0, 1], [2, 3], [4, 5], [6, 7]]),\n", "# label_ids=np.array([1, 1, 0, 1]),\n", "# )\n", "# compute_metrics(eval_pred)" ] }, { "cell_type": "markdown", "id": "33820cc6", "metadata": {}, "source": [ "### 3.定义训练超参数" ] }, { "cell_type": "markdown", "id": "1dac5bed", "metadata": {}, "source": [ "##### 在开始训练之前,需要定义好超参数,HuggingFace 使用 `TrainingArguments`对象来封装超参数,代码如下:\n" ] }, { "cell_type": "code", "execution_count": 17, "id": "8829e0ab", "metadata": {}, "outputs": [], "source": [ "#第6章/定义训练参数\n", "\n", "#定义训练参数\n", "args = TrainingArguments(\n", "#定义临时数据保存路径\n", " output_dir='./output_dir',\n", "#定义测试执行的策略,可取值为no、epoch、steps\n", " evaluation_strategy='steps',\n", "#定义每隔多少个step执行一次测试\n", " eval_steps=30,\n", "#定义模型保存策略,可取值为no、epoch、steps\n", " save_strategy='steps',\n", "#定义每隔多少个step保存一次\n", " save_steps=30,\n", "#定义共训练几个轮次\n", " num_train_epochs=1,\n", "#定义学习率\n", " learning_rate=1e-4,\n", "#加入参数权重衰减,防止过拟合\n", " weight_decay=1e-2,\n", "#定义测试和训练时的批次大小\n", " per_device_eval_batch_size=16,\n", " per_device_train_batch_size=16,\n", "#定义是否要使用GPU训练\n", " use_cpu=True\n", ")\n" ] }, { "cell_type": "code", "execution_count": 18, "id": "4fbb3891", "metadata": {}, "outputs": [], "source": [ "# 对于初学者建议从这些简单的参数开始调试,完整的参数列表可参照HuggingFace官方文档。\n" ] }, { "cell_type": "markdown", "id": "ee88c3ca", "metadata": {}, "source": [ "### 4.定义训练器\n" ] }, { "cell_type": "code", "execution_count": 19, "id": "98ede906", "metadata": {}, "outputs": [], "source": [ "#第6章/定义训练器\n", "\n", "#定义训练器\n", "# 定义训练器时需要传递要训练的模型、超参数对象、训练和验证\n", "# 数据集、评价函数,以及数据整理函数。\n", "trainer = Trainer(\n", "model=model,\n", "args=args,\n", "train_dataset=dataset['train'],\n", "eval_dataset=dataset['test'],\n", "compute_metrics=compute_metrics,\n", "data_collator=DataCollatorWithPadding(tokenizer),\n", ")\n" ] }, { "cell_type": "markdown", "id": "c2300dc2", "metadata": {}, "source": [ "### 5.数据整理函数介绍" ] }, { "cell_type": "markdown", "id": "e6bab652", "metadata": {}, "source": [ "###### 数据整理函数使用了由 HuggingFace 提供的 `DataCollatorWithPadding` 对象,\n", "它能把一个批次中长短不一的句子补充成统一的长度,长度取决于这个批次中最长的句子有多长,\n", "所有数据的长度一致后即可转换成矩阵,模型期待的数据类型也是矩阵,\n", "所以经过数据整理函数的处理之后,数据即被整理成模型可以直接计算的矩阵格式。\n", "可以通过下面的例子验证,代码如下:" ] }, { "cell_type": "code", "execution_count": 20, "id": "7c4784e2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "186\n", "43\n", "166\n", "91\n", "94\n", "input_ids torch.Size([5, 186])\n", "token_type_ids torch.Size([5, 186])\n", "attention_mask torch.Size([5, 186])\n", "labels torch.Size([5])\n" ] } ], "source": [ "#第6章/测试数据整理函数\n", "data_collator = DataCollatorWithPadding(tokenizer)\n", "#获取一批数据\n", "data = dataset['train'][:5]\n", "#输出这些句子的长度\n", "for i in data['input_ids']:\n", " print(len(i))\n", "#调用数据整理函数\n", "data = data_collator(data)\n", "#查看整理后的数据\n", "for k, v in data.items():\n", " print(k, v.shape)\n" ] }, { "cell_type": "markdown", "id": "5884f208", "metadata": {}, "source": [ "在这段代码中,首先初始化了一个DataCollatorWithPadding对象作为数据整理函数,\n", "然后从训练集中获取了5条数据作为一批数据,从输出可以看出这些句子有长有短,\n", "之后使用数据整理函数处理这批数据,得到的结果再输出形状,\n", "可以看到这些数据已经被整理成统一的长度,长度取决于这批句子中最长的句子,并且被转换为矩阵形式。" ] }, { "cell_type": "markdown", "id": "671d0fbb", "metadata": {}, "source": [ "通过如下代码可以查看数据整理函数是如何对句子进行补长的\n" ] }, { "cell_type": "code", "execution_count": 21, "id": "18163627", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'[CLS] 地 理 位 置 不 错 , 离 去 机 场 大 大 巴 站 很 近 , 周 围 吃 饭 很 方 便 , 有 一 家 齐 齐 火 锅 不 错 , 也 很 便 宜. [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]'" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tokenizer.decode(data['input_ids'][1])\n" ] }, { "cell_type": "markdown", "id": "06d202a1", "metadata": {}, "source": [ "###### 6.2.3 训练和测试" ] }, { "cell_type": "markdown", "id": "a9e8562b", "metadata": {}, "source": [ "### 1.训练模型" ] }, { "cell_type": "markdown", "id": "6e1f4a9c", "metadata": {}, "source": [ "在开始训练之前,不妨直接对模型进行一次测试,先定下训练前的基准,在训练结束后再对比这里得到的基准,以验证训练的有效性,代码如下:\n" ] }, { "cell_type": "code", "execution_count": 22, "id": "ab673b63", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " \n", " [7/7 2:11:21]\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'eval_loss': 0.7311601042747498,\n", " 'eval_accuracy': 0.4444444444444444,\n", " 'eval_runtime': 12.7081,\n", " 'eval_samples_per_second': 7.79,\n", " 'eval_steps_per_second': 0.551}" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#评价模型\n", "trainer.evaluate()" ] }, { "cell_type": "markdown", "id": "962a0b4f", "metadata": {}, "source": [ "可见模型在训练之前,有44%的正确率。由于使用的训练集为二\n", "分类数据集,所以44%的正确率近乎于瞎猜。这符合预期,因为模型\n", "还没有训练,接下来对模型进行训练,期待它能超过此处得到的成\n", "绩。" ] }, { "cell_type": "markdown", "id": "e56a5f41", "metadata": {}, "source": [ "对模型进行训练,代码如下:" ] }, { "cell_type": "code", "execution_count": 23, "id": "20e20b37", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " \n", " [124/124 11:35, Epoch 1/1]\n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
StepTraining LossValidation LossAccuracy
30No log0.6970270.696970
60No log0.4250630.838384
90No log0.3644910.858586
120No log0.3452740.868687

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "TrainOutput(global_step=124, training_loss=0.4012822489584646, metrics={'train_runtime': 699.6392, 'train_samples_per_second': 2.831, 'train_steps_per_second': 0.177, 'total_flos': 71545310026908.0, 'train_loss': 0.4012822489584646, 'epoch': 1.0})" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trainer.train()" ] }, { "cell_type": "markdown", "id": "dd4914b1", "metadata": {}, "source": [ "如果在训练的过程中由于各种原因导致训练中断,或者希望从某\n", "个 检 查 点 重 新 训 练 模 型 , 则 可 以 使 用 训 练 器 的 train() 函 数 的\n", "`resume_from_checkpoint`参数设定检查点,从该检查点重新训练,\n", "代码如下:" ] }, { "cell_type": "code", "execution_count": null, "id": "842e1b20", "metadata": {}, "outputs": [], "source": [ "#第6章/从某个存档文件继续训练\n", "trainer.train(resume_from_checkpoint='./output_dir/checkpoint-90')\n" ] }, { "cell_type": "markdown", "id": "dea0bb94", "metadata": {}, "source": [ "继续训练和从头训练的输出是一致的,只是继续训练会跳过前90\n", "个steps,所以上面的代码只会训练124−90=34个steps,继续训练\n", "同样会保存检查点,所以上面的代码会覆盖检查点checkpoint-120。\n" ] }, { "cell_type": "code", "execution_count": 24, "id": "06a54b68", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "

\n", " \n", " \n", " [7/7 00:11]\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "{'eval_loss': 0.34446045756340027,\n", " 'eval_accuracy': 0.8686868686868687,\n", " 'eval_runtime': 13.0395,\n", " 'eval_samples_per_second': 7.592,\n", " 'eval_steps_per_second': 0.537,\n", " 'epoch': 1.0}" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#第6章/评价模型\n", "trainer.evaluate()" ] }, { "cell_type": "markdown", "id": "76994746", "metadata": {}, "source": [ "### 2.模型的保存和加载" ] }, { "cell_type": "markdown", "id": "aa5a6681", "metadata": {}, "source": [ "训练得到满意的模型之后,可以手动将该模型的参数保存到磁盘\n", "上,以备以后需要时加载,代码如下:" ] }, { "cell_type": "code", "execution_count": 27, "id": "a83d3389", "metadata": {}, "outputs": [], "source": [ "#第6章/手动保存模型参数\n", "trainer.save_model(output_dir='./output_dir/save_model')" ] }, { "cell_type": "markdown", "id": "aa482c75", "metadata": {}, "source": [ "加载模型参数的方法如下:\n" ] }, { "cell_type": "code", "execution_count": 30, "id": "042a4526", "metadata": {}, "outputs": [], "source": [ "#第6章/手动加载模型参数\n", "import torch\n", "# model.load_state_dict(torch.load('./output_dir/save_model/PyTorch_model.bin'))\n", "model = model.from_pretrained('./output_dir/save_model')" ] }, { "cell_type": "markdown", "id": "5154072c", "metadata": {}, "source": [ "### 3.使用模型预测" ] }, { "cell_type": "code", "execution_count": 31, "id": "7c2a5aa8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "这 次 入 住 和 上 次 相 比, 感 觉 差 很 多 啊... 卫 生 间 马 桶 一 直 漏 水, 早 上 打 扫 房 间 服 务 员 简 直 像 抄 家 一 样, 搞 的 整 个 楼 层 都 鸡 犬 不 宁, 想 多 睡 一 会 儿 都 不 行 ; 晚 上 2 层 的 ktv 音 响 一 直 闹 到 半 夜, 住 在 3 层 的 我 不 但 没 法 睡 觉, 连 听 电 视 的 声 音 都 有 困 难. 下 次 再 去 扬 州, 我 肯 定 要 换 个 酒 店 了.\n", "label= 0\n", "predict= 0\n", "一 进 房 间 就 有 一 股 霉 味 , 后 来 发 现 马 桶 水 箱 出 不 了 水 , 两 次 让 服 务 员 来 修 理 , 还 是 不 太 放 心 , 而 且 对 服 务 员 的 态 度 也 感 到 不 满 , 于 是 在 前 台 要 求 更 换 另 一 楼 层 的 房 间 , 可 是 换 过 了 的 房 间 , 可 能 很 长 时 间 无 人 住 过 , 下 水 渠 散 出 很 浓 的 臭 味 , 真 让 人 不 适 , 还 好 , 这 层 的 服 务 员 还 算 很 认 真 地 用 水 冲 洗 了 浴 室 , 到 了 晚 上 我 们 洗 澡 后 , 又 发 现 有 水 从 床 前 的 木 地 板 夹 逢 渗 透 出 来 , 相 对 这 样 收 费 却 又 如 此 的 质 量 , 真 让 我 无 话 可 说 了 。\n", "label= 0\n", "predict= 0\n", "我 本 身 就 是 一 个 漫 画 迷 ! 非 常 喜 欢 朱 德 庸 的 作 品 ! 《 绝 对 小 孩 》 这 本 书 出 版 以 后 立 即 买 回 来 。 里 面 的 内 容 太 搞 笑 了 ! 女 儿 也 特 别 喜 欢 , 每 天 回 来 就 赶 紧 写 作 业 , 然 后 好 看 书 。 哈 哈 ! 这 是 我 的 小 计 策 ! 早 点 写 完 作 业 , 就 可 以 看 这 本 漫 画 书 作 为 奖 励 ! 《 绝 对 小 孩 2 》 是 作 为 期 末 考 试 95 分 以 上 的 奖 励 买 回 来 的 。 用 这 书 作 为 物 质 刺 激 还 真 是 不 错 呢 !\n", "label= 1\n", "predict= 1\n", "虽 然 我 的 键 盘 有 些 小 的 问 题 , 但 这 是 个 别 现 象 , 这 个 我 自 己 清 楚 , 我 也 没 有 找 京 东 , 直 接 找 的 thinkpad 客 服 , 目 前 正 在 处 理 中 , 相 信 不 是 什 么 大 事 , thinkpad 可 以 帮 助 我 解 决 好 的 。\n", "label= 0\n", "predict= 0\n", "房 间 隔 音 效 果 极 差 , 深 夜 如 果 隔 壁 客 人 大 声 喧 哗 的 话 服 务 员 会 去 提 醒 , 但 仅 限 于 你 投 诉 后\n", "label= 0\n", "predict= 0\n", "我 也 是 前 段 时 间 玩 的 那 游 戏 。 。 。 真 正 的 历 史 也 往 往 夹 杂 了 一 些 黑 暗 的 元 素 比 如 奴 隶 的 贩 卖 对 新 土 地 的 掠 夺 但 是 对 于 今 天 的 人 们 来 说 大 海 依 旧 是 令 人 向 往 的 世 界 所 以 将 过 去 的 历 史 填 补 进 记 忆 并 且 更 加 繁 荣 的 辉 煌 下 去 吧 前 天 刚 看 的 电 影 《 英 吉 利 海 盗 》 书 里 面 居 然 真 的 写 到 历 史 上 真 有 爱 德 华 & # 183 ; 蒂 奇 此 人 只 不 过 电 影 里 他 是 英 吉 利 的 黑 胡 子 海 盗 船 长 而 历 史 上 他 在 加 勒 比 海 那 边 。 。 。\n", "label= 1\n", "predict= 1\n", "v 系 统 和 xp 系 统 能 做 到 二 选 一 就 更 好 了 , 毕 竟 大 部 分 人 还 是 更 偏 爱 xp 系 统 。\n", "label= 0\n", "predict= 1\n", "买 来 要 自 己 装 系 统 , 麻 烦 ! amd 散 热 不 太 好 ! 反 应 有 点 慢 ! 价 钱 和 我 们 这 边 的 商 场 差 不 多 ! 没 实 惠 !\n", "label= 0\n", "predict= 0\n" ] } ], "source": [ "#第6章/测试\n", "model.eval()\n", "for i, data in enumerate(trainer.get_eval_dataloader()):\n", " break\n", "out = model(**data)\n", "out = out['logits'].argmax(dim=1)\n", "for i in range(8):\n", " print(tokenizer.decode(data['input_ids'][i],skip_special_tokens =True))\n", " print('label=', data['labels'][i].item())\n", " print('predict=', out[i].item())" ] }, { "cell_type": "code", "execution_count": null, "id": "3de7e1a8", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.13" } }, "nbformat": 4, "nbformat_minor": 5 }