Bert入门-使用BERT(transformers库)对推特灾难文本二分类

Kaggle入门竞赛-对推特灾难文本二分类

这个是二月份学习的,最近整理资料所以上传到博客备份一下

数据在这里:https://www.kaggle.com/competitions/nlp-getting-started/data
github(jupyter notebook):https://github.com/ziggystardust-pop/bert-bi-classification.git
使用BERT(transformers库)对推特灾难文本二分类

xxx着火了(灾难)

火烧云像是燃烧的火焰(非灾难)

import os
import pandas
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
# 用于加载bert模型的分词器
from transformers import AutoTokenizer
# 用于加载bert模型
from transformers import AutoModel
from pathlib import Path
from tqdm.notebook import tqdm



batch_size = 16
# 文本的最大长度
text_max_length = 128
epochs = 100
# 取多少训练集的数据作为验证集
validation_ratio = 0.1
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 每多少步,打印一次loss
log_per_step = 50

# 数据集所在位置
dataset_dir = Path("/kaggle/input/nlp-getting-started/")
os.makedirs(dataset_dir) if not os.path.exists(dataset_dir) else ''

# 模型存储路径
model_dir = Path("/kaggle/working/")
# 如果模型目录不存在,则创建一个
os.makedirs(model_dir) if not os.path.exists(model_dir) else ''

print("Device:", device)



Device: cuda

数据处理

加载数据集,查看文本最大长度

pd_data = pandas.read_csv(dataset_dir / 'train.csv')
pd_data
idkeywordlocationtexttarget
01NaNNaNOur Deeds are the Reason of this #earthquake M...1
14NaNNaNForest fire near La Ronge Sask. Canada1
25NaNNaNAll residents asked to 'shelter in place' are ...1
36NaNNaN13,000 people receive #wildfires evacuation or...1
47NaNNaNJust got sent this photo from Ruby #Alaska as ...1
..................
760810869NaNNaNTwo giant cranes holding a bridge collapse int...1
760910870NaNNaN@aria_ahrary @TheTawniest The out of control w...1
761010871NaNNaNM1.94 [01:04 UTC]?5km S of Volcano Hawaii. htt...1
761110872NaNNaNPolice investigating after an e-bike collided ...1
761210873NaNNaNThe Latest: More Homes Razed by Northern Calif...1

7613 rows × 5 columns

pd_data = pandas.read_csv(dataset_dir / 'train.csv')[['text', 'target']]
pd_data
texttarget
0Our Deeds are the Reason of this #earthquake M...1
1Forest fire near La Ronge Sask. Canada1
2All residents asked to 'shelter in place' are ...1
313,000 people receive #wildfires evacuation or...1
4Just got sent this photo from Ruby #Alaska as ...1
.........
7608Two giant cranes holding a bridge collapse int...1
7609@aria_ahrary @TheTawniest The out of control w...1
7610M1.94 [01:04 UTC]?5km S of Volcano Hawaii. htt...1
7611Police investigating after an e-bike collided ...1
7612The Latest: More Homes Razed by Northern Calif...1

7613 rows × 2 columns

在使用BERT进行文本分类时,文本序列会被分段成较小的片段,每个片段的长度不能超过BERT模型的最大输入长度。BERT-base模型的最大输入长度为512个token。但是,实际上,通常不会使用整个512个token的长度,因为这会导致模型的计算和内存消耗过高,尤其是在GPU内存有限的情况下。

因此,为了在保持模型性能的同时有效利用计算资源,常见的做法是将文本序列截断或填充到一个较小的长度,通常是128或者256。在这个设置下,大多数文本序列都可以被完整地处理,而且不会导致过多的计算资源消耗。

选择128作为文本最大长度的原因可能是出于以下考虑:

大多数文本序列可以在128个token的长度内完整表示,因此不会丢失太多信息。
128是一个相对合理的长度,可以平衡模型性能和计算资源的消耗。
在实际应用中,较长的文本序列很少出现,因此选择128不会对大多数样本产生太大影响。

