1 NLP分类之:FastText

news2025/1/24 3:04:06

0 数据

https://download.csdn.net/download/qq_28611929/88580520?spm=1001.2014.3001.5503

数据集合:0 NLP: 数据获取与EDA-CSDN博客

词嵌入向量文件: embedding_SougouNews.npz

词典文件:vocab.pkl

1 模型

基于fastText做词向量嵌入然后引入2-gram, 3-gram扩充,最后接入一个MLP即可;

fastText 是一个由 Facebook AI Research 实现的开源库,用于进行文本分类和词向量学习。它结合了传统的词袋模型和神经网络的优点,能够快速训练大规模的文本数据。

fastText 的主要特点包括:

1. 快速训练:fastText 使用了层次化 Softmax 和负采样等技术,大大加快了训练速度。

2. 子词嵌入:fastText 将单词表示为字符级别的 n-gram,并将其视为单词的子词。这样可以更好地处理未登录词和稀有词。

3. 文本分类:fastText 提供了一个简单而高效的文本分类接口,可以用于训练和预测多类别文本分类任务。

4. 多语言支持:fastText 支持多种语言,并且可以通过学习共享词向量来提高跨语言任务的性能。

需要注意的是,fastText 主要适用于文本分类任务,对于其他类型的自然语言处理任务(如命名实体识别、机器翻译等),可能需要使用其他模型或方法。

 2 代码

nn.Embedding.from_pretrained(config.embedding_pretrained, freeze=False)
 

`nn.Embedding.from_pretrained` 是 PyTorch 中的一个函数,用于从预训练的词向量加载 Embedding 层的权重。

在使用 `nn.Embedding.from_pretrained` 时,你需要提供一个预训练的词向量矩阵作为参数,

freeze 参数: 指定是否冻结该层的权重。预训练的词向量可以是从其他模型(如 Word2Vec 或 GloVe)中得到的。

y = nn.Embedding.from_pretrained (x)

x输入:词的索引

y返回: 词向量

import pandas as pd
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import pickle as pkl
from tqdm import tqdm
import time
from torch.utils.data import Dataset

from datetime import timedelta
from sklearn.model_selection import train_test_split
from torch.utils.data import Dataset, DataLoader
from collections import defaultdict
from torch.optim import AdamW

UNK, PAD = '<UNK>', '<PAD>'  # 未知字,padding符号
RANDOM_SEED = 2023


file_path = "./data/online_shopping_10_cats.csv"
vocab_file = "./data/vocab.pkl"
emdedding_file = "./data/embedding_SougouNews.npz"
vocab = pkl.load(open(vocab_file, 'rb'))

class MyDataSet(Dataset):
    def __init__(self, df, vocab,pad_size=None):
        self.data_info = df
        self.data_info['review'] = self.data_info['review'].apply(lambda x:str(x).strip())
        self.data_info = self.data_info[['review','label']].values
        self.vocab = vocab 
        self.pad_size = pad_size
        self.buckets = 250499  
        
    def biGramHash(self,sequence, t):
        t1 = sequence[t - 1] if t - 1 >= 0 else 0
        return (t1 * 14918087) % self.buckets
        
    def triGramHash(self,sequence, t):
        t1 = sequence[t - 1] if t - 1 >= 0 else 0
        t2 = sequence[t - 2] if t - 2 >= 0 else 0
        return (t2 * 14918087 * 18408749 + t1 * 14918087) % self.buckets
        
    def __getitem__(self, item):
        result = {}
        view, label = self.data_info[item]
        result['view'] = view.strip()
        result['label'] = torch.tensor(label,dtype=torch.long)
        
        token = [i for i in view.strip()]
        seq_len = len(token)
        # 填充
        if self.pad_size:
            if len(token) < self.pad_size:
                token.extend([PAD] * (self.pad_size - len(token)))
            else:
                token = token[:self.pad_size]
                seq_len = self.pad_size
        result['seq_len'] = seq_len
        
        # 词表的转换
        words_line = []
        for word in token:
            words_line.append(self.vocab.get(word, self.vocab.get(UNK)))
        result['input_ids'] = torch.tensor(words_line, dtype=torch.long) 
        
        # 
        bigram = []
        trigram = []
        for i in range(self.pad_size):
            bigram.append(self.biGramHash(words_line, i))
            trigram.append(self.triGramHash(words_line, i))
            
        result['bigram'] = torch.tensor(bigram, dtype=torch.long)
        result['trigram'] = torch.tensor(trigram, dtype=torch.long)
        return result

    def __len__(self):
        return len(self.data_info)
df = pd.read_csv("./data/online_shopping_10_cats.csv")

