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

[oneAPI] 基于BERT預(yù)訓(xùn)練模型的命名體識別任務(wù)

這篇具有很好參考價值的文章主要介紹了[oneAPI] 基于BERT預(yù)訓(xùn)練模型的命名體識別任務(wù)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

比賽:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517
Intel? DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/

Intel? DevCloud for oneAPI 和 Intel? Optimization for PyTorch

在本次實(shí)驗(yàn)中,我們在Intel? DevCloud for oneAPI上搭建實(shí)驗(yàn),借助完全虛擬化的環(huán)境,專注于模型開發(fā)與優(yōu)化,無需關(guān)心底層配置。使用Intel? Optimization for PyTorch,對PyTorch模型進(jìn)行高效優(yōu)化。

我們充分發(fā)揮了PyTorch和Intel? Optimization for PyTorch的強(qiáng)大功能,經(jīng)過仔細(xì)的優(yōu)化和拓展。這些優(yōu)化措施極大地提升了PyTorch在各種任務(wù)中的性能,尤其是在英特爾硬件上的表現(xiàn)更為卓越。通過這些優(yōu)化方法,我們的模型在訓(xùn)練和推斷過程中變得更加敏捷高效,大幅縮短了計算時間,從而提升了整體效率。借助深度融合硬件與軟件的巧妙設(shè)計,我們成功地釋放了硬件潛力,使模型的訓(xùn)練和應(yīng)用變得更加迅速高效。這些優(yōu)化舉措為人工智能應(yīng)用開辟了嶄新的前景,帶來了全新的可能性。
[oneAPI] 基于BERT預(yù)訓(xùn)練模型的命名體識別任務(wù),python雜記,oneapi,bert,人工智能

基于BERT預(yù)訓(xùn)練模型的命名體識別任務(wù)

基于BERT預(yù)訓(xùn)練模型的第五個下游任務(wù)場景,即如何完成命名體識別(Named Entity Recognition, NER)任務(wù)。所謂命名體指的是給模型輸入一句文本,最后需要模型將其中的實(shí)體(例如人名、地名、組織等等)標(biāo)記出來。

1 句子:涂伊說,如果有機(jī)會他想去黃州赤壁看一看!
2 標(biāo)簽:['B-PER', 'I-PER', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'B-LOC', 'I-LOC', 'B-LOC', 'I-LOC', 'O', 'O', 'O', 'O']
3 實(shí)體:涂伊(人名)、黃州(地名)、赤壁(地名)

通常來講,對于任意一個NLP任務(wù)來說模型最后所要完成的基本上都是一個分類任務(wù),盡管表面上看起來可能不太像。根據(jù)給出的標(biāo)簽來看,對于原始句子中的每個字符來說其都有一個對應(yīng)的類別標(biāo)簽,因此對于NER任務(wù)來說只需要對原始句子里的每個字符進(jìn)行分類即可,然后再將預(yù)測后的結(jié)果進(jìn)行后處理便能夠得到句子從存在的相應(yīng)實(shí)體。

原始數(shù)據(jù)輸入為一個句子,我們只需要在句子的首尾分別加上[CLS]和[SEP],然后輸入到模型當(dāng)中進(jìn)行特征提取并最終通過一個分類層對輸出的每個Token進(jìn)行分類即可,最后只需要對各個Token的預(yù)測結(jié)果進(jìn)行后處理便能夠?qū)崿F(xiàn)整個NER任務(wù)。

語料介紹

一個中文命名體識別數(shù)據(jù)集https://github.com/zjy-ucas/ChineseNER,如下所示便是原始數(shù)據(jù)的存儲形式:

 1 涂 B-PER
 2 伊 I-PER
 3 說 O
 4 , O
 5 如 O
 6 果 O
 7 有 O
 8 機(jī) O
 9 會 O
10 他 O
11 想 O
12 去 O
13 黃 B-LOC
14 州 I-LOC
15 赤 B-LOC
16 壁 I-LOC
17 看 O
18 一 O
19 看 O
20 !O

其中每一行包含一個字符和其對應(yīng)的所屬類別,B-表示該類實(shí)體的開始標(biāo)志,I-表示該類實(shí)體的延續(xù)標(biāo)志。例如對于13-16行來說其對應(yīng)了“黃州”和“赤壁”這兩個實(shí)體。同時,對于這個數(shù)據(jù)集來說,其一共包含有3類實(shí)體(人名、地名和組織),因此其對應(yīng)的分類總數(shù)便為7,如下所示:

1 {'O': 0, 'B-ORG': 1, 'B-LOC': 2, 'B-PER': 3, 'I-ORG': 4, 'I-LOC': 5, 'I-PER': 6}

對于數(shù)據(jù)預(yù)處理部分我們可以繼續(xù)繼承之前文本分類處理中的LoadSingleSentenceClassificationDataset類,然后再稍微修改其中的部分方法即可。

數(shù)據(jù)集構(gòu)建

在說完數(shù)據(jù)集構(gòu)造的整理思路后,下面我們就來正式編碼實(shí)現(xiàn)整個數(shù)據(jù)集的構(gòu)造過程。同樣,對于數(shù)據(jù)預(yù)處理部分我們可以繼續(xù)繼承之前文本分類處理中的LoadSingleSentenceClassificationDataset類,然后再稍微修改其中的部分方法即可。

class LoadChineseNERDataset(LoadSingleSentenceClassificationDataset):
    def __init__(self, entities=None, num_labels=None, ignore_idx=-100, **kwargs):
        super(LoadChineseNERDataset, self).__init__(**kwargs)
        self.entities = entities
        self.num_labels = num_labels
        self.IGNORE_IDX = ignore_idx
        if self.entities is None or self.num_labels is None:
            raise ValueError(f"類 {self.__class__.__name__} 中參數(shù) entities 或 num_labels 不能為空!")

    @cache
    def data_process(self, filepath, postfix='cache'):
        raw_iter = open(filepath, encoding="utf8").readlines()
        data = []
        max_len = 0
        tmp_token_ids = []
        tmp_sentence = ""
        tmp_label = []
        tmp_entity = []
        for raw in tqdm(raw_iter, ncols=80):
            line = raw.rstrip("\n").split(self.split_sep)
            if len(line) != 1 and len(line) != 2:
                raise ValueError(f"數(shù)據(jù)標(biāo)注有誤{line}")
            if len(line) == 1:  # 表示得到一個完整的token id樣本
                if len(tmp_token_ids) > self.max_position_embeddings - 2:
                    tmp_token_ids = tmp_token_ids[:self.max_position_embeddings - 2]
                    tmp_label = tmp_label[:self.max_position_embeddings - 2]
                max_len = max(max_len, len(tmp_label) + 2)
                token_ids = torch.tensor([self.CLS_IDX] + tmp_token_ids +
                                         [self.SEP_IDX], dtype=torch.long)
                labels = torch.tensor([self.IGNORE_IDX] + tmp_label +
                                      [self.IGNORE_IDX], dtype=torch.long)
                data.append([tmp_sentence, token_ids, labels])

                logging.debug(" ### 樣本構(gòu)造結(jié)果為:")
                logging.debug(f"   ## 句子: {tmp_sentence}")
                logging.debug(f"   ## 實(shí)體: {tmp_entity}")
                logging.debug(f"   ## input_ids: {token_ids.tolist()}")
                logging.debug(f"   ## label: {labels.tolist()}")
                logging.debug(f" ================================\n")
                assert len(tmp_token_ids) == len(tmp_label)
                tmp_token_ids = []
                tmp_sentence = ""
                tmp_label = []
                tmp_entity = []
                continue
            tmp_sentence += line[0]
            tmp_token_ids.append(self.vocab[line[0]])
            tmp_label.append(self.entities[line[-1]])
            tmp_entity.append(line[-1])
        return data, max_len

    def generate_batch(self, data_batch):
        batch_sentence, batch_token_ids, batch_label = [], [], []
        for (sen, token_ids, label) in data_batch:  # 開始對一個batch中的每一個樣本進(jìn)行處理。
            batch_sentence.append(sen)
            batch_token_ids.append(token_ids)
            batch_label.append(label)
        batch_token_ids = pad_sequence(batch_token_ids,  # [batch_size,max_len]
                                       padding_value=self.PAD_IDX,
                                       batch_first=False,
                                       max_len=self.max_sen_len)
        batch_label = pad_sequence(batch_label,  # [batch_size,max_len]
                                   padding_value=self.IGNORE_IDX,
                                   batch_first=False,
                                   max_len=self.max_sen_len)
        # ① 因?yàn)閘abel的長度各不相同,所以同一個batch中的label需要padding到相同的長度;
        # ② 因?yàn)檫M(jìn)行了padding操作,所以在計算損失的時候需要把padding部分的損失忽略掉;
        # ③ 又因?yàn)閘abel中有0這個類別的存在,所以不能用詞表中的PAD_IDX進(jìn)行padding(PAD_IDX為0),所以要另外取一個IGNORE_IDX
        return batch_sentence, batch_token_ids, batch_label

    def make_inference_samples(self, sentences):
        if not isinstance(sentences, list):
            sentences = [sentences]
        data = []
        for sen in sentences:
            tokens = [self.vocab[word] for word in sen]
            label = [-1] * len(tokens)
            token_ids = torch.tensor([self.CLS_IDX] + tokens + [self.SEP_IDX], dtype=torch.long)
            labels = torch.tensor([self.IGNORE_IDX] + label + [self.IGNORE_IDX], dtype=torch.long)
            data.append([sen, token_ids, labels])
        return self.generate_batch(data)