max_length = pd_data['text'].str.len().max()
print(max_length)
# 按ratio随机划分训练集和验证集
pd_validation_data = pd_data.sample(frac = validation_ratio)
pd_train_data = pd_data[~pd_data.index.isin(pd_validation_data.index)]
pd_train_data
"""
输出:157
"""
texttarget
0Our Deeds are the Reason of this #earthquake M...1
1Forest fire near La Ronge Sask. Canada1
2All residents asked to 'shelter in place' are ...1
4Just got sent this photo from Ruby #Alaska as ...1
5#RockyFire Update => California Hwy. 20 closed...1
.........
7607#stormchase Violent Record Breaking EF-5 El Re...1
7608Two giant cranes holding a bridge collapse int...1
7610M1.94 [01:04 UTC]?5km S of Volcano Hawaii. htt...1
7611Police investigating after an e-bike collided ...1
7612The Latest: More Homes Razed by Northern Calif...1

6852 rows × 2 columns

#定义数据类
class MyDataset(Dataset):
    def __init__(self,mode = 'train'):
        super(MyDataset,self).__init__()
        self.mode = mode
        if mode == 'train':
            self.dataset = pd_train_data
        elif mode == 'validation':
            self.dataset = pd_validation_data
        elif mode == 'test':
            # 如果是测试模式,则返回推文和id。拿id做target主要是方便后面写入结果。
            self.dataset = pandas.read_csv(dataset_dir / 'test.csv')[['text', 'id']]
        else:
            raise Exception("Unknown mode {}".format(mode))
    
    def __getitem__(self, index):
        # 取第index条
        data = self.dataset.iloc[index]
        # 取其推文,做个简单的数据清理
        source = data['text'].replace("#", "").replace("@", "")
        # 取对应的推文
        if self.mode == 'test':
            # 如果是test,将id做为target
            target = data['id']
        else:
            target = data['target']
        # 返回推文和target
        return source, target

    def __len__(self):
        return len(self.dataset)
train_dataset = MyDataset('train')
validation_dataset = MyDataset('validation')
train_dataset.__getitem__(0)
"""
('Our Deeds are the Reason of this earthquake May ALLAH Forgive us all', 1)
"""
#使用分词器
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
tokenizer("I'm learning deep learning", return_tensors='pt')


"""
tokenizer_config.json:   0%|          | 0.00/48.0 [00:00<?, ?B/s]
config.json:   0%|          | 0.00/570 [00:00<?, ?B/s]
vocab.txt:   0%|          | 0.00/232k [00:00<?, ?B/s]
tokenizer.json:   0%|          | 0.00/466k [00:00<?, ?B/s]

{'input_ids': tensor([[ 101, 1045, 1005, 1049, 4083, 2784, 4083,  102]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1]])}
"""

下面这个collate_fn函数用于对一个batch的文本数据进行处理,将文本句子转换为tensor,并组成一个batch。下面是函数的具体功能和输入输出:

输入参数 batch:一个batch的句子,每个句子是一个元组,包含文本和目标标签,例如:[(‘推文1’, 目标1), (‘推文2’, 目标2), …]

输出:处理后的结果,包含两部分:

src:是要送给BERT模型的输入,包含两个tensor:
input_ids:经过分词和映射后的输入文本的token id序列。
attention_mask:用于指示BERT模型在进行自注意力机制时哪些部分是padding的,需要被忽略。1表示有效token,0表示padding。
target:目标标签的tensor序列,即对应每个文本的标签。
这个函数首先将输入的batch分成两个列表,一个是文本列表 text,一个是目标标签列表 target。然后使用 tokenizer 对文本进行分词、映射、padding和裁剪等预处理操作,得到模型的输入 src。最后将处理后的输入 src 和目标标签 target 组合成输出。