#myDataset[0]
df_train, df_test = train_test_split(df, test_size=0.1, random_state=RANDOM_SEED)
df_val, df_test = train_test_split(df_test, test_size=0.5, random_state=RANDOM_SEED)
df_train.shape, df_val.shape, df_test.shape

def create_data_loader(df,vocab,pad_size,batch_size=4):
    ds = MyDataSet(df,
                   vocab,
                   pad_size=pad_size
                  )
    return DataLoader(ds,batch_size=batch_size)

MAX_LEN = 256
BATCH_SIZE = 4
train_data_loader = create_data_loader(df_train,vocab,pad_size=MAX_LEN, batch_size=BATCH_SIZE)
val_data_loader = create_data_loader(df_val,vocab,pad_size=MAX_LEN, batch_size=BATCH_SIZE)
test_data_loader = create_data_loader(df_test,vocab,pad_size=MAX_LEN, batch_size=BATCH_SIZE)

class Config(object):

    """配置参数"""
    def __init__(self):
        self.model_name = 'FastText'
        self.embedding_pretrained = torch.tensor(
            np.load("./data/embedding_SougouNews.npz")["embeddings"].astype('float32'))  # 预训练词向量
            
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')   # 设备

        self.dropout = 0.5                                              # 随机失活
        self.require_improvement = 1000                                 # 若超过1000batch效果还没提升,则提前结束训练
        self.num_classes = 2                                            # 类别数
        self.n_vocab = 0                                                # 词表大小,在运行时赋值
        self.num_epochs = 20                                            # epoch数
        self.batch_size = 128                                           # mini-batch大小
        self.learning_rate = 1e-4                                       # 学习率
        self.embed = self.embedding_pretrained.size(1)\
            if self.embedding_pretrained is not None else 300           # 字向量维度
        self.hidden_size = 256                                          # 隐藏层大小
        self.n_gram_vocab = 250499                                      # ngram 词表大小

class Model(nn.Module):
    def __init__(self, config):
        super(Model, self).__init__()
        if config.embedding_pretrained is not None:
            self.embedding = nn.Embedding.from_pretrained(config.embedding_pretrained, freeze=False)
        else:
            self.embedding = nn.Embedding(config.n_vocab, config.embed, padding_idx=config.n_vocab - 1)
        self.embedding_ngram2 = nn.Embedding(config.n_gram_vocab, config.embed)
        self.embedding_ngram3 = nn.Embedding(config.n_gram_vocab, config.embed)
        self.dropout = nn.Dropout(config.dropout)
        self.fc1 = nn.Linear(config.embed * 3, config.hidden_size)
        # self.dropout2 = nn.Dropout(config.dropout)
        self.fc2 = nn.Linear(config.hidden_size, config.num_classes)

    def forward(self, x):
        
        out_word = self.embedding(x['input_ids'])
        out_bigram = self.embedding_ngram2(x['bigram'])
        out_trigram = self.embedding_ngram3(x['trigram'])
        out = torch.cat((out_word, out_bigram, out_trigram), -1)

        out = out.mean(dim=1)
        out = self.dropout(out)
        out = self.fc1(out)
        out = F.relu(out)
        out = self.fc2(out)
        return out

config = Config()
model = Model(config)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = model.to(device)
 
EPOCHS = 5 # 训练轮数
optimizer = AdamW(model.parameters(),lr=2e-4)
total_steps = len(train_data_loader) * EPOCHS
# schedule = get_linear_schedule_with_warmup(optimizer,num_warmup_steps=0,
#                                num_training_steps=total_steps)
loss_fn = nn.CrossEntropyLoss().to(device)

def train_epoch(model,data_loader,loss_fn,device,n_exmaples,schedule=None):
    model = model.train()
    losses = []
    correct_predictions = 0
    for d in tqdm(data_loader):
        # input_ids = d['input_ids'].to(device)
        # attention_mask = d['attention_mask'].to(device)
        targets = d['label']#.to(device)
        outputs = model(d)
        
        _,preds = torch.max(outputs, dim=1)
        loss = loss_fn(outputs,targets)
        losses.append(loss.item())
        
        correct_predictions += torch.sum(preds==targets)
        loss.backward()
        nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
        optimizer.step()
        #scheduler.step()
        optimizer.zero_grad()
    return correct_predictions.double() / n_examples, np.mean(losses)
 
def eval_model(model, data_loader, loss_fn, device, n_examples):
    model = model.eval() # 验证预测模式
 
    losses = []
    correct_predictions = 0
 
    with torch.no_grad():
        for d in data_loader:
            targets = d['label']#.to(device)
            outputs = model(d)
            _, preds = torch.max(outputs, dim=1)
 
            loss = loss_fn(outputs, targets)
 
            correct_predictions += torch.sum(preds == targets)
            losses.append(loss.item())
 
    return correct_predictions.double() / n_examples, np.mean(losses)

