国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

自然語言處理 Paddle NLP - 情感分析技術及應用SKEP-實踐

這篇具有很好參考價值的文章主要介紹了自然語言處理 Paddle NLP - 情感分析技術及應用SKEP-實踐。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

基礎
自然語言處理(NLP)
自然語言處理PaddleNLP-詞向量應用展示
自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習
自然語言處理PaddleNLP-預訓練語言模型及應用
自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram)
自然語言處理PaddleNLP-詞法分析技術及其應用
自然語言處理PaddleNLP-快遞單信息抽取
理解
自然語言處理PaddleNLP-信息抽取技術及應用
自然語言處理PaddleNLP-基于預訓練模型完成實體關系抽取--實踐
自然語言處理PaddleNLP-情感分析技術及應用-理論
自然語言處理PaddleNLP-情感分析技術及應用SKEP-實踐
問答
自然語言處理PaddleNLP-檢索式文本問答-理論
自然語言處理PaddleNLP-結(jié)構化數(shù)據(jù)問答-理論
翻譯
自然語言處理PaddleNLP-文本翻譯技術及應用-理論
自然語言處理PaddleNLP-機器同傳技術及應用-理論
對話
自然語言處理PaddleNLP-任務式對話系統(tǒng)-理論
自然語言處理PaddleNLP-開放域?qū)υ捪到y(tǒng)-理論
產(chǎn)業(yè)實踐
自然語言處理 Paddle NLP - 預訓練模型產(chǎn)業(yè)實踐課-理論

Part A. 情感分析任務

眾所周知,人類自然語言中包含了豐富的情感色彩:表達人的情緒(如悲傷、快樂)、表達人的心情(如倦怠、憂郁)、表達人的喜好(如喜歡、討厭)、表達人的個性特征和表達人的立場等等。情感分析在商品喜好、消費決策、輿情分析等場景中均有應用。利用機器自動分析這些情感傾向,不但有助于幫助企業(yè)了解消費者對其產(chǎn)品的感受,為產(chǎn)品改進提供依據(jù);同時還有助于企業(yè)分析商業(yè)伙伴們的態(tài)度,以便更好地進行商業(yè)決策。

被人們所熟知的情感分析任務是將一段文本分類,如分為情感極性為正向、負向其他的三分類問題:



情感分析任務

  • 正向: 表示正面積極的情感,如高興,幸福,驚喜,期待等。
  • 負向: 表示負面消極的情感,如難過,傷心,憤怒,驚恐等。
  • 其他: 其他類型的情感。

實際上,以上熟悉的情感分析任務是句子級情感分析任務。

情感分析任務還可以進一步分為句子級情感分析、目標級情感分析等任務。在下面章節(jié)將會詳細介紹兩種任務及其應用場景。

Part B. 情感分析預訓練模型SKEP

近年來,大量的研究表明基于大型語料庫的預訓練模型(Pretrained Models, PTM)可以學習通用的語言表示,有利于下游NLP任務,同時能夠避免從零開始訓練模型。隨著計算能力的發(fā)展,深度模型的出現(xiàn)(即 Transformer)和訓練技巧的增強使得 PTM 不斷發(fā)展,由淺變深。

情感預訓練模型SKEP(Sentiment Knowledge Enhanced Pre-training for Sentiment Analysis)。SKEP利用情感知識增強預訓練模型, 在14項中英情感分析典型任務上全面超越SOTA,此工作已經(jīng)被ACL 2020錄用。SKEP是百度研究團隊提出的基于情感知識增強的情感預訓練算法,此算法采用無監(jiān)督方法自動挖掘情感知識,然后利用情感知識構建預訓練目標,從而讓機器學會理解情感語義。SKEP為各類情感分析任務提供統(tǒng)一且強大的情感語義表示。

論文地址:https://arxiv.org/abs/2005.05635

百度研究團隊在三個典型情感分析任務,句子級情感分類(Sentence-level Sentiment Classification),評價目標級情感分類(Aspect-level Sentiment Classification)、觀點抽?。∣pinion Role Labeling),共計14個中英文數(shù)據(jù)上進一步驗證了情感預訓練模型SKEP的效果。

具體實驗效果參考:https://github.com/baidu/Senta#skep

Part C 句子級情感分析 & 目標級情感分析

Part C.1 句子級情感分析

對給定的一段文本進行情感極性分類,常用于影評分析、網(wǎng)絡論壇輿情分析等場景。如:

選擇珠江花園的原因就是方便,有電動扶梯直接到達海邊,周圍餐館、食廊、商場、超市、攤位一應俱全。酒店裝修一般,但還算整潔。 泳池在大堂的屋頂,因此很小,不過女兒倒是喜歡。 包的早餐是西式的,還算豐富。 服務嗎,一般	1
15.4寸筆記本的鍵盤確實爽,基本跟臺式機差不多了,蠻喜歡數(shù)字小鍵盤,輸數(shù)字特方便,樣子也很美觀,做工也相當不錯	1
房間太小。其他的都一般。。。。。。。。。	0

其中1表示正向情感,0表示負向情感。




句子級情感分析任務

常用數(shù)據(jù)集

ChnSenticorp數(shù)據(jù)集是公開中文情感分析常用數(shù)據(jù)集, 其為2分類數(shù)據(jù)集。PaddleNLP已經(jīng)內(nèi)置該數(shù)據(jù)集,一鍵即可加載。

from paddlenlp.datasets import load_dataset

train_ds, dev_ds, test_ds = load_dataset("chnsenticorp", splits=["train", "dev", "test"])

print(train_ds[0])
print(train_ds[1])
print(train_ds[:10])
100%|██████████| 1909/1909 [00:00<00:00, 37287.30it/s]
{'text': '選擇珠江花園的原因就是方便,有電動扶梯直接到達海邊,周圍餐館、食廊、商場、超市、攤位一應俱全。酒店裝修一般,但還算整潔。 泳池在大堂的屋頂,因此很小,不過女兒倒是喜歡。 包的早餐是西式的,還算豐富。 服務嗎,一般', 'label': 1, 'qid': ''}

{'text': '15.4寸筆記本的鍵盤確實爽,基本跟臺式機差不多了,蠻喜歡數(shù)字小鍵盤,輸數(shù)字特方便,樣子也很美觀,做工也相當不錯', 'label': 1, 'qid': ''}

[{'text': '選擇珠江花園的原因就是方便,有電動扶梯直接到達海邊,周圍餐館、食廊、商場、超市、攤位一應俱全。酒店裝修一般,但還算整潔。 泳池在大堂的屋頂,因此很小,不過女兒倒是喜歡。 包的早餐是西式的,還算豐富。 服務嗎,一般', 'label': 1, 'qid': ''}, {'text': '15.4寸筆記本的鍵盤確實爽,基本跟臺式機差不多了,蠻喜歡數(shù)字小鍵盤,輸數(shù)字特方便,樣子也很美觀,做工也相當不錯', 'label': 1, 'qid': ''}, {'text': '房間太小。其他的都一般。。。。。。。。。', 'label': 0, 'qid': ''}, {'text': '1.接電源沒有幾分鐘,電源適配器熱的不行. 2.攝像頭用不起來. 3.機蓋的鋼琴漆,手不能摸,一摸一個印. 4.硬盤分區(qū)不好辦.', 'label': 0, 'qid': ''}, {'text': '今天才知道這書還有第6卷,真有點郁悶:為什么同一套書有兩種版本呢?當當網(wǎng)是不是該跟出版社商量商量,單獨出個第6卷,讓我們的孩子不會有所遺憾。', 'label': 1, 'qid': ''}, {'text': '機器背面似乎被撕了張什么標簽,殘膠還在。但是又看不出是什么標簽不見了,該有的都在,怪', 'label': 0, 'qid': ''}, {'text': '呵呵,雖然表皮看上去不錯很精致,但是我還是能看得出來是盜的。但是里面的內(nèi)容真的不錯,我媽愛看,我自己也學著找一些穴位。', 'label': 0, 'qid': ''}, {'text': '這本書實在是太爛了,以前聽浙大的老師說這本書怎么怎么不對,哪些地方都是誤導的還不相信,終于買了一本看一下,發(fā)現(xiàn)真是~~~無語,這種書都寫得出來', 'label': 0, 'qid': ''}, {'text': '地理位置佳,在市中心。酒店服務好、早餐品種豐富。我住的商務數(shù)碼房電腦寬帶速度滿意,房間還算干凈,離湖南路小吃街近。', 'label': 1, 'qid': ''}, {'text': '5.1期間在這住的,位置還可以,在市委市政府附近,要去商業(yè)區(qū)和步行街得打車,屋里有蚊子,雖然空間挺大,晚上熄燈后把窗簾拉上簡直是伸手不見五指,很適合睡覺,但是會被該死的蚊子吵醒!打死了兩只,第二天早上還是發(fā)現(xiàn)又沒打死的,衛(wèi)生間挺大,但是設備很老舊。', 'label': 1, 'qid': ''}]