collate_fn函数在数据加载器每次取出一个batch的样本时被调用,用于对这个batch的样本进行预处理、转换成模型所需的格式。

def collate_fn(batch):
    """
    将一个batch的文本句子转成tensor,并组成batch。
    :param batch: 一个batch的句子,例如: [('推文', target), ('推文', target), ...]
    :return: 处理后的结果,例如:
             src: {'input_ids': tensor([[ 101, ..., 102, 0, 0, ...], ...]), 'attention_mask': tensor([[1, ..., 1, 0, ...], ...])}
             target:[1, 1, 0, ...]
    """
    text, target = zip(*batch)
    text, target = list(text), list(target)

    # src是要送给bert的,所以不需要特殊处理,直接用tokenizer的结果即可
    # padding='max_length' 不够长度的进行填充
    # truncation=True 长度过长的进行裁剪
    src = tokenizer(text, padding='max_length', max_length=text_max_length, return_tensors='pt', truncation=True)

    return src, torch.LongTensor(target)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, collate_fn=collate_fn)
validation_loader = DataLoader(validation_dataset, batch_size=batch_size, shuffle=False, collate_fn=collate_fn)
inputs, targets = next(iter(train_loader))
print("inputs:", inputs)
print(inputs['input_ids'].shape)
print("targets:", targets)
#batch_size = 16

"""
inputs: {'input_ids': tensor([[  101, 10482,  6591,  ...,     0,     0,     0],
        [  101,  4911,  2474,  ...,     0,     0,     0],
        [  101,  5916,  6340,  ...,     0,     0,     0],
        ...,
        [  101, 21318,  2571,  ...,     0,     0,     0],
        [  101, 20010, 21149,  ...,     0,     0,     0],
        [  101, 26934,  5315,  ...,     0,     0,     0]]), 'token_type_ids': tensor([[0, 0, 0,  ..., 0, 0, 0],
        [0, 0, 0,  ..., 0, 0, 0],
        [0, 0, 0,  ..., 0, 0, 0],
        ...,
        [0, 0, 0,  ..., 0, 0, 0],
        [0, 0, 0,  ..., 0, 0, 0],
        [0, 0, 0,  ..., 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1,  ..., 0, 0, 0],
        [1, 1, 1,  ..., 0, 0, 0],
        [1, 1, 1,  ..., 0, 0, 0],
        ...,
        [1, 1, 1,  ..., 0, 0, 0],
        [1, 1, 1,  ..., 0, 0, 0],
        [1, 1, 1,  ..., 0, 0, 0]])}
torch.Size([16, 128])
targets: tensor([0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1])

"""

768是BERT模型中隐藏层的维度大小。BERT模型使用了12层或者24层的Transformer编码器,每一层的隐藏层输出的维度大小为768

nn.Linear(768, 256):将输入的维度从768降到256,这是一个线性变换(全连接层),将BERT模型输出的768维隐藏表示转换为更低维度的表示。

nn.ReLU():ReLU激活函数,用于引入非线性。在降维后的表示上应用ReLU激活函数,以增加模型的非线性能力。

nn.Linear(256, 1):将256维的表示进一步映射到一个单一的值,用于二分类问题中的概率预测。

nn.Sigmoid():Sigmoid激活函数,将输出值压缩到0到1之间,表示概率值。

因此,整个self.predictor模块的作用是将BERT模型的输出映射到一个单一的概率值,用于二分类问题的预测。

#构建模型
class TextClassificationModel(nn.Module):
    def __init__(self):
        super(TextClassificationModel, self).__init__()

        # 加载bert模型
        self.bert = AutoModel.from_pretrained("bert-base-uncased")

        # 最后的预测层
        self.predictor = nn.Sequential(
            nn.Linear(768, 256),
            nn.ReLU(),
            nn.Linear(256, 1),
            nn.Sigmoid()
        )
    def forward(self, src):
        """
        :param src: 分词后的推文数据
        """

        # 将src直接序列解包传入bert,因为bert和tokenizer是一套的,所以可以这么做。
        # 得到encoder的输出,用最前面[CLS]的输出作为最终线性层的输入
        outputs = self.bert(**src).last_hidden_state[:, 0, :]

        # 使用线性层来做最终的预测
        return self.predictor(outputs)

    
