学习笔记:深度学习(8)——基于PyTorch的BERT应用实践

学习时间:2022.04.26~2022.04.30

本节着重于将BERT模型应用到具体的实践当中,因此未来有很多可以优化的地方,比如自己重写dataset和dataloader方法,这样对于pytorch应该能有更好地、更灵活的运用。

7.1 工具选取

使用PyTorch框架应用Bert,一般是去Hugging Face(一个社区,有很多人会把训练好了的模型放在上面,可以支持PyTorch和Tenserflow)上,把Bert模型下载下来,然后再应用。

在应用具体模型之前,需要先安装一下Hugging Face提供的transformers库,因为它上面的模型都是基于这个transformers库来编写的,即使下载了模型也要通过这个库来使用。(这个是必要的)

pip install transformers

此外,数据处理部分,如果不想自己重写dataset和dataloader方法的话,Hugging Face也提供了datasets库,可以通过 pip install datasets来进行安装和使用。(这个是可选的)

7.2 文本预处理

这一部分主要参考了Kaggle上大神的代码,然后汇总了一下装进一个函数里了。以下简单举例:

def clean_data(data):
    punct_tag = re.compile(r'[^\w\s]')
    data = punct_tag.sub(r'', data)
    html_tag = re.compile(r'')
    data = html_tag.sub(r'', data)
    url_clean = re.compile(r"https://\S+|www\.\S+")
    data = url_clean.sub(r'', data)
    emoji_clean = re.compile("["
                             u"\U0001F600-\U0001F64F"
                             u"\U0001F300-\U0001F5FF"
                             u"\U0001F680-\U0001F6FF"
                             u"\U0001F1E0-\U0001F1FF"
                             u"\U00002702-\U000027B0"
                             u"\U000024C2-\U0001F251"
                             "]+", flags=re.UNICODE)
    data = emoji_clean.sub(r'', data)
    url_clean = re.compile(r"https://\S+|www\.\S+")
    data = url_clean.sub(r'', data)
    return data
def strip_possessives(text):
    text = text.replace("'s", '')
    text = text.replace(''s', '')
    text = text.replace("\'s", '')
    text = text.replace("\'s", '')
    return text
def clean_numbers(x):
    x = re.sub("[0-9]{5,}", '#####', x)
    x = re.sub("[0-9]{4}", '####', x)
    x = re.sub("[0-9]{3}", '###', x)
    x = re.sub("[0-9]{2}", '##', x)
    return x

最后通过一个函数全部调用:

def texts_preprogress(df):

    df = df.apply(lambda x: clean_data(x))
    df = df.apply(lambda x: expand_contractions(x))
    df = df.apply(lambda x: replace_typical_misspell(x))
    df = df.apply(lambda x: strip_possessives(x))
    df = df.apply(lambda x: replace_multi_exclamation_mark(x))
    df = df.apply(lambda x: clean_text(x))
    df = df.apply(lambda x: change_stopwords(x))
    df = df.apply(lambda x: clean_numbers(x))
    return df

7.3 使用BERT模型

整个使用分为5部分:数据输入及应用预处理、提取词向量、构建网络模型(嵌入BERT)、参数准备和模型训练。

个人本次使用的是 bert-base-uncased模型。


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)

train_df = pd.read_csv('train.csv', nrows=540)
train_df['question_text'] = texts_preprogress(train_df['question_text'])
eval_df = pd.read_csv('train.csv', nrows=675)[540:675]
eval_df['question_text'] = texts_preprogress(eval_df['question_text'])

⭐这里值得特别特别特别提一下的是: tokenizer函数中的 padding参数。

padding=True等价于 padding='max_length',只对于句子对任务起作用,会一样自动补全到batch中的最长长度;但是!!!对于单句的任务,两者并不等价!!!这也是我一开始设置了 padding=True,然后指定 max_length=72,最后输出的句子却依然长短不一,然后输不进网络的原因。

所以对于单句任务,一定要先指定 padding='max_length',然后再设置 max_length=,这样才会真正补全。


tokenizer = AutoTokenizer.from_pretrained('D:/Py-project/models/huggingface/bert-base-uncased/')

def tokenize_function(examples):
    return tokenizer(examples['question_text'], padding='max_length', max_length=72, truncation=True)