SKEP模型加載

PaddleNLP已經(jīng)實現(xiàn)了SKEP預訓練模型,可以通過一行代碼實現(xiàn)SKEP加載。

句子級情感分析模型是SKEP fine-tune 文本分類常用模型SkepForSequenceClassification。其首先通過SKEP提取句子語義特征,之后將語義特征進行分類。

from paddlenlp.transformers import SkepForSequenceClassification, SkepTokenizer

# 指定模型名稱,一鍵加載模型
model = SkepForSequenceClassification.from_pretrained(pretrained_model_name_or_path="skep_ernie_1.0_large_ch", num_classes=len(train_ds.label_list))
# 同樣地,通過指定模型名稱一鍵加載對應的Tokenizer,用于處理文本數(shù)據(jù),如切分token,轉(zhuǎn)token_id等。
tokenizer = SkepTokenizer.from_pretrained(pretrained_model_name_or_path="skep_ernie_1.0_large_ch")
[2023-06-09 11:33:08,208] [    INFO] - Downloading https://paddlenlp.bj.bcebos.com/models/transformers/skep/skep_ernie_1.0_large_ch.pdparams and saved to /home/aistudio/.paddlenlp/models/skep_ernie_1.0_large_ch
[2023-06-09 11:33:08,211] [    INFO] - Downloading skep_ernie_1.0_large_ch.pdparams from https://paddlenlp.bj.bcebos.com/models/transformers/skep/skep_ernie_1.0_large_ch.pdparams
100%|██████████| 1238309/1238309 [00:30<00:00, 40700.73it/s]
W0609 11:33:38.774677   148 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 8.0, Driver API Version: 11.2, Runtime API Version: 11.2
W0609 11:33:38.778790   148 device_context.cc:465] device: 0, cuDNN Version: 8.2.
[2023-06-09 11:33:46,676] [    INFO] - Downloading https://paddlenlp.bj.bcebos.com/models/transformers/skep/skep_ernie_1.0_large_ch.vocab.txt and saved to /home/aistudio/.paddlenlp/models/skep_ernie_1.0_large_ch
[2023-06-09 11:33:46,679] [    INFO] - Downloading skep_ernie_1.0_large_ch.vocab.txt from https://paddlenlp.bj.bcebos.com/models/transformers/skep/skep_ernie_1.0_large_ch.vocab.txt
100%|██████████| 55/55 [00:00<00:00, 5570.66it/s]

SkepForSequenceClassification可用于句子級情感分析和目標級情感分析任務。其通過預訓練模型SKEP獲取輸入文本的表示,之后將文本表示進行分類。

  • pretrained_model_name_or_path:模型名稱。支持"skep_ernie_1.0_large_ch","skep_ernie_2.0_large_en"。

    • "skep_ernie_1.0_large_ch":是SKEP模型在預訓練ernie_1.0_large_ch基礎之上在海量中文數(shù)據(jù)上繼續(xù)預訓練得到的中文預訓練模型;
    • "skep_ernie_2.0_large_en":是SKEP模型在預訓練ernie_2.0_large_en基礎之上在海量英文數(shù)據(jù)上繼續(xù)預訓練得到的英文預訓練模型;
  • num_classes: 數(shù)據(jù)集分類類別數(shù)。

關于SKEP模型實現(xiàn)詳細信息參考:https://github.com/PaddlePaddle/PaddleNLP/tree/develop/paddlenlp/transformers/skep

數(shù)據(jù)處理

同樣地,我們需要將原始ChnSentiCorp數(shù)據(jù)處理成模型可以讀入的數(shù)據(jù)格式。

SKEP模型對中文文本處理按照字粒度進行處理,我們可以使用PaddleNLP內(nèi)置的SkepTokenizer完成一鍵式處理。

import os
from functools import partial


import numpy as np
import paddle
import paddle.nn.functional as F
from paddlenlp.data import Stack, Tuple, Pad

from utils import create_dataloader