"""

last_hidden_state 的形状是 (batch_size, sequence_length, hidden_size),其中:

batch_size 是当前批次中样本的数量。
sequence_length 是输入序列的长度。
hidden_size 是隐藏状态的维度,通常等于BERT模型的隐藏层大小,例如在BERT-base中是768。
"""
model = TextClassificationModel()
model = model.to(device)
model(inputs.to(device))
criteria = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=3e-5)
# 由于inputs是字典类型的,定义一个辅助函数帮助to(device)
def to_device(dict_tensors):
    result_tensors = {}
    for key, value in dict_tensors.items():
        result_tensors[key] = value.to(device)
    return result_tensors
"""
将字典中的张量转移到指定的设备(如GPU)。它接受一个字典,其中键是张量的名称,值是张量本身。
然后,它迭代字典中的每个键值对,并将值转移到设备上,最后返回一个具有相同键但值位于指定设备上的新字典
"""



def validate():
    model.eval()
    total_loss = 0.
    total_correct = 0
    for inputs, targets in validation_loader:
        inputs, targets = to_device(inputs), targets.to(device)
        outputs = model(inputs)
        loss = criteria(outputs.view(-1), targets.float())
        total_loss += float(loss)

        correct_num = (((outputs >= 0.5).float() * 1).flatten() == targets).sum()
        total_correct += correct_num

    return total_correct / len(validation_dataset), total_loss / len(validation_dataset)
"""
model.safetensors:   0%|          | 0.00/440M [00:00<?, ?B/s]
"""
# 首先将模型调成训练模式
model.train()

# 清空一下cuda缓存
if torch.cuda.is_available():
    torch.cuda.empty_cache()

# 定义几个变量,帮助打印loss
total_loss = 0.
# 记录步数
step = 0

# 记录在验证集上最好的准确率
best_accuracy = 0

# 开始训练
for epoch in range(epochs):
    model.train()
    for i, (inputs, targets) in enumerate(train_loader):
        # 从batch中拿到训练数据
        inputs, targets = to_device(inputs), targets.to(device)
        # 传入模型进行前向传递
        outputs = model(inputs)
        # 计算损失
        loss = criteria(outputs.view(-1), targets.float())
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        total_loss += float(loss)
        step += 1

        if step % log_per_step == 0:
            print("Epoch {}/{}, Step: {}/{}, total loss:{:.4f}".format(epoch+1, epochs, i, len(train_loader), total_loss))
            total_loss = 0

        del inputs, targets

    # 一个epoch后,使用过验证集进行验证
    accuracy, validation_loss = validate()
    print("Epoch {}, accuracy: {:.4f}, validation loss: {:.4f}".format(epoch+1, accuracy, validation_loss))
    torch.save(model, model_dir / f"model_{epoch}.pt")

    # 保存最好的模型
    if accuracy > best_accuracy:
        torch.save(model, model_dir / f"model_best.pt")
        best_accuracy = accuracy