使用示例

在完成數(shù)據(jù)集構(gòu)造部分的相關(guān)代碼實(shí)現(xiàn)之后,便可以通過如下所示的方式進(jìn)行使用,代碼如下:

class ModelConfig:
    def __init__(self):
        self.project_dir = os.path.dirname(os.path.abspath(__file__))
        self.dataset_dir = os.path.join(self.project_dir, 'ChineseNERdata')
        self.pretrained_model_dir = os.path.join(self.project_dir, "pretraining")
        self.vocab_path = os.path.join(self.pretrained_model_dir, 'vocab.txt')
        self.device = torch.device('xpu' if torch.cuda.is_available() else 'cpu')
        self.train_file_path = os.path.join(self.dataset_dir, 'example_train.txt')
        self.val_file_path = os.path.join(self.dataset_dir, 'example_dev.txt')
        self.test_file_path = os.path.join(self.dataset_dir, 'example_test.txt')
        self.model_save_dir = os.path.join(self.project_dir, 'cache')
        self.model_save_name = "ner_model.pt"
        self.logs_save_dir = os.path.join(self.project_dir, 'logs')
        self.split_sep = ' '
        self.is_sample_shuffle = True
        self.batch_size = 6
        self.max_sen_len = None
        self.epochs = 10
        self.learning_rate = 1e-5
        self.model_val_per_epoch = 2
        self.entities = {'O': 0, 'B-ORG': 1, 'B-LOC': 2, 'B-PER': 3, 'I-ORG': 4, 'I-LOC': 5, 'I-PER': 6}
        self.num_labels = len(self.entities)
        self.ignore_idx = -100
        logger_init(log_file_name='ner', log_level=logging.DEBUG,
                    log_dir=self.logs_save_dir)
        if not os.path.exists(self.model_save_dir):
            os.makedirs(self.model_save_dir)

        # 把原始bert中的配置參數(shù)也導(dǎo)入進(jìn)來
        bert_config_path = os.path.join(self.pretrained_model_dir, "config.json")
        bert_config = BertConfig.from_json_file(bert_config_path)
        for key, value in bert_config.__dict__.items():
            self.__dict__[key] = value
        # 將當(dāng)前配置打印到日志文件中
        logging.info(" ### 將當(dāng)前配置打印到日志文件中 ")
        for key, value in self.__dict__.items():
            logging.info(f"###  {key} = {value}")

命名體識別模型

前向傳播

我們只需要在原始BERT模型的基礎(chǔ)上再加一個對所有Token進(jìn)行分類的分類層即可,因此這部分代碼相對來說也比較容易理解。首先需要在DownstreamTasks目錄下新建一個BertForTokenClassification模塊,并完成整個模型的初始化和前向傳播過程,代碼如下:

from ..BasicBert.Bert import BertModel
import torch.nn as nn