def convert_example(example,
                    tokenizer,
                    max_seq_length=512,
                    is_test=False):
    """
    Builds model inputs from a sequence or a pair of sequence for sequence classification tasks
    by concatenating and adding special tokens. And creates a mask from the two sequences passed 
    to be used in a sequence-pair classification task.
        
    A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence has the following format:
    ::
        - single sequence: ``[CLS] X [SEP]``
        - pair of sequences: ``[CLS] A [SEP] B [SEP]``

    A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence pair mask has the following format:
    ::

        0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
        | first sequence    | second sequence |

    If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s).


    Args:
        example(obj:`list[str]`): List of input data, containing text and label if it have label.
        tokenizer(obj:`PretrainedTokenizer`): This tokenizer inherits from :class:`~paddlenlp.transformers.PretrainedTokenizer` 
            which contains most of the methods. Users should refer to the superclass for more information regarding methods.
        max_seq_len(obj:`int`): The maximum total input sequence length after tokenization. 
            Sequences longer than this will be truncated, sequences shorter will be padded.
        is_test(obj:`False`, defaults to `False`): Whether the example contains label or not.

    Returns:
        input_ids(obj:`list[int]`): The list of token ids.
        token_type_ids(obj: `list[int]`): List of sequence pair mask.
        label(obj:`int`, optional): The input label if not is_test.
    """
    # 將原數(shù)據(jù)處理成model可讀入的格式,enocded_inputs是一個dict,包含input_ids、token_type_ids等字段
    encoded_inputs = tokenizer(
        text=example["text"], max_seq_len=max_seq_length)

    # input_ids:對文本切分token后,在詞匯表中對應的token id
    input_ids = encoded_inputs["input_ids"]
    # token_type_ids:當前token屬于句子1還是句子2,即上述圖中表達的segment ids
    token_type_ids = encoded_inputs["token_type_ids"]

    if not is_test:
        # label:情感極性類別
        label = np.array([example["label"]], dtype="int64")
        return input_ids, token_type_ids, label
    else:
        # qid:每條數(shù)據(jù)的編號
        qid = np.array([example["qid"]], dtype="int64")
        return input_ids, token_type_ids, qid
# 批量數(shù)據(jù)大小
batch_size = 32
# 文本序列最大長度
max_seq_length = 256

# 將數(shù)據(jù)處理成模型可讀入的數(shù)據(jù)格式
trans_func = partial(
    convert_example,
    tokenizer=tokenizer,
    max_seq_length=max_seq_length)

# 將數(shù)據(jù)組成批量式數(shù)據(jù),如
# 將不同長度的文本序列padding到批量式數(shù)據(jù)中最大長度
# 將每條數(shù)據(jù)label堆疊在一起
batchify_fn = lambda samples, fn=Tuple(
    Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input_ids
    Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # token_type_ids
    Stack()  # labels
): [data for data in fn(samples)]
train_data_loader = create_dataloader(
    train_ds,
    mode='train',
    batch_size=batch_size,
    batchify_fn=batchify_fn,
    trans_fn=trans_func)
dev_data_loader = create_dataloader(
    dev_ds,
    mode='dev',
    batch_size=batch_size,
    batchify_fn=batchify_fn,
    trans_fn=trans_func)

模型訓練和評估

定義損失函數(shù)、優(yōu)化器以及評價指標后,即可開始訓練。

推薦超參設置:

  • max_seq_length=256
  • batch_size=48
  • learning_rate=2e-5
  • epochs=10

實際運行時可以根據(jù)顯存大小調(diào)整batch_size和max_seq_length大小。

import time

from utils import evaluate

# 訓練輪次
epochs = 1
# 訓練過程中保存模型參數(shù)的文件夾
ckpt_dir = "skep_ckpt"
# len(train_data_loader)一輪訓練所需要的step數(shù)
num_training_steps = len(train_data_loader) * epochs

# Adam優(yōu)化器
optimizer = paddle.optimizer.AdamW(
    learning_rate=2e-5,
    parameters=model.parameters())
# 交叉熵損失函數(shù)
criterion = paddle.nn.loss.CrossEntropyLoss()
# accuracy評價指標
metric = paddle.metric.Accuracy()
# 開啟訓練
global_step = 0
tic_train = time.time()
for epoch in range(1, epochs + 1):
    for step, batch in enumerate(train_data_loader, start=1):
        input_ids, token_type_ids, labels = batch
        # 喂數(shù)據(jù)給model
        logits = model(input_ids, token_type_ids)
        # 計算損失函數(shù)值
        loss = criterion(logits, labels)
        # 預測分類概率值
        probs = F.softmax(logits, axis=1)
        # 計算acc
        correct = metric.compute(probs, labels)
        metric.update(correct)
        acc = metric.accumulate()

        global_step += 1
        if global_step % 10 == 0:
            print(
                "global step %d, epoch: %d, batch: %d, loss: %.5f, accu: %.5f, speed: %.2f step/s"
                % (global_step, epoch, step, loss, acc,
                    10 / (time.time() - tic_train)))
            tic_train = time.time()
        
        # 反向梯度回傳,更新參數(shù)
        loss.backward()
        optimizer.step()
        optimizer.clear_grad()

        if global_step % 100 == 0:
            save_dir = os.path.join(ckpt_dir, "model_%d" % global_step)
            if not os.path.exists(save_dir):
                os.makedirs(save_dir)
            # 評估當前訓練的模型
            evaluate(model, criterion, metric, dev_data_loader)
            # 保存當前模型參數(shù)等
            model.save_pretrained(save_dir)
            # 保存tokenizer的詞表等
            tokenizer.save_pretrained(save_dir)