Epoch 1/100, Step: 49/429, total loss:27.0852
Epoch 1/100, Step: 99/429, total loss:21.9039
Epoch 1/100, Step: 149/429, total loss:22.6578
Epoch 1/100, Step: 199/429, total loss:21.1815
Epoch 1/100, Step: 249/429, total loss:20.3617
Epoch 1/100, Step: 299/429, total loss:18.9497
Epoch 1/100, Step: 349/429, total loss:20.8270
Epoch 1/100, Step: 399/429, total loss:20.0272
Epoch 1, accuracy: 0.8279, validation loss: 0.0247
Epoch 2/100, Step: 20/429, total loss:18.0542
Epoch 2/100, Step: 70/429, total loss:14.7096
Epoch 2/100, Step: 120/429, total loss:15.0193
Epoch 2/100, Step: 170/429, total loss:14.2937
Epoch 2/100, Step: 220/429, total loss:14.1752
Epoch 2/100, Step: 270/429, total loss:14.2685
Epoch 2/100, Step: 320/429, total loss:14.0682
Epoch 2/100, Step: 370/429, total loss:16.1425
Epoch 2/100, Step: 420/429, total loss:17.1818
Epoch 2, accuracy: 0.8397, validation loss: 0.0279
Epoch 3/100, Step: 41/429, total loss:8.0204
Epoch 3/100, Step: 91/429, total loss:9.5614
Epoch 3/100, Step: 141/429, total loss:9.2036
Epoch 3/100, Step: 191/429, total loss:8.9964
Epoch 3/100, Step: 241/429, total loss:10.7305
Epoch 3/100, Step: 291/429, total loss:10.5000
Epoch 3/100, Step: 341/429, total loss:11.3632
Epoch 3/100, Step: 391/429, total loss:10.3103
Epoch 3, accuracy: 0.8252, validation loss: 0.0339
Epoch 4/100, Step: 12/429, total loss:8.1302
Epoch 4/100, Step: 62/429, total loss:5.9590
Epoch 4/100, Step: 112/429, total loss:6.9333
Epoch 4/100, Step: 162/429, total loss:6.4659
Epoch 4/100, Step: 212/429, total loss:6.3636
Epoch 4/100, Step: 262/429, total loss:6.6609
Epoch 4/100, Step: 312/429, total loss:6.3064
Epoch 4/100, Step: 362/429, total loss:5.7218
Epoch 4/100, Step: 412/429, total loss:6.8676
Epoch 4, accuracy: 0.8042, validation loss: 0.0370
Epoch 5/100, Step: 33/429, total loss:4.4049
Epoch 5/100, Step: 83/429, total loss:3.0673
Epoch 5/100, Step: 133/429, total loss:4.1351
Epoch 5/100, Step: 183/429, total loss:3.8803
Epoch 5/100, Step: 233/429, total loss:3.2633
Epoch 5/100, Step: 283/429, total loss:4.6513
Epoch 5/100, Step: 333/429, total loss:4.3888
Epoch 5/100, Step: 383/429, total loss:5.1710
Epoch 5, accuracy: 0.8055, validation loss: 0.0484
model = torch.load(model_dir / f"model_best.pt")
model = model.eval()
test_dataset = MyDataset('test')
#构造测试集的dataloader。测试集是不包含target的
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, collate_fn=collate_fn)
results = []
for inputs, ids in tqdm(test_loader):
    outputs = model(inputs.to(device))
    outputs = (outputs >= 0.5).int().flatten().tolist()
    ids = ids.tolist()
    results = results + [(id, result) for result, id in zip(outputs, ids)]
with open('/kaggle/working/results.csv', 'w', encoding='utf-8') as f:
    f.write('id,target\n')
    for id, result in results:
        f.write(f"{id},{result}\n")
print("Finished!")

"""
  0%|          | 0/204 [00:00<?, ?it/s]
  Finished!
"""

提交后的结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JavaEE】多线程进阶

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; 文章目录 1.锁策略1.1悲观锁和乐观锁1.2重量级锁和轻量级锁1.3自旋锁和挂起等待锁1.4可…

AI大模型的智能心脏:向量数据库的崛起

在人工智能的飞速发展中,一个关键技术正悄然成为AI大模型的智能心脏——向量数据库。它不仅是数据存储和管理的革命性工具,更是AI技术突破的核心。随着AI大模型在各个领域的广泛应用,向量数据库的重要性日益凸显。 01 技术突破:向量数据库的内在力量 向量数据库以其快速检索…