class BertForTokenClassification(nn.Module):
    def __init__(self, config, bert_pretrained_model_dir=None):
        super(BertForTokenClassification, self).__init__()
        self.num_labels = config.num_labels
        if bert_pretrained_model_dir is not None:
            self.bert = BertModel.from_pretrained(config, bert_pretrained_model_dir)
        else:
            self.bert = BertModel(config)
        self.dropout = nn.Dropout(config.hidden_dropout_prob)
        self.classifier = nn.Linear(config.hidden_size, self.num_labels)
        self.config = config

    def forward(self,
                input_ids=None,
                attention_mask=None,
                token_type_ids=None,
                position_ids=None,
                labels=None):
        """
        :param input_ids: [src_len,batch_size]
        :param attention_mask: [batch_size, src_len]
        :param token_type_ids:
        :param position_ids:
        :param labels: [src_len,batch_size]
        :return:
        """

        _, all_encoder_outputs = self.bert(input_ids=input_ids,
                                           attention_mask=attention_mask,
                                           token_type_ids=token_type_ids,
                                           position_ids=position_ids)  # [batch_size,hidden_size]
        sequence_output = all_encoder_outputs[-1]  # 取最后一層
        # sequence_output: [src_len, batch_size, hidden_size]
        sequence_output = self.dropout(sequence_output)
        logits = self.classifier(sequence_output)
        # logit: [src_len, batch_size, num_labels]
        if labels is not None:  # [src_len,batch_size]
            loss_fct = nn.CrossEntropyLoss(ignore_index=self.config.ignore_idx)
            loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
            return loss, logits
        else:
            return logits

模型訓(xùn)練

對于模型訓(xùn)練這部分內(nèi)容來說,首先我們需要在Tasks目錄下新建一個TaskForChineseNER.py模塊,并新建一個配置類ModelConfig來管理整個模型需要用到的參數(shù),代碼實(shí)現(xiàn)如下:

class ModelConfig:
    def __init__(self):
        self.project_dir = os.path.dirname(os.path.abspath(__file__))
        self.dataset_dir = os.path.join(self.project_dir, 'ChineseNERdata')
        self.pretrained_model_dir = os.path.join(self.project_dir, "pretraining")
        self.vocab_path = os.path.join(self.pretrained_model_dir, 'vocab.txt')
        self.device = torch.device('xpu' if torch.cuda.is_available() else 'cpu')
        self.train_file_path = os.path.join(self.dataset_dir, 'example_train.txt')
        self.val_file_path = os.path.join(self.dataset_dir, 'example_dev.txt')
        self.test_file_path = os.path.join(self.dataset_dir, 'example_test.txt')
        self.model_save_dir = os.path.join(self.project_dir, 'cache')
        self.model_save_name = "ner_model.pt"
        self.logs_save_dir = os.path.join(self.project_dir, 'logs')
        self.split_sep = ' '
        self.is_sample_shuffle = True
        self.batch_size = 6
        self.max_sen_len = None
        self.epochs = 10
        self.learning_rate = 1e-5
        self.model_val_per_epoch = 2
        self.entities = {'O': 0, 'B-ORG': 1, 'B-LOC': 2, 'B-PER': 3, 'I-ORG': 4, 'I-LOC': 5, 'I-PER': 6}
        self.num_labels = len(self.entities)
        self.ignore_idx = -100
        logger_init(log_file_name='ner', log_level=logging.DEBUG,
                    log_dir=self.logs_save_dir)
        if not os.path.exists(self.model_save_dir):
            os.makedirs(self.model_save_dir)

        # 把原始bert中的配置參數(shù)也導(dǎo)入進(jìn)來
        bert_config_path = os.path.join(self.pretrained_model_dir, "config.json")
        bert_config = BertConfig.from_json_file(bert_config_path)
        for key, value in bert_config.__dict__.items():
            self.__dict__[key] = value
        # 將當(dāng)前配置打印到日志文件中
        logging.info(" ### 將當(dāng)前配置打印到日志文件中 ")
        for key, value in self.__dict__.items():
            logging.info(f"###  {key} = {value}")

因?yàn)樵谀P陀?xùn)練過程中需要計算相關(guān)的評價指標(biāo),如準(zhǔn)確率、精確率和召回率等,因此需要對這部分進(jìn)行實(shí)現(xiàn),代碼如下