global step 10, epoch: 1, batch: 10, loss: 0.68203, accu: 0.56875, speed: 2.49 step/s
global step 20, epoch: 1, batch: 20, loss: 0.67362, accu: 0.60313, speed: 3.92 step/s
global step 30, epoch: 1, batch: 30, loss: 0.32944, accu: 0.67812, speed: 3.74 step/s
global step 40, epoch: 1, batch: 40, loss: 0.23817, accu: 0.73203, speed: 3.60 step/s
global step 50, epoch: 1, batch: 50, loss: 0.22706, accu: 0.76812, speed: 3.69 step/s
global step 60, epoch: 1, batch: 60, loss: 0.32217, accu: 0.79010, speed: 3.65 step/s
global step 70, epoch: 1, batch: 70, loss: 0.38290, accu: 0.80848, speed: 3.99 step/s
global step 80, epoch: 1, batch: 80, loss: 0.32560, accu: 0.81914, speed: 3.81 step/s
global step 90, epoch: 1, batch: 90, loss: 0.28812, accu: 0.83090, speed: 3.69 step/s
global step 100, epoch: 1, batch: 100, loss: 0.08818, accu: 0.83906, speed: 3.68 step/s
eval loss: 0.22184, accu: 0.91250
global step 110, epoch: 1, batch: 110, loss: 0.19725, accu: 0.90312, speed: 1.06 step/s
global step 120, epoch: 1, batch: 120, loss: 0.13100, accu: 0.90781, speed: 3.58 step/s
global step 130, epoch: 1, batch: 130, loss: 0.19981, accu: 0.90833, speed: 3.68 step/s
global step 140, epoch: 1, batch: 140, loss: 0.15833, accu: 0.90938, speed: 3.77 step/s
global step 150, epoch: 1, batch: 150, loss: 0.11410, accu: 0.91563, speed: 3.76 step/s
global step 160, epoch: 1, batch: 160, loss: 0.22827, accu: 0.91771, speed: 3.78 step/s
global step 170, epoch: 1, batch: 170, loss: 0.13842, accu: 0.91652, speed: 3.62 step/s
global step 180, epoch: 1, batch: 180, loss: 0.03657, accu: 0.91992, speed: 3.88 step/s
global step 190, epoch: 1, batch: 190, loss: 0.20643, accu: 0.91840, speed: 3.65 step/s
global step 200, epoch: 1, batch: 200, loss: 0.40149, accu: 0.91750, speed: 3.84 step/s
eval loss: 0.19440, accu: 0.93083

預測提交結(jié)果

使用訓練得到的模型還可以對文本進行情感預測。

import numpy as np
import paddle

# 處理測試集數(shù)據(jù)
trans_func = partial(
    convert_example,
    tokenizer=tokenizer,
    max_seq_length=max_seq_length,
    is_test=True)
batchify_fn = lambda samples, fn=Tuple(
    Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input
    Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # segment
    Stack() # qid
): [data for data in fn(samples)]
test_data_loader = create_dataloader(
    test_ds,
    mode='test',
    batch_size=batch_size,
    batchify_fn=batchify_fn,
    trans_fn=trans_func)
# 根據(jù)實際運行情況,更換加載的參數(shù)路徑
params_path = 'skep_ckp/model_500/model_state.pdparams'
if params_path and os.path.isfile(params_path):
    # 加載模型參數(shù)
    state_dict = paddle.load(params_path)
    model.set_dict(state_dict)
    print("Loaded parameters from %s" % params_path)
label_map = {0: '0', 1: '1'}
results = []
# 切換model模型為評估模式,關閉dropout等隨機因素
model.eval()
for batch in test_data_loader:
    input_ids, token_type_ids, qids = batch
    # 喂數(shù)據(jù)給模型
    logits = model(input_ids, token_type_ids)
    # 預測分類
    probs = F.softmax(logits, axis=-1)
    idx = paddle.argmax(probs, axis=1).numpy()
    idx = idx.tolist()
    labels = [label_map[i] for i in idx]
    qids = qids.numpy().tolist()
    results.extend(zip(qids, labels))