def batch_label(df):
    df = df.drop('qid', axis=1)
    dataset = Dataset.from_pandas(df)
    for k in dataset.column_names:
        if k == 'target':
            dataset = dataset.rename_column(k, 'labels')
    inputs = dataset.map(tokenize_function, batched=True)
    inputs.set_format(type='torch')
    inputs = inputs.remove_columns('question_text')
    dataloader = DataLoader(inputs, shuffle=True, batch_size=128)
    return dataloader

train_dl = batch_label(train_df)
eval_dl = batch_label(eval_df)

其实Bert也有直接提供一个训练好的bertclassification模型,但只能直接调用,不太好嵌入到网络,所以这里只用了bert模型,然后嵌入到了网络里面。

class my_bert(nn.Module):
    def __init__(self):
        super(my_bert, self).__init__()

        self.bert = BertModel.from_pretrained("D:/Py-project/models/huggingface/bert-base-uncased")

        for param in self.bert.parameters():
            param.requires_grad = True
        self.linear = torch.nn.Linear(768, 2)
        self.dropout = torch.nn.Dropout(0.5)

    def forward(self, x):

        input_ids = x['input_ids'].to(device)
        token_type_ids = x['token_type_ids'].to(device)
        attention_mask = x['attention_mask'].to(device)

        output = self.bert(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
        output = output['pooler_output']
        output = self.linear(output)
        output = self.dropout(output)
        output = torch.sigmoid(output)
        return output

seed = 42
if device == 'cuda':
    torch.cuda.manual_seed(seed)
else:
    torch.manual_seed(seed)

model = my_bert()
model.to(device)

lr = 2e-5
epoch = 2
show_step = 1
optimizer = optim.AdamW(model.parameters(), lr=lr)
criterion = nn.CrossEntropyLoss()

这里只涉及到一个小问题:如果数据集太大了,基本都需要转成dataloader后再分批输入网络进行训练和验证。

for i in range(epoch):
    model.train()
    losses = []
    accuracy = []
    start_time = time.time()

    for batch in tqdm(train_dl, desc=f'第{i+1}/{epoch}次迭代进度', ncols=100):
        pred = model(batch)
        label = batch['labels'].to(device)
        loss = criterion(pred, label)

        losses.append(loss.item())
        pred_labels = torch.argmax(pred, dim=1)
        acc = torch.sum(pred_labels == label).item() / len(pred_labels)
        accuracy.append(acc)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    if i % show_step == 0:
        model.eval()
        ev_losses = []
        ev_acc = []
        with torch.no_grad():
            for batch in eval_dl:
                ev_pred = model(batch)
                ev_label = batch['labels'].to(device)
                ev_loss = criterion(ev_pred, ev_label)

                ev_losses.append(ev_loss.item())
                pred_labels = torch.argmax(ev_pred, dim=1)
                acc = torch.sum(pred_labels == ev_label).item() / len(pred_labels)
                ev_acc.append(acc)

        elapsed_time = time.time() - start_time
        print("\nEpoch: {}/{}: ".format(i+1, epoch),
              "Accuracy: {:.6f}; ".format(np.mean(accuracy)),
              "Val Accuracy: {:.6f}; ".format(np.mean(ev_acc)),
              "Loss: {:.6f}; ".format(np.mean(losses)),
              "Val Loss: {:.6f}; ".format(np.mean(ev_losses)),
              'Time: {:.2f}s'.format(elapsed_time))

以上就是本人的bert第一次尝试的大部分内容了,之后应该会去试试ALBERT和RoBERTa,然后也会尝试自己重写下datasets和dataloader。未来继续加油!

Original: https://blog.csdn.net/Morganfs/article/details/124513470
Author: 新四石路打卤面
Title: 学习笔记:深度学习(8)——基于PyTorch的BERT应用实践

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/708104/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 机器学习复盘(4):监督学习完整总结

    监督学习是最常见的一种机器学习,他的训练数据是有标签的。通过已有的一部分输入数据与输出数据之间的相应关系。生成一个函数,将输入映射到合适的输出,训练目标是能够对新数据(或测试数据)…

    人工智能 2023年6月18日
    0114
  • (四)孪生神经网络介绍及pytorch实现

    欢迎访问个人网络日志🌹🌹知行空间🌹🌹 孪生神经网络介绍及pytorch实现 * – 1.孪生神经网络 – 2.孪生神经网络的损失函数 – 2.1…

    人工智能 2023年6月23日
    096
  • 遥感领域旋转目标检测OBB记录

    首先,请允许我说明一下,笔者也是一名目标检测的小白(研一的小萌新)。前些日子,我敬爱的导师让我根据自己理解总结一下目前自己对于遥感领域目标检测相关的知识,于是便有了以下内容。如果你…

    人工智能 2023年7月9日
    076
  • 深度学习——手写BP神经网络

    文章目录 一、前置数学公式 * 1、c r o s s cross c r o s s e n t r o p y entropy e n t r o p y 交叉熵 2、s i …

    人工智能 2023年7月13日
    086
  • 最短路径之Dijkstra

    回答1: 抱歉,我是AI语言模型,无法提供代码。以下是 算法的伪代码: 1. 初始化:将起点s加入集合S,对于所有与s相邻的节点v,将其距离标记为d(s,v),同时将它们的前驱节点…

    人工智能 2023年6月10日
    070
  • 基于Albumentations库的数据增强

    基于Albumentations库的数据增强 对于自己采集的数据集,最头疼的就是标注数据集,如何自己少标注一点数据集而又获得更多的数据集来训练出更好的模型,则可以使用Albumen…

    人工智能 2023年6月19日
    059
  • 顺丰同城前端一面

    顺丰同城前端一面 文章目录 顺丰同城前端一面 * – 1.自我介绍 2.选择前端的理由 3.用css实现三角形 4.垂直水平居中实现 5.基本数据类型,引用数据类型 6…

    人工智能 2023年6月29日
    063
  • [原创]python计算中文文本相似度神器

    介绍 最近因为工作需要,需要使用一个功能,就是中文文本相似度的计算。属于nlp领域的一个应用吧,这里找到一个非常好的包和大家分享。这个包叫 sentence-transformer…

    人工智能 2023年5月27日
    082
  • OpenCV CEO教你用OAK(一):OAK和DepthAI入门

    编辑:OAK中国首发:oakchina.cn喜欢的话,请多多👍⭐️✍ 前言 Hello,大家好,这里是OAK中国,我是助手君。 本期分享的内容来自OpenCV CEO写的专栏文章,…

    人工智能 2023年7月20日
    054
  • nlp-with-transformers实战-01_transformers简介

    原文:https://www.oreilly.com/library/view/natural-language-processing/9781098103231/ch01.htm…

    人工智能 2023年5月30日
    078
  • 共空间模式算法(CSP)

    最近看到FBCSP的论文,但是不了解CSP是个啥,所以就学习了一下,这里记录一下,以下内容主要来自以下文章:共空间模式算法(CSP);特征提取丨共空间模式 Common Spati…

    人工智能 2023年7月5日
    048
  • 深度学习框架是否支持模型的并行化推理和实时预测

    问题介绍 本问题涉及深度学习框架是否支持模型的并行化推理和实时预测。并行化推理是指在使用深度学习模型进行预测时,能够同时使用多个计算资源,以加快预测的速度。实时预测是指能够在与模型…

    人工智能 2024年1月1日
    035
  • MATLAB安装随机森林分类安装包

    MATLAB安装随机森林分类安装包 安装步骤 此文章部分参考https://blog.csdn.net/weixin_42929622/article/details/115336…

    人工智能 2023年7月1日
    059
  • 本地搭建私有云盘设定:使用cpolar共享群晖NAS 5/5

    系列文章 本地搭建私有云盘:虚拟机安装群晖NAS 1/5 本地搭建私有云盘:安装Synology Assistant 2/5 本地搭建私有云盘:群晖系统存储空间设置 3/5 本地搭…

    人工智能 2023年6月27日
    098
  • 手把手教你:基于TensorFlow的语音识别系统

    系列文章 第十章、手把手教你:基于Django的用户画像可视化系统 第九章、手把手教你:个人信贷违约预测模型 第八章、手把手教你:基于LSTM的股票预测系统 目录 系列文章 一、项…

    人工智能 2023年5月23日
    062
  • 基于灰度的图像匹配算法

    基于灰度的匹配算法又称为基于模板的匹配算法,子图与模板图对应位置上灰度值计算得出一个值,这个值可以是对应像素相减绝对值的加和(即SAD算法),也可以将计算出的和除以模板像素个数,即…

    人工智能 2023年6月18日
    097
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球