def accuracy(logits, y_true, ignore_idx=-100):
    """
    :param logits:  [src_len,batch_size,num_labels]
    :param y_true:  [src_len,batch_size]
    :param ignore_idx: 默認(rèn)情況為-100
    :return:
    e.g.
    y_true = torch.tensor([[-100, 0, 0, 1, -100],
                       [-100, 2, 0, -100, -100]]).transpose(0, 1)
    logits = torch.tensor([[[0.5, 0.1, 0.2], [0.5, 0.4, 0.1], [0.7, 0.2, 0.3], [0.5, 0.7, 0.2], [0.1, 0.2, 0.5]],
                           [[0.3, 0.2, 0.5], [0.7, 0.2, 0.4], [0.8, 0.1, 0.3], [0.9, 0.2, 0.1], [0.1, 0.5, 0.2]]])
    logits = logits.transpose(0, 1)
    print(accuracy(logits, y_true, -100)) # (0.8, 4, 5)
    """
    y_pred = logits.transpose(0, 1).argmax(axis=2).reshape(-1).tolist()
    # 將 [src_len,batch_size,num_labels] 轉(zhuǎn)成 [batch_size, src_len,num_labels]
    y_true = y_true.transpose(0, 1).reshape(-1).tolist()
    real_pred, real_true = [], []
    for item in zip(y_pred, y_true):
        if item[1] != ignore_idx:
            real_pred.append(item[0])
            real_true.append(item[1])
    return accuracy_score(real_true, real_pred), real_true, real_pred

為了能夠在模型訓(xùn)練或推理過程中輸入模型的預(yù)測結(jié)果,因此我們需要實(shí)現(xiàn)3個輔助函數(shù)來完成。首先需要實(shí)現(xiàn)根據(jù)logits和input_token_ids來得到每個預(yù)測值對應(yīng)的實(shí)體標(biāo)簽,代碼如下:

def get_ner_tags(logits, token_ids, entities, SEP_IDX=102):
    """
    :param logits:  [src_len,batch_size,num_samples]
    :param token_ids: # [src_len,batch_size]
    :return:
    e.g.
    logits = torch.tensor([[[0.4, 0.7, 0.2],[0.5, 0.4, 0.1],[0.1, 0.2, 0.3],[0.5, 0.7, 0.2],[0.1, 0.2, 0.5]],
                       [[0.3, 0.2, 0.5],[0.7, 0.8, 0.4],[0.1, 0.1, 0.3],[0.9, 0.2, 0.1],[0.1, 0.5,0.2]]])
    logits = logits.transpose(0, 1)  # [src_len,batch_size,num_samples]
    token_ids = torch.tensor([[101, 2769, 511, 102, 0],
                              [101, 56, 33, 22, 102]]).transpose(0, 1)  # [src_len,batch_size]
    labels, probs = get_ner_tags(logits, token_ids, entities)
    [['O', 'B-LOC'], ['B-ORG', 'B-LOC', 'O']]
    [[0.5, 0.30000001192092896], [0.800000011920929, 0.30000001192092896, 0.8999999761581421]]
    """
    # entities = {'O': 0, 'B-ORG': 1, 'B-LOC': 2, 'B-PER': 3, 'I-ORG': 4, 'I-LOC': 5, 'I-PER': 6}
    label_list = list(entities.keys())
    logits = logits[1:].transpose(0, 1)  # [batch_size,src_len-1,num_samples]
    prob, y_pred = torch.max(logits, dim=-1)  # prob, y_pred: [batch_size,src_len-1]
    token_ids = token_ids[1:].transpose(0, 1)  # [ batch_size,src_len-1], 去掉[cls]
    assert y_pred.shape == token_ids.shape
    labels = []
    probs = []
    for sample in zip(y_pred, token_ids, prob):
        tmp_label, tmp_prob = [], []
        for item in zip(*sample):
            if item[1] == SEP_IDX:  # 忽略最后一個[SEP]字符
                break
            tmp_label.append(label_list[item[0]])
            tmp_prob.append(item[2].item())
        labels.append(tmp_label)
        probs.append(tmp_prob)
    return labels, probs

進(jìn)一步,在得到每個輸入句子的預(yù)測結(jié)果后,還需要將其進(jìn)行格式化處理得到最終的預(yù)測結(jié)果,實(shí)現(xiàn)代碼如下:

def pretty_print(sentences, labels, entities):
    """
    :param sentences:
    :param labels:
    :param entities:
    :return:
    e.g.
    labels = [['B-PER','I-PER', 'O','O','O','O','O','O','O','O','O','O','B-LOC','I-LOC','B-LOC','I-LOC','O','O','O','O'],
    ['B-LOC','I-LOC','O','B-LOC','I-LOC','O','B-LOC','I-LOC','I-LOC','O','B-LOC','I-LOC','O','O','O','B-PER','I-PER','O','O','O','O','O','O']]
    sentences=["涂伊說,如果有機(jī)會他想去赤壁看一看!",
               "麗江、大理、九寨溝、黃龍等都是涂伊想去的地方!"]
    entities = {'O': 0, 'B-ORG': 1, 'B-LOC': 2, 'B-PER': 3, 'I-ORG': 4, 'I-LOC': 5, 'I-PER': 6}


    句子:涂伊說,如果有機(jī)會他想去黃州赤壁看一看!
    涂伊:  PER
    黃州:  LOC
    赤壁:  LOC
    句子:麗江、大理、九寨溝、黃龍等都是涂伊想去的地方!
    麗江:  LOC
    大理:  LOC
    九寨溝:  LOC
    黃龍:  LOC
    涂伊:  PER
    """

    sep_tag = [tag for tag in list(entities.keys()) if 'I' not in tag]
    result = []
    for sen, label in zip(sentences, labels):
        logging.info(f"句子:{sen}")
        last_tag = None
        for item in zip(sen + "O", label + ['O']):
            if item[1] in sep_tag:  #
                if len(result) > 0:
                    entity = "".join(result)
                    logging.info(f"\t{entity}:  {last_tag.split('-')[-1]}")
                    result = []
                if item[1] != 'O':
                    result.append(item[0])
                    last_tag = item[1]
            else:
                result.append(item[0])
                last_tag = item[1]

輸出結(jié)果如下:

1 句子:涂伊說,如果有機(jī)會他想去黃州赤壁看一看!
 2 涂伊:  PER
 3 黃州:  LOC
 4 赤壁:  LOC
 5 句子:麗江、大理、九寨溝、黃龍等都是涂伊想去的地方!
 6 麗江:  LOC
 7 大理:  LOC
 8 九寨溝:  LOC
 9 黃龍:  LOC
10 涂伊:  PER

在完成上述所有鋪墊之后,便可以來實(shí)現(xiàn)模型的訓(xùn)練部分,代碼如下(下面只摘錄核心部分進(jìn)行介紹):

def train(config):
    model = BertForTokenClassification(config,
                                       config.pretrained_model_dir)
    model_save_path = os.path.join(config.model_save_dir,
                                   config.model_save_name)
    global_steps = 0
    if os.path.exists(model_save_path):
        checkpoint = torch.load(model_save_path)
        global_steps = checkpoint['last_epoch']
        loaded_paras = checkpoint['model_state_dict']
        model.load_state_dict(loaded_paras)
        logging.info("## 成功載入已有模型,進(jìn)行追加訓(xùn)練......")

    model = model.to(config.device)
    optimizer = torch.optim.Adam(model.parameters(), lr=config.learning_rate)

    '''
    Apply Intel Extension for PyTorch optimization against the model object and optimizer object.
    '''
    model, optimizer = ipex.optimize(model, optimizer=optimizer)

    model.train()

    data_loader = LoadChineseNERDataset(
        entities=config.entities,
        num_labels=config.num_labels,
        ignore_idx=config.ignore_idx,
        vocab_path=config.vocab_path,
        tokenizer=BertTokenizer.from_pretrained(
            config.pretrained_model_dir).tokenize,
        batch_size=config.batch_size,
        max_sen_len=config.max_sen_len,
        split_sep=config.split_sep,
        max_position_embeddings=config.max_position_embeddings,
        pad_index=config.pad_token_id,
        is_sample_shuffle=config.is_sample_shuffle)
    train_iter, test_iter, val_iter = \
        data_loader.load_train_val_test_data(train_file_path=config.train_file_path,
                                             val_file_path=config.val_file_path,
                                             test_file_path=config.test_file_path,
                                             only_test=False)

    max_acc = 0
    for epoch in range(config.epochs):
        losses = 0
        start_time = time.time()
        for idx, (sen, token_ids, labels) in enumerate(train_iter):
            token_ids = token_ids.to(config.device)
            labels = labels.to(config.device)
            padding_mask = (token_ids == data_loader.PAD_IDX).transpose(0, 1)
            loss, logits = model(input_ids=token_ids,  # [src_len, batch_size]
                                 attention_mask=padding_mask,  # [batch_size,src_len]
                                 token_type_ids=None,
                                 position_ids=None,
                                 labels=labels)  # [src_len, batch_size]
            # logit: [src_len, batch_size, num_labels]
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            losses += loss.item()
            global_steps += 1
            acc, _, _ = accuracy(logits, labels, config.ignore_idx)
            if idx % 20 == 0:
                logging.info(f"Epoch: {epoch}, Batch[{idx}/{len(train_iter)}], "
                             f"Train loss :{loss.item():.3f}, Train acc: {round(acc, 5)}")
            if idx % 100 == 0:
                show_result(sen[:10], logits[:, :10], token_ids[:, :10], config.entities)
        end_time = time.time()
        train_loss = losses / len(train_iter)
        logging.info(f"Epoch: [{epoch + 1}/{config.epochs}],"
                     f" Train loss: {train_loss:.3f}, Epoch time = {(end_time - start_time):.3f}s")
        if (epoch + 1) % config.model_val_per_epoch == 0:
            acc = evaluate(config, val_iter, model, data_loader)
            logging.info(f"Accuracy on val {acc:.3f}")
            if acc > max_acc:
                max_acc = acc
                state_dict = deepcopy(model.state_dict())
                torch.save({'last_epoch': global_steps,
                            'model_state_dict': state_dict},
                           model_save_path)