res_dir = "./results"
if not os.path.exists(res_dir):
    os.makedirs(res_dir)
# 寫入預測結(jié)果
with open(os.path.join(res_dir, "ChnSentiCorp.tsv"), 'w', encoding="utf8") as f:
    f.write("index\tprediction\n")
    for qid, label in results:
        f.write(str(qid[0])+"\t"+label+"\n")

Part C.2 目標級情感分析

在電商產(chǎn)品分析場景下,除了分析整體商品的情感極性外,還細化到以商品具體的“方面”為分析主體進行情感分析(aspect-level),如下、:

  • 這個薯片口味有點咸,太辣了,不過口感很脆。

關于薯片的口味方面是一個負向評價(咸,太辣),然而對于口感方面卻是一個正向評價(很脆)。

  • 我很喜歡夏威夷,就是這邊的海鮮太貴了。

關于夏威夷是一個正向評價(喜歡),然而對于夏威夷的海鮮卻是一個負向評價(價格太貴)。




目標級情感分析任務

#### 常用數(shù)據(jù)集

千言數(shù)據(jù)集已提供了許多任務常用數(shù)據(jù)集。
其中情感分析數(shù)據(jù)集下載鏈接:https://aistudio.baidu.com/aistudio/competition/detail/50/?isFromLUGE=TRUE

SE-ABSA16_PHNS數(shù)據(jù)集是關于手機的目標級情感分析數(shù)據(jù)集。PaddleNLP已經(jīng)內(nèi)置了該數(shù)據(jù)集,加載方式,如下:

train_ds, test_ds = load_dataset("seabsa16", "phns", splits=["train", "test"])

print(train_ds[0])
print(train_ds[1])
print(train_ds[2])

SKEP模型加載

目標級情感分析模型同樣使用SkepForSequenceClassification模型,但目標級情感分析模型的輸入不單單是一個句子,而是句對。一個句子描述“評價對象方面(aspect)”,另一個句子描述"對該方面的評論"。如下圖所示。

# 指定模型名稱一鍵加載模型
model = SkepForSequenceClassification.from_pretrained(
    'skep_ernie_1.0_large_ch', num_classes=len(train_ds.label_list))
# 指定模型名稱一鍵加載tokenizer
tokenizer = SkepTokenizer.from_pretrained('skep_ernie_1.0_large_ch')

數(shù)據(jù)處理

同樣地,我們需要將原始SE_ABSA16_PHNS數(shù)據(jù)處理成模型可以讀入的數(shù)據(jù)格式。

SKEP模型對中文文本處理按照字粒度進行處理,我們可以使用PaddleNLP內(nèi)置的SkepTokenizer完成一鍵式處理。

from functools import partial
import os
import time

import numpy as np
import paddle
import paddle.nn.functional as F
from paddlenlp.data import Stack, Tuple, Pad


def convert_example(example,
                    tokenizer,
                    max_seq_length=512,
                    is_test=False,
                    dataset_name="chnsenticorp"):
    """
    Builds model inputs from a sequence or a pair of sequence for sequence classification tasks
    by concatenating and adding special tokens. And creates a mask from the two sequences passed 
    to be used in a sequence-pair classification task.
        
    A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence has the following format:
    ::
        - single sequence: ``[CLS] X [SEP]``
        - pair of sequences: ``[CLS] A [SEP] B [SEP]``

    A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence pair mask has the following format:
    ::

        0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
        | first sequence    | second sequence |

    If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s).
    
    note: There is no need token type ids for skep_roberta_large_ch model.


    Args:
        example(obj:`list[str]`): List of input data, containing text and label if it have label.
        tokenizer(obj:`PretrainedTokenizer`): This tokenizer inherits from :class:`~paddlenlp.transformers.PretrainedTokenizer` 
            which contains most of the methods. Users should refer to the superclass for more information regarding methods.
        max_seq_len(obj:`int`): The maximum total input sequence length after tokenization. 
            Sequences longer than this will be truncated, sequences shorter will be padded.
        is_test(obj:`False`, defaults to `False`): Whether the example contains label or not.
        dataset_name((obj:`str`, defaults to "chnsenticorp"): The dataset name, "chnsenticorp" or "sst-2".

    Returns:
        input_ids(obj:`list[int]`): The list of token ids.
        token_type_ids(obj: `list[int]`): List of sequence pair mask.
        label(obj:`numpy.array`, data type of int64, optional): The input label if not is_test.
    """
    encoded_inputs = tokenizer(
        text=example["text"],
        text_pair=example["text_pair"],
        max_seq_len=max_seq_length)

    input_ids = encoded_inputs["input_ids"]
    token_type_ids = encoded_inputs["token_type_ids"]

    if not is_test:
        label = np.array([example["label"]], dtype="int64")
        return input_ids, token_type_ids, label
    else:
        return input_ids, token_type_ids