TypeError: Cannot read properties of null (reading ‘nextSibling‘)

做项目用的Vue3Vite, 在画静态页面时&#xff0c;点击菜单跳转之后总是出现如下报错&#xff0c;百思不得其解。看了网上很多回答&#xff0c;也没有解决问题&#xff0c;然后试了很多方法&#xff0c;最后竟然发现是template里边没有结构的原因。。。 原来我的index.vue是这样…

自注意力 公式解释

公式 (\mathbf{y}_i f(\mathbf{x}_i, (\mathbf{x}_1, \mathbf{x}_1), \ldots, (\mathbf{x}_n, \mathbf{x}_n)) \in \mathbb{R}^d) 描述了自注意力机制中单个词元的输出表示如何生成。我们来逐步解释这个公式&#xff1a; 输入序列 (\mathbf{x}_1, \mathbf{x}_2, \ldots, \math…

2024吉他手的超级助手Guitar Pro8中文版本发布啦!

亲爱的音乐爱好者们&#xff0c;今天我要来和你们分享一款让我彻底沉迷的软件—Guitar Pro。如果你是一名热爱吉他的朋友&#xff0c;那么接下来的内容你可要瞪大眼睛仔细看哦&#xff01;&#x1f440;&#x1f3b6; Guitar Pro免费绿色永久安装包下载&#xff1a;&#xff0…

《昇思 25 天学习打卡营第 11 天 | ResNet50 图像分类 》

《昇思 25 天学习打卡营第 11 天 | ResNet50 图像分类 》 活动地址&#xff1a;https://xihe.mindspore.cn/events/mindspore-training-camp 签名&#xff1a;Sam9029 计算机视觉-图像分类&#xff0c;很感兴趣 且今日精神颇佳&#xff0c;一个字&#xff0c;学啊 上一节&…

【数据结构】经典链表题目详解集合(反转链表、相交链表、链表的中间节点、回文链表)

文章目录 一、反转链表1、程序详解2、代码 二、相交链表1、程序详解2、代码 三、链表的中间节点1、程序详解2、代码 四、回文链表1、程序详解2、代码 一、反转链表 1、程序详解 题目&#xff1a;给定单链表的头节点 head &#xff0c;请反转链表&#xff0c;并返回反转后的链…

STM32实现硬件IIC通信(HAL库)

文章目录 一. 前言二. 关于IIC通信三. IIC通信过程四. STM32实现硬件IIC通信五. 关于硬件IIC的Bug 一. 前言 最近正在DIY一款智能电池&#xff0c;需要使用STM32F030F4P6和TI的电池管理芯片BQ40Z50进行SMBUS通信。SMBUS本质上就是IIC通信&#xff0c;项目用到STM32CubeMXHAL库…

基于ROS的智能网联车远程交互软件,全UI无需记忆指令,剑指核心原理。

基于ROS的智能网联车远程交互软件&#xff0c;全UI无需记忆指令&#xff0c;剑指核心原理。 服务于中汽恒泰&#xff0c;伟大的项目&#xff0c;希望看官点赞&#xff0c;谢谢~~ 进程&#xff08;节点&#xff09;列表化&#xff0c;参数面板化&#xff0c;实现快速机器人配置…

SpringMVC(2)——controller方法参数与html表单对应