結(jié)果

[oneAPI] 基于BERT預(yù)訓(xùn)練模型的命名體識別任務(wù),python雜記,oneapi,bert,人工智能

[oneAPI] 基于BERT預(yù)訓(xùn)練模型的命名體識別任務(wù),python雜記,oneapi,bert,人工智能

參考資料

基于BERT預(yù)訓(xùn)練模型的中文文本分類任務(wù): https://mp.weixin.qq.com/s/bbeN95mlLaE05dFndUAxgA文章來源地址http://www.zghlxwxcb.cn/news/detail-663158.html

到了這里,關(guān)于[oneAPI] 基于BERT預(yù)訓(xùn)練模型的命名體識別任務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 自然語言處理實(shí)戰(zhàn)項目8- BERT模型的搭建,訓(xùn)練BERT實(shí)現(xiàn)實(shí)體抽取識別的任務(wù)

    大家好,我是微學(xué)AI,今天給大家介紹一下自然語言處理實(shí)戰(zhàn)項目8- BERT模型的搭建,訓(xùn)練BERT實(shí)現(xiàn)實(shí)體抽取識別的任務(wù)。BERT模型是一種用于自然語言處理的深度學(xué)習(xí)模型,它可以通過訓(xùn)練來理解單詞之間的上下文關(guān)系,從而為下游任務(wù)提供高質(zhì)量的語言表示。它的結(jié)構(gòu)是由多

    2024年02月07日
    瀏覽(26)
  • 基于Bert+Attention+LSTM智能校園知識圖譜問答推薦系統(tǒng)——NLP自然語言處理算法應(yīng)用(含Python全部工程源碼及訓(xùn)練模型)+數(shù)據(jù)集

    基于Bert+Attention+LSTM智能校園知識圖譜問答推薦系統(tǒng)——NLP自然語言處理算法應(yīng)用(含Python全部工程源碼及訓(xùn)練模型)+數(shù)據(jù)集

    這個項目充分利用了Google的Bert模型,這是一種基于Attention的大規(guī)模語料預(yù)訓(xùn)練模型,以及LSTM命名實(shí)體識別網(wǎng)絡(luò)。項目的目標(biāo)是設(shè)計一套通用的問答系統(tǒng)處理邏輯,以實(shí)現(xiàn)智能問答任務(wù)。 首先,我們采用了Bert模型,這是一種在自然語言處理領(lǐng)域非常強(qiáng)大的預(yù)訓(xùn)練模型。它具備

    2024年02月09日
    瀏覽(39)
  • 在 Google Colab 中微調(diào)用于命名實(shí)體識別的 BERT 模型

    命名實(shí)體識別是自然語言處理(NLP)領(lǐng)域的一項主要任務(wù)。它用于檢測文本中的實(shí)體,以便在下游任務(wù)中進(jìn)一步使用,因?yàn)槟承┪谋?單詞對于給定上下文比其他文本/單詞更具信息性和重要性。這就是 NER 有時被稱為信息檢索的原因,即從文本中提取相關(guān)并將其分類為所

    2024年02月11日
    瀏覽(19)
  • [oneAPI] 使用Bert進(jìn)行中文文本分類

    [oneAPI] 使用Bert進(jìn)行中文文本分類

    比賽:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel? DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ 在本次實(shí)驗(yàn)中,我們利用PyTorch和Intel? Optimization for PyTorch的強(qiáng)大功能,對PyTorch進(jìn)行了精心的優(yōu)化和擴(kuò)展。這些優(yōu)化舉措極大地增強(qiáng)了PyTorch在各

    2024年02月12日
    瀏覽(27)
  • 基于OpenCV的人臉識別和模型訓(xùn)練系統(tǒng)(萬字詳解)

    基于OpenCV的人臉識別和模型訓(xùn)練系統(tǒng)(萬字詳解)

    我們身邊的人臉識別有車站檢票,監(jiān)控人臉,無人超市,支付寶人臉支付,上班打卡,人臉解鎖手機(jī)。? 人臉檢測是人臉識別系統(tǒng)組成的關(guān)鍵部分之一,其目的是檢測出任意給定圖片中的包含的一個或多個人臉,是人臉識別、表情識別等下游任務(wù)的基礎(chǔ)。人臉識別是通過采集

    2024年02月12日
    瀏覽(24)
  • 036中藥飲片識別小程序python卷積網(wǎng)絡(luò)訓(xùn)練模型識別

    036中藥飲片識別小程序python卷積網(wǎng)絡(luò)訓(xùn)練模型識別

    代碼下載和視頻演示地址: 036-037基于深度學(xué)習(xí)識別中藥飲片小程序_嗶哩嗶哩_bilibili ? ?完整的文件展示如下: ? 算法部分? ? 其中中藥飲片數(shù)據(jù)集文件夾下存放的圖像數(shù)據(jù)集。 運(yùn)行01訓(xùn)練數(shù)據(jù)集文本生成.py會將數(shù)據(jù)集圖片路徑帶上標(biāo)簽保存在txt文本中。 運(yùn)行02train.py會將

    2024年04月12日
    瀏覽(18)
  • 【深度學(xué)習(xí)】預(yù)訓(xùn)練語言模型-BERT

    【深度學(xué)習(xí)】預(yù)訓(xùn)練語言模型-BERT

    ????????BERT 是一種預(yù)訓(xùn)練語言模型(pre-trained language model, PLM),其全稱是Bidirectional Encoder Representations from Transformers。下面從語言模型和預(yù)訓(xùn)練開始展開對預(yù)訓(xùn)練語言模型BERT的介紹。 1-1 語言模型 ????????語言模型 :對于任意的詞序列,它能夠計算出這個序列是一句

    2023年04月08日
    瀏覽(36)
  • BERT數(shù)據(jù)處理,模型,預(yù)訓(xùn)練

    首先讀取文本,每個文本必須包含兩個以上句子(為了第二個預(yù)訓(xùn)練任務(wù):判斷兩個句子,是否連續(xù))。paragraphs 其中一部分結(jié)果如下所示 上述已經(jīng)將數(shù)據(jù)處理完,最后看一下處理后的例子: 隨后就是把處理好的數(shù)據(jù),送入bert中。在 BERTEncoder 中,執(zhí)行如下代碼: 將編碼完后

    2024年02月13日
    瀏覽(17)
  • 初步了解預(yù)訓(xùn)練語言模型BERT

    初步了解預(yù)訓(xùn)練語言模型BERT

    本文字?jǐn)?shù):: 4024 字 預(yù)計閱讀時間: 12 分鐘 BERT 是由Google提出的預(yù)訓(xùn)練語言模型,它基于 transformer 架構(gòu),被廣泛應(yīng)用于自然語言處理領(lǐng)域,是當(dāng)前自然語言處理領(lǐng)域最流行的預(yù)訓(xùn)練模型之一。而了解 BERT 需要先了解注意力機(jī)制與 Transformers 。 注意力機(jī)制 注意力機(jī)制(Atten

    2024年02月15日
    瀏覽(25)
  • 【預(yù)訓(xùn)練語言模型】 使用Transformers庫進(jìn)行BERT預(yù)訓(xùn)練

    【預(yù)訓(xùn)練語言模型】 使用Transformers庫進(jìn)行BERT預(yù)訓(xùn)練

    基于 HuggingFace的Transformer庫,在Colab或Kaggle進(jìn)行預(yù)訓(xùn)練。 鑒于算力限制,選用了較小的英文數(shù)據(jù)集wikitext-2 目的 :跑通Mask語言模型的預(yù)訓(xùn)練流程 注意:在Kaggle上訓(xùn)練時,最好將datasets更新到最新版(再重啟kernel),避免版本低報錯 colab和kaggle已經(jīng)預(yù)安裝transformers庫 加載數(shù)據(jù)

    2024年03月14日
    瀏覽(27)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包