# 處理的最大文本序列長度
max_seq_length=256
# 批量數(shù)據(jù)大小
batch_size=16

# 將數(shù)據(jù)處理成model可讀入的數(shù)據(jù)格式
trans_func = partial(
    convert_example,
    tokenizer=tokenizer,
    max_seq_length=max_seq_length)
# 將數(shù)據(jù)組成批量式數(shù)據(jù),如
# 將不同長度的文本序列padding到批量式數(shù)據(jù)中最大長度
# 將每條數(shù)據(jù)label堆疊在一起
batchify_fn = lambda samples, fn=Tuple(
    Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input_ids
    Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # token_type_ids
    Stack(dtype="int64")  # labels
): [data for data in fn(samples)]
train_data_loader = create_dataloader(
    train_ds,
    mode='train',
    batch_size=batch_size,
    batchify_fn=batchify_fn,
    trans_fn=trans_func)

模型訓練

定義損失函數(shù)、優(yōu)化器以及評價指標后,即可開始訓練。

# 訓練輪次
epochs = 3
# 總共需要訓練的step數(shù)
num_training_steps = len(train_data_loader) * epochs
# 優(yōu)化器
optimizer = paddle.optimizer.AdamW(
    learning_rate=5e-5,
    parameters=model.parameters())
# 交叉熵損失
criterion = paddle.nn.loss.CrossEntropyLoss()
# Accuracy評價指標
metric = paddle.metric.Accuracy()
# 開啟訓練
ckpt_dir = "skep_aspect"
global_step = 0
tic_train = time.time()
for epoch in range(1, epochs + 1):
    for step, batch in enumerate(train_data_loader, start=1):
        input_ids, token_type_ids, labels = batch
        # 喂數(shù)據(jù)給model
        logits = model(input_ids, token_type_ids)
        # 計算損失函數(shù)值
        loss = criterion(logits, labels)
        # 預測分類概率
        probs = F.softmax(logits, axis=1)
        # 計算acc
        correct = metric.compute(probs, labels)
        metric.update(correct)
        acc = metric.accumulate()

        global_step += 1
        if global_step % 10 == 0:
            print(
                "global step %d, epoch: %d, batch: %d, loss: %.5f, acc: %.5f, speed: %.2f step/s"
                % (global_step, epoch, step, loss, acc,
                    10 / (time.time() - tic_train)))
            tic_train = time.time()
        
        # 反向梯度回傳,更新參數(shù)
        loss.backward()
        optimizer.step()
        optimizer.clear_grad()

        if global_step % 100 == 0:
            
            save_dir = os.path.join(ckpt_dir, "model_%d" % global_step)
            if not os.path.exists(save_dir):
                os.makedirs(save_dir)
            # 保存模型參數(shù)
            model.save_pretrained(save_dir)
            # 保存tokenizer的詞表等
            tokenizer.save_pretrained(save_dir)

預測提交結(jié)果

使用訓練得到的模型還可以對評價對象進行情感預測。

@paddle.no_grad()
def predict(model, data_loader, label_map):
    """
    Given a prediction dataset, it gives the prediction results.

    Args:
        model(obj:`paddle.nn.Layer`): A model to classify texts.
        data_loader(obj:`paddle.io.DataLoader`): The dataset loader which generates batches.
        label_map(obj:`dict`): The label id (key) to label str (value) map.
    """
    model.eval()
    results = []
    for batch in data_loader:
        input_ids, token_type_ids = batch
        logits = model(input_ids, token_type_ids)
        probs = F.softmax(logits, axis=1)
        idx = paddle.argmax(probs, axis=1).numpy()
        idx = idx.tolist()
        labels = [label_map[i] for i in idx]
        results.extend(labels)
    return results
# 處理測試集數(shù)據(jù)
label_map = {0: '0', 1: '1'}
trans_func = partial(
    convert_example,
    tokenizer=tokenizer,
    max_seq_length=max_seq_length,
    is_test=True)