controller方法参数与html表单对应 0. User实体类 import org.springframework.format.annotation.DateTimeFormat;import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.Map;public class User implements Serializable {private …

CosyVoice - 阿里最新开源语音克隆、文本转语音项目 支持情感控制及粤语 本地一键整合包下载

近日&#xff0c;阿里通义实验室发布开源语音大模型项目FunAudioLLM&#xff0c;而且一次包含两个模型&#xff1a;SenseVoice和CosyVoice。 CosyVoice专注自然语音生成&#xff0c;支持多语言、音色和情感控制&#xff0c;支持中英日粤韩5种语言的生成&#xff0c;效果显著优于…

apk反编译修改教程系列-----修改apk 解除软件限制功能 实例操作步骤解析_3【二十二】

在前面的几期博文中有过解析去除apk中功能权限的反编译步骤。另外在以往博文中也列举了修改apk中选项功能权限的操作方法。今天以另外一款apk作为演示修改反编译去除软件功能限制的步骤。兴趣的友友可以参考其中的修改过程。 课程的目的是了解apk中各个文件的具体作用以及简单…

JavaWeb—Servlet

概述 Javaweb的核心就是围绕servlet Servlet就是一个接口&#xff0c; 定义了java类 被浏览器访问到&#xff08;tomcat识别&#xff09;的接口 将来就是自己写一个类 &#xff0c;实现servlet接口 &#xff0c;重写方法 执行过程 当服务器接收到客户端浏览器的请求后&#xff…

【机器学习】机器学习与时间序列分析的融合应用与性能优化新探索

文章目录 引言第一章&#xff1a;机器学习在时间序列分析中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 数据增强 1.2 模型选择1.2.1 自回归模型1.2.2 移动平均模型1.2.3 长短期记忆网络1.2.4 卷积神经网络 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 A…

C# 编程中互斥锁的使用

C# 中的互斥锁 互斥锁是 C# 中使用的同步原语&#xff0c;用于控制多个线程或进程对共享资源的访问。其目的是确保在任何给定时间只有一个线程或进程可以获取互斥锁&#xff0c;从而提供互斥。 C# 中互斥锁的优点 可以使用互斥锁 (Mutex) 并享受其带来的好处。 1. 共享资源…

一篇就够了,为你答疑解惑:锂电池一阶模型-在线参数辨识(附代码)

锂电池一阶模型-在线参数辨识 背景在线 VS 离线 参数辨识递推最小二乘法一阶戴维南Z域离散表达式 背景 锂电池一阶戴维南等效模型的基础知识和离线辨识方法&#xff0c;已经在上一期非常详细地讲解了一轮&#xff08;上期文章请戳此处&#xff09;&#xff0c;本期继续讲解一下…

秋招提前批面试经验分享(上)

⭐️感谢点开文章&#x1f44b;&#xff0c;欢迎来到我的微信公众号&#xff01;我是恒心&#x1f60a; 一位热爱技术分享的博主。如果觉得本文能帮到您&#xff0c;劳烦点个赞、在看支持一下哈&#x1f44d;&#xff01; ⭐️我叫恒心&#xff0c;一名喜欢书写博客的研究生在读…

vue3中使用EasyPlayer播放h265视频流

1、下载EasyPlayer 5.0.3版本 在package.json中加入EasyPlayer&#xff0c;并全局install下 "dependencies": {"easydarwin/easyplayer": "^5.0.3" }2、找到node_modules中的EasyPlayer.wasm和EasyPlayer-element.min.js 3、复制到public下面&…

多元微分学中可微、连续、存在问题

一、偏导存在 与一元证明相同&#xff0c;利用偏导定义式&#xff0c;证明偏导数左右极限存在且相同。 二、偏导连续 与一元证明相同&#xff0c;证明 三、极限存在 1、找一条路径&#xff0c;一般地找 y kx 2、代入f(x,y)&#xff0c;得f(x,kx) 3、证明f(x,kx)极限存在 注意&…

基于java语言+ Vue+ElementUI+ MySQL8.0.36数字化产科管理平台源码,妇幼信息化整体解决方案

基于java语言 VueElementUI MySQL8.0.36数字化产科管理平台源码&#xff0c;妇幼信息化整体解决方案 数字化产科管理平台是为医院产科量身定制的信息管理系统。它管理了孕妇从怀孕开始到生产结束42天一系列医院保健服务信息。该系统由门诊系统、住院系统、数据统计模块三部分组…