# train model
EPOCHS = 5
history = defaultdict(list) # 记录10轮loss和acc
best_accuracy = 0
 
for epoch in range(EPOCHS):
 
    print(f'Epoch {epoch + 1}/{EPOCHS}')
    print('-' * 10)
 
    train_acc, train_loss = train_epoch(
        model,
        train_data_loader,
        loss_fn,
        optimizer,
        device,
        len(df_train)
    )
 
    print(f'Train loss {train_loss} accuracy {train_acc}')
 
    val_acc, val_loss = eval_model(
        model,
        val_data_loader,
        loss_fn,
        device,
        len(df_val)
    )
 
    print(f'Val   loss {val_loss} accuracy {val_acc}')
    print()
 
    history['train_acc'].append(train_acc)
    history['train_loss'].append(train_loss)
    history['val_acc'].append(val_acc)
    history['val_loss'].append(val_loss)
 
    if val_acc > best_accuracy:
        torch.save(model.state_dict(), 'best_model_state.bin')
        best_accuracy = val_acc

备注: CPU训练模型很慢啊!!!有GPU的用GPU吧。大家有想了解的可以私聊。

平均 1epoch / h;

Epoch 1/10
----------
100%|██████████████████████████████████| 14124/14124 [10:25:00<00:00,  2.66s/it]
Train loss 0.30206009501767567 accuracy 0.9164365618804872
Val   loss 0.335533762476819 accuracy 0.9111181905065308

Epoch 2/10
----------
100%|███████████████████████████████████| 14124/14124 [1:40:00<00:00,  2.35it/s]
Train loss 0.2812397742334814 accuracy 0.924667233078448
Val   loss 0.33604823821747 accuracy 0.9114367633004141

Epoch 3/10
----------
100%|███████████████████████████████████| 14124/14124 [1:26:10<00:00,  2.73it/s]
Train loss 0.26351333512826924 accuracy 0.9319420843953554
Val   loss 0.3722937448388443 accuracy 0.9082510353615801

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1279435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二、ZooKeeper集群搭建

目录 1、概述 2、安装 2.1 第一步&#xff1a;下载zookeeeper压缩包 2.2 第二步&#xff1a;解压 2.3 第三步&#xff1a;修改配置文件 2.4 第四步&#xff1a;添加myid配置 ​​​​​​​2.5 第五步&#xff1a;安装包分发并修改myid的值 ​​​​​​​2.6 第六步&a…

Ubuntu22.04无需命令行安装中文输入法

概要&#xff1a;Ubuntu22.04安装完成后&#xff0c;只需在设置中点点点即可完成中文输入法的安装&#xff0c;无需命令行。 一、安装中文语言包 1、点击屏幕右上角&#xff0c;如下图所示。 2、点击设置 3、选择地区与语言&#xff0c;点击管理已安装的语言 4、点击安装 5、输…

SSM SpringBoot vue社团事务管理系统

SSM SpringBoot vue社团事务管理系统 系统功能 登录 个人中心 人员信息管理 考勤信息管理 空闲时间管理 现金日记账管理 经费预算管理 物品租借管理 会议信息管理 活动信息管理 项目任务管理 公告通知管理 物资信息管理 开发环境和技术 开发语言&#xff1a;Java 使用框架:…

人工智能时代:AIGC的横空出世

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 什么是AIGC?二. AIGC的主要特征2.1 文本生成2.2 图像生成2.3 语音生成2.4 视…

微信支付/

微信支付准备工作 3.2.1 如何保证数据安全&#xff1f; 完成微信支付有两个关键的步骤&#xff1a; 第一个就是需要在商户系统当中调用微信后台的一个下单接口&#xff0c;就是生成预支付交易单。 第二个就是支付成功之后微信后台会给推送消息。 这两个接口数据的安全性&#x…

13.字符串处理函数——输入输出

文章目录 前言一、题目描述 二、解题 程序运行代码 三、总结 前言 本系列为字符串处理函数编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 二、解题 程序运行代码 #include<stdio.h> #include<string.h> int main() {char str[10];printf(&q…

思维导图应用程序:iThoughts 6.5 Crack

为什么选择 iThoughts&#xff1f; 有很多思维导图应用程序。他们中的许多人都非常好。那么您为什么要考虑 iThoughts&#xff1f; 免责声明&#xff1a;我创建了 iThoughts - 这是我过去 12 年的生活 - 我有点偏见&#xff01; 大多数思维导图应用程序都提供相同的基本功能级…

BUUCTF 间谍启示录 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 在城际公路的小道上&#xff0c;罪犯G正在被警方追赶。警官X眼看他正要逃脱&#xff0c;于是不得已开枪击中了罪犯G。罪犯G情急之下将一个物体抛到了前方湍急的河流中&#xff0c;便头一歪突然倒地。警官X接近一看&…