batchify_fn = lambda samples, fn=Tuple(
    Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input_ids
    Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # token_type_ids
): [data for data in fn(samples)]
test_data_loader = create_dataloader(
    test_ds,
    mode='test',
    batch_size=batch_size,
    batchify_fn=batchify_fn,
    trans_fn=trans_func)
# 根據(jù)實際運行情況,更換加載的參數(shù)路徑
params_path = 'skep_ckpt/model_900/model_state.pdparams'
if params_path and os.path.isfile(params_path):
    # 加載模型參數(shù)
    state_dict = paddle.load(params_path)
    model.set_dict(state_dict)
    print("Loaded parameters from %s" % params_path)

results = predict(model, test_data_loader, label_map)
# 寫入預測結(jié)果
with open(os.path.join("results", "SE-ABSA16_PHNS.tsv"), 'w', encoding="utf8") as f:
    f.write("index\tprediction\n")
    for idx, label in enumerate(results):
        f.write(str(idx)+"\t"+label+"\n")

視頻:https://aistudio.baidu.com/aistudio/course/introduce/24177?sharedLesson=1470935&sharedType=2&sharedUserId=2631487&ts=1686280983462

實踐:https://aistudio.baidu.com/aistudio/projectdetail/6357403?forkThirdPart=1&sUid=2631487&shared=1&ts=1686280956584文章來源地址http://www.zghlxwxcb.cn/news/detail-493700.html

到了這里,關于自然語言處理 Paddle NLP - 情感分析技術及應用SKEP-實踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 自然語言處理 Paddle NLP - 機器同傳技術及應用-理論

    自然語言處理 Paddle NLP - 機器同傳技術及應用-理論

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月11日
    瀏覽(25)
  • 自然語言處理 Paddle NLP - 預訓練語言模型及應用

    自然語言處理 Paddle NLP - 預訓練語言模型及應用

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月08日
    瀏覽(30)
  • 自然語言處理 Paddle NLP - 詞向量應用展示

    自然語言處理 Paddle NLP - 詞向量應用展示

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月08日
    瀏覽(25)
  • 自然語言處理 Paddle NLP - 任務式對話系統(tǒng)-理論

    自然語言處理 Paddle NLP - 任務式對話系統(tǒng)-理論

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月11日
    瀏覽(28)
  • 自然語言處理 Paddle NLP - 檢索式文本問答-理論

    自然語言處理 Paddle NLP - 檢索式文本問答-理論

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月11日
    瀏覽(26)
  • 自然語言處理 Paddle NLP - 開放域?qū)υ捪到y(tǒng)-理論

    自然語言處理 Paddle NLP - 開放域?qū)υ捪到y(tǒng)-理論

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月11日
    瀏覽(45)
  • 自然語言處理 Paddle NLP - 結(jié)構化數(shù)據(jù)問答-理論

    自然語言處理 Paddle NLP - 結(jié)構化數(shù)據(jù)問答-理論

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月11日
    瀏覽(27)
  • 【自然語言處理(NLP)】基于循環(huán)神經(jīng)網(wǎng)絡實現(xiàn)情感分類

    【自然語言處理(NLP)】基于循環(huán)神經(jīng)網(wǎng)絡實現(xiàn)情感分類

    活動地址:[CSDN21天學習挑戰(zhàn)賽](https://marketing.csdn.net/p/bdabfb52c5d56532133df2adc1a728fd) 作者簡介 :在校大學生一枚,華為云享專家,阿里云星級博主,騰云先鋒(TDP)成員,云曦智劃項目總負責人,全國高等學校計算機教學與產(chǎn)業(yè)實踐資源建設專家委員會(TIPCC)志愿者,以及編程

    2024年02月07日
    瀏覽(26)
  • 自然語言處理 Paddle NLP - 基于預訓練模型完成實體關系抽取

    自然語言處理 Paddle NLP - 基于預訓練模型完成實體關系抽取

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月10日
    瀏覽(24)
  • 自然語言處理 Paddle NLP - 快遞單信息抽取 (ERNIE 1.0)

    自然語言處理 Paddle NLP - 快遞單信息抽取 (ERNIE 1.0)

    基礎 自然語言處理(NLP) 自然語言處理PaddleNLP-詞向量應用展示 自然語言處理(NLP)-前預訓練時代的自監(jiān)督學習 自然語言處理PaddleNLP-預訓練語言模型及應用 自然語言處理PaddleNLP-文本語義相似度計算(ERNIE-Gram) 自然語言處理PaddleNLP-詞法分析技術及其應用 自然語言處理Pa

    2024年02月09日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包