【算法刷题】Day11

文章目录 面试题 08.01. 三步问题题干&#xff1a;算法原理&#xff1a;1、状态表示2、状态转移方程3、初始化4、填表顺序5、返回值 代码&#xff1a; 209. 长度最小的子数组题干&#xff1a;算法原理&#xff1a;1、暴力枚举出所有的子数组的和2、利用单调性&#xff0c;使用“…

【Unity动画】状态机添加参数控制动画切换(Animator Controller)

Unity - 手册&#xff1a;动画参数 在Unity中&#xff0c;动画状态的切换是通过Animator Controller中的过渡&#xff08;Transition&#xff09;来实现的。过渡是状态之间的连接&#xff0c;控制过渡一般都是靠调用代码参数 我们来实现一个案例&#xff1a; 创建动画状态机&a…

Zabbix HA高可用集群搭建

Zabbix HA高可用集群搭建 Zabbix HA高可用集群搭建一、Zabbix 高可用集群&#xff08;Zabbix HA&#xff09;二、部署Zabbix高可用集群1、两个服务端配置1.1主节点 Zabbix Server 配置1.2 备节点 Zabbix Server 配置1.3 主备节点添加监控主机1.4 查看高可用集群状态 2、两个客户…

[前 5 名] 最顶级的数据恢复软件解决方案列表

您是否在互联网上找到适用于 Windows PC 的前 5 名最受好评的数据恢复软件解决方案&#xff1f;嗯&#xff0c;在线市场上有很多工具可以恢复已删除的文件。但并不是所有的应用程序都值得使用它。值得信赖的文件恢复工具将有助于快速检索丢失、删除、格式化的数据并从计算机恢复…

数据结构和算法-线索二叉树中的线索化和在线索二叉树中找前驱后继

线索二叉树的概念 找到某个节点得按照遍历得到的序列开始遍历才能遍历全部节点&#xff0c;非常繁琐 中序线索二叉树 线索二叉树的存储结构 先序线索二叉树 后序线索二叉树 三种线索二叉树的对比 即对应前驱后后继判断标准不同 小结 二叉树的线索化 用土办法找中序前驱 当…

专治Java底子差:Java所有的运算符都在这里了

&#x1f497;推荐阅读文章&#x1f497; &#x1f338;JavaSE系列&#x1f338;&#x1f449;1️⃣《JavaSE系列教程》&#x1f33a;MySQL系列&#x1f33a;&#x1f449;2️⃣《MySQL系列教程》&#x1f340;JavaWeb系列&#x1f340;&#x1f449;3️⃣《JavaWeb系列教程》…

JavaScript 延迟加载的艺术:按需加载的最佳实践

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Python海绵宝宝

目录 系列文章 写在前面 海绵宝宝 写在后面 系列文章 序号文章目录直达链接表白系列1浪漫520表白代码https://want595.blog.csdn.net/article/details/1306668812满屏表白代码https://want595.blog.csdn.net/article/details/1297945183跳动的爱心https://want595.blog.cs…

【毕业设计】基于雷达与深度学习的摔倒检测——微多普勒效应

运动物体的微多普勒效应为人体动作识别提供了可能&#xff0c;基于雷达的居家检测具有良好的隐私保护性&#xff0c;且不易受环境因素影响&#xff08;如光照、温度等&#xff09;&#xff0c;近年来已受到国内外学者的广泛关注。由于雷达信号的非平稳特性&#xff0c;通过短时…

9. 双向队列

在队列中&#xff0c;我们仅能删除头部元素或在尾部添加元素。如下图所示&#xff0c;双向队列(double-ended queue)提供了更高的灵活性&#xff0c;允许在头部和尾部执行元素的添加或删除操作。 9.1 双向队列常用操作 双向队列的常用操作如下表所示&#xff0c;具体的方法名称…

MIT线性代数笔记-第21讲-特征值,特征向量

目录 21.特征值&#xff0c;特征向量打赏 21.特征值&#xff0c;特征向量 对于一个方阵 A A A&#xff0c;若 A x ⃗ λ x ⃗ A \vec{x} \lambda \vec{x} Ax λx &#xff0c;即 A x ⃗ A \vec{x} Ax 平行于 x ⃗ \vec{x} x &#xff0c;那么 λ \lambda λ是 A A A的特征值…

数据结构——堆排序的topk问题

呀哈喽&#xff0c;我是结衣 前言 今天给大家带来的堆排序的topk问题。topk就是在许多数中&#xff0c;找出前k个大的数&#xff0c;可能是几十个数&#xff0c;也可能是几千万个数中找。今天我们将要在1000000&#xff08;一百万&#xff09;个数中找出前10大的数。 知识点 C…