NLP任务之预测最后一个词

目录

 1.加载预训练模型

2  从本地加载数据集 

3.数据集处理 

 4.下游任务模型

5.测试代码 

6.训练代码 

7.保存训练好的模型 

8. 加载 保存的模型


 

 1.加载预训练模型

#加载预训练模型
from transformers import AutoTokenizer


#预训练模型:distilgpt2
#use_fast=True:用rust语言写的分词器,速度比python语言写的分词器快很多
tokenizer = AutoTokenizer.from_pretrained(r'../data/model/distilgpt2/', use_fast=True)
tokenizer.batch_encode_plus([
    'hide new secretions from the parental units',
    'this moive is great'  
])


#输出:
#{'input_ids': [[24717, 649, 3200, 507, 422, 262, 21694, 4991], [5661, 6941, 425, 318, 1049]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]}


print(tokenizer)

 

GPT2TokenizerFast(name_or_path='../data/model/distilgpt2/', vocab_size=50257, model_max_length=1024, is_fast=True, padding_side='right', truncation_side='right', special_tokens={'bos_token': '<|endoftext|>', 'eos_token': '<|endoftext|>', 'unk_token': '<|endoftext|>'}, clean_up_tokenization_spaces=False),  added_tokens_decoder={
	50256: AddedToken("<|endoftext|>", rstrip=False, lstrip=False, single_word=False, normalized=True, special=True),
}

#预测最后一个词:是一个多分类问题
#针对这个vocab_size=50257的问题,分类类别就是50257个类别 

2  从本地加载数据集 

from datasets import load_from_disk


dataset = load_from_disk(r'E:/ALOT/10_deep_learning/data/datasets/glue_sst2/')

dataset

 

DatasetDict({
    train: Dataset({
        features: ['sentence', 'label', 'idx'],
        num_rows: 67349
    })
    validation: Dataset({
        features: ['sentence', 'label', 'idx'],
        num_rows: 872
    })
    test: Dataset({
        features: ['sentence', 'label', 'idx'],
        num_rows: 1821
    })
})

3.数据集处理 

#预测下一个词,只需要数据集中的sentence, 不需要label和idx
#使用map函数做映射。处理只剩下sentence 

def f(dataset, tokenizer):
    return tokenizer.batch_encode_plus(dataset['sentence'])

#num_proc=8  查看任务管理器--性能--逻辑处理器的数量
dataset = dataset.map(f, batched=True, batch_size=1000, num_proc=8,
                      remove_columns=['sentence', 'label', 'idx'],
                      fn_kwargs={'tokenizer': tokenizer})  


dataset
DatasetDict({
    train: Dataset({
        features: ['input_ids', 'attention_mask'],
        num_rows: 67349
    })
    validation: Dataset({
        features: ['input_ids', 'attention_mask'],
        num_rows: 872
    })
    test: Dataset({
        features: ['input_ids', 'attention_mask'],
        num_rows: 1821
    })
})

 

#规定一个句子最小要有8个单词
#过滤掉太短的句子
def f_1(dataset):
    return [len(i) >=8 for i in dataset['input_ids']]  #i是每一句话

dataset = dataset.filter(f_1, batched=True, batch_size=1000, num_proc=8)


dataset

 

DatasetDict({
    train: Dataset({
        features: ['input_ids', 'attention_mask'],
        num_rows: 39905
    })
    validation: Dataset({
        features: ['input_ids', 'attention_mask'],
        num_rows: 848
    })
    test: Dataset({
        features: ['input_ids', 'attention_mask'],
        num_rows: 1730
    })
})
#截断句子
def f_2(dataset):
    #分别获取截断之后的input_ids, attention_mask
    dataset['input_ids'] = [i[:8] for i in dataset['input_ids']]
    dataset['attention_mask'] = [[1] * 8] * len(dataset['attention_mask'])
    #预测最后一个词,前七个单词输入,最后一个输入
    #模型帮我们做了偏移量问题, 这里输入和输出保持一致即可
    dataset['labels'] = dataset['input_ids']
    return dataset

dataset = dataset.map(f_2, batched=True, batch_size=1000, num_proc=8)


dataset

 

DatasetDict({
    train: Dataset({
        features: ['input_ids', 'attention_mask', 'labels'],
        num_rows: 39905
    })
    validation: Dataset({
        features: ['input_ids', 'attention_mask', 'labels'],
        num_rows: 848
    })
    test: Dataset({
        features: ['input_ids', 'attention_mask', 'labels'],
        num_rows: 1730
    })
})
dataset['train'][0]

 

{'input_ids': [24717, 649, 3200, 507, 422, 262, 21694, 4991],
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1],
 'labels': [24717, 649, 3200, 507, 422, 262, 21694, 4991]}
#定义数据加载器
import torch
#default_data_collator: 将一条条取数据变成批量取数据
from transformers.data.data_collator import default_data_collator

loader = torch.utils.data.DataLoader(
    dataset=dataset['train'],  #取出训练数据集
    batch_size=16,
    collate_fn=default_data_collator,
    shuffle=True,
    drop_last=True  #若最后一批数据没有batch_size个数据,就删掉不用
)

for data in loader:
    break
    
len(loader), data

 

(2494,
 {'input_ids': tensor([[22602,  4340,   262,  2126,   286,  1642,   479,   993],
          [ 5832,   651,   262, 10647,   326,  6260,   290,  3437],
          [   11,   645,   530,   460,  3285,   345,  3013,   382],
          [48580,   257,  2612,   290,  3950,   326, 36675,   262],
          [  361,   345,   467,   287,  6970,   326,   837,   345],
          [  270,   705,    82,   257,  4950,  2646,   837,  1336],
          [   71,  1794,  6819,   837, 26996,  6819,  6776,   837],
          [11246,  7650, 30669, 13766, 17548,   351,  6159,   220],
          [ 1169, 11918,   286,   281,  7876,  1013, 30909,  1358],
          [22437,   299,   470,  1612,   340,   705,    82,   922],
          [  270,   705,    82, 23056,   284,   766,   257,  3807],
          [ 5832,  1244,   892,   339,   373,  2491,   329,  2607],
          [ 2395,  9259,   736, 49253,   837, 11441,  2223, 16311],
          [ 8505,   837,  1312, 11691,   340,   705,    82, 14081],
          [ 1169,  1306, 13203, 29185,   286,   262,  1842,  8848],
          [26535,   867, 14138,   290, 41169,    12, 44517,  2628]]),
  'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1]]),
  'labels': tensor([[22602,  4340,   262,  2126,   286,  1642,   479,   993],
          [ 5832,   651,   262, 10647,   326,  6260,   290,  3437],
          [   11,   645,   530,   460,  3285,   345,  3013,   382],
          [48580,   257,  2612,   290,  3950,   326, 36675,   262],
          [  361,   345,   467,   287,  6970,   326,   837,   345],
          [  270,   705,    82,   257,  4950,  2646,   837,  1336],
          [   71,  1794,  6819,   837, 26996,  6819,  6776,   837],
          [11246,  7650, 30669, 13766, 17548,   351,  6159,   220],
          [ 1169, 11918,   286,   281,  7876,  1013, 30909,  1358],
          [22437,   299,   470,  1612,   340,   705,    82,   922],
          [  270,   705,    82, 23056,   284,   766,   257,  3807],
          [ 5832,  1244,   892,   339,   373,  2491,   329,  2607],
          [ 2395,  9259,   736, 49253,   837, 11441,  2223, 16311],
          [ 8505,   837,  1312, 11691,   340,   705,    82, 14081],
          [ 1169,  1306, 13203, 29185,   286,   262,  1842,  8848],
          [26535,   867, 14138,   290, 41169,    12, 44517,  2628]])})

 4.下游任务模型

from transformers import AutoModelForCausalLM, GPT2Model


class Model(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.pretrained = GPT2Model.from_pretrained('../data/model/distilgpt2/')
        self.fc = torch.nn.Linear(768, tokenizer.vocab_size, bias=False)
        
        #加载预训练权重的模型
        parameters = AutoModelForCausalLM.from_pretrained('../data/model/distilgpt2/')
        #全连接层加载预训练权重
        self.fc.load_state_dict(parameters.lm_head.state_dict()) 
        
        #前四句代码的简便写法
        #self_pretrained = AutoModelForCausalLM.from_pretrained('../data/model/distilgpt2/')
        
        self.criterion = torch.nn.CrossEntropyLoss()
        
    def forward(self, input_ids, attention_mask, labels=None):
        logits = self.pretrained(input_ids=input_ids, attention_mask=attention_mask)
        logits = logits.last_hidden_state
        logits = self.fc(logits)
        
        loss=None
        if labels is not None:
            #传入数据与labels 的取值范围的偏移量为1
            #第0维度与第2维度都要,第1维度的最后一个不要
            shift_logits = logits[:, :-1].reshape(-1, tokenizer.vocab_size)  #-1表示前两个维度合并
            #第0维度与第2维度都要,第1维度的第一个不要
            shift_labels = labels[:, 1:].reshape(-1)  #二维tensor数组变成一维
            loss = self.criterion(shift_logits, shift_labels)
        return {'loss':loss, 'logits':logits}

model = Model()
#参数量
print(sum(i.numel() for i in model.parameters()) / 10000)  #除以10000是以万为单位

 12050.9952

#python中**的用法,可以自动把一个字典解包成关键字参数{} -->xxx = xxx, xxx-->xxx
out = model(**data)
# print(out)  #一个字典
print(out['loss'], out['logits'].shape)

 

tensor(6.2742, grad_fn=<NllLossBackward0>) torch.Size([16, 8, 50257])

5.测试代码 

# 测试代码
def test(model):
    model.eval()
    
    # 加载测试数据
    loader_test = torch.utils.data.DataLoader(
        dataset=dataset['test'],
        batch_size=16,
        collate_fn=default_data_collator,
        shuffle=True,   #测试预测时,可以不打乱数据
        drop_last=True
    )
    
    correct = 0
    total = 0
    for i, data in enumerate(loader_test):
        # 只计算最后一个词的准确率. 
        label = data['input_ids'][:, -1].clone()    #clone()克隆数据,不修改原数据
        # 再从数据中抹除最后一个词, 防止模型作弊. 
        data['input_ids'][:, -1] = 0   #把最后一列数据都赋值为0
        # label就不需要了   都赋值为0
        data['labels'][:, :]  = 0
        
        # 计算
        with torch.no_grad():      #测试预测时,不需要求导梯度下降(是处于训练时做的事)
            #相当于 out = model(input_ids=input_ids, attention_mask=attention_mask, labels=labels)
            out = model(**data)
            
        # 最后一个词的准确率, 因为有偏移量的关系, 这里取的是倒数第二个词
        out = out['logits'].argmax(dim=2)[:, -2]  
        #在PyTorch中,.item() 是一个常用于从包含单个元素的张量(通常是一个0维张量,即标量scalar)中提取Python数值的方法。
        correct += (label==out).sum().item()
        total += 16    #16就是batch_szie的数值
        
        if i % 10 == 0:   #每隔10次
            print(i)
            print(label)
            print(out)
            
        if i == 50:   #只循环50次
            break
            
    print('accuracy: ', correct / total)
    
    for i in range(8):
        print(tokenizer.decode(data['input_ids'][i, :-1]))
        print(tokenizer.decode(label[i]), tokenizer.decode(out[i]))
        print()
test(model)

 

0
tensor([  416, 42738,  7297,  2709,   651,   837,   290,   349,   290, 11815,
           72, 14505,  7559,   532,  3822,   262])
tensor([   11,   262,  3807,  5000,  1064,    13,    11,   453,    13, 13664,
           72,   983,   340,    13,    12,   262])
10
tensor([  284,   428,   991,   705,   318, 11783,  1787,    65, 43527,  2306,
          460,  8395,   743,  6386,  2370,   393])
tensor([  284,   262,   262,   447,    11,    11,    76,    65, 38520, 20706,
          318,   502,   468,  6386,  4899,  1022])
20
tensor([ 7357,  1936,  4572,  2465,  1049,   257,  7358,   262, 29963,  2646,
          517,   290,  9188,  1647,   278,  1241])
tensor([7357,  584,  290, 1143,  649,  262, 2656,  262, 7051,   11,  257,  284,
         262,   12,  278, 1210])
30
tensor([14969,  5239,  3016,   837, 43207,   262,   764,  4129,   307,   262,
          705,   465,   262,   837,  1100,  2700])
tensor([   67,  5239, 12302,    13,  2033,   262,   284,  1988,   307,   262,
         1053,   262,   262,    13,  1621,  2700])
40
tensor([21730, 13770,  2737,   264,   477,  2218,   262,   257,   340,  8886,
          848, 14821,  1178,   705,   787,  1239])
tensor([  13,  290, 2737,  670,  262,  290,  262,  340,    6,  983,  257,  262,
        1438,  460,  787,  318])
50
tensor([  262,  6840,   763,   286,   611,   286,   475,  2915,   764,   837,
         4379, 12986, 10997,   272,   257,  1200])
tensor([  262,   651,   318,  1683,   621,   286,   475,    12,   284,   837,
          257,   262, 10997,   272,   257,   262])
accuracy:  0.18382352941176472
automatically pegs itself for
 the  the

if there 's a way to
 effectively  get

while benigni ( who stars and
 co  is

the stupidest , most insulting movie
 of  ever

the film might have been more satisfying
 if  than

a journey through memory , a celebration
 of  of

the story may not be new ,
 but  but

there are touching moments in eto
iles -

6.训练 

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
device

 device(type='cuda', index=0)

from transformers import AdamW
from transformers.optimization import get_scheduler


#训练代码
def train():
    #设置优化器:优化梯度下降的算法
    optimizer = AdamW(model.parameters(), lr=2e-5)
    #学习率下降计划
    scheduler = get_scheduler(name='linear',
                              num_warmup_steps=0,   #下降步长从0开始
                              num_training_steps=len(loader), #训练次数就是训练数据加载器的长度
                              optimizer=optimizer)
    #将模型发送到设备上
    model.to(device)
    model.train() #模型训练
    for i, data in enumerate(loader):
        input_ids, attention_mask, labels = data['input_ids'], data['attention_mask'], data['labels']
        input_ids, attention_mask, labels = input_ids.to(device), attention_mask.to(device), labels.to(device)
        out = model(input_ids=input_ids, attention_mask=attention_mask, labels=labels)
        
        #计算损失, 损失在model中以及计算了, 可以从返回值中获取
        loss = out['loss']
        
        #为了训练稳定(不要波动太大), 进行梯度裁剪
        torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1)    #max_norm就是公式中的c
        
        #用计算的损失来反向传播
        loss.backward()
        #梯度更新
        optimizer.step()
        scheduler.step()
        #梯度清零
        optimizer.zero_grad()
        model.zero_grad()
        
        if i % 50 == 0:  #每隔50次
            labels = labels[:, 1:]
            #out是三维tensor数组, 在索引2的维度上找最大的概率
            out = out['logits'].argmax(dim=2)[:, :-1]
            correct = (labels == out).sum().item()  #.item()一维tensor标量可以取出来
            accuracy = correct / (16 * 7)  #一批16个数据, 每个数据7个数据(8-1个偏移量)
            lr = optimizer.state_dict()['param_groups'][0]['lr']
            
            print(i, loss.item(), accuracy, lr)
train()
0 6.9149088859558105 0.14285714285714285 1.9991980753809144e-05
50 5.734440803527832 0.1875 1.959101844426624e-05
100 5.432187557220459 0.1875 1.919005613472334e-05
150 5.808253765106201 0.16964285714285715 1.8789093825180436e-05
200 5.217792510986328 0.16071428571428573 1.838813151563753e-05
250 5.223909854888916 0.20535714285714285 1.7987169206094627e-05

。。。。。

2250 5.031280040740967 0.14285714285714285 1.948676824378509e-06
2300 4.822522163391113 0.2857142857142857 1.5477145148356058e-06
2350 4.803909778594971 0.25 1.1467522052927025e-06
2400 4.606936931610107 0.26785714285714285 7.457898957497996e-07
2450 4.976705074310303 0.24107142857142858 3.4482758620689656e-07

7.保存训练好的模型 

torch.save(model, '../data//预测最后一个词模型.model')

8. 加载 保存的模型

#加载上一行代码保存的模型
#注意:加载的模型是传送到GPU训练得到的, 在加载时需要改到cpu上-->map_location='cpu'
model2 = torch.load('../data/预测最后一个词模型.model', map_location='cpu')
test(model2)

 

0
tensor([  627,   616,  1486,  4608,   290, 38132,   880,   262,  3900,   336,
          890,   428,   764,   428,   837,  1377])
tensor([  286,   262,   318,  3988,   837,  3807,   257,   262,   705, 14397,
         3807,   262,   621,   262,   290,   326])
10
tensor([11815,   326,   663,  7464,   340,  3898,   287,    82,   257,   546,
         3281,   262, 16631,  3807,   428,  2646])
tensor([7635,  286,  663, 3807,  286, 3898,  287,   82,  257,  257, 1146,  262,
         837,  837,  262, 2646])
20
tensor([  546,  1312,   307,   340,   262,   422,  1049, 11648,   640,  1267,
         2089,  1683,   800,  1502,   355,   475])
tensor([ 345,  340,  307,  340,  262,  837, 2646, 3807,  262, 1267, 2089,  705,
        6275,  262,  355,  475])
30
tensor([   82, 19377,   764,   837,  3316,  1751,   508,   809,  1621,  3755,
           12,  4681,  2071,  1039, 48133,   290])
tensor([   82,   257,   326,   837,  2860,   290,   508,   705,  2646,  2567,
        48133, 20170,   555,  1039, 48133,   290])
40
tensor([ 3704,   705,  2589, 36138,   534,   503,   262, 20024,  8591,   290,
          788,  3923,  3807,  8925,  1128,   764])
tensor([  898,   423,  1218,   772,   534,   345,   262, 20024,   262,   290,
          257,  1692,  2646,  2568,   837,   837])
50
tensor([  837,  5581,   764, 21981,   287,    12,  4379,   318,   705,   286,
         2962, 10997,  3146,   717,   764,  1165])
tensor([  837,  3159,   326,   257,   837,   288,   257,   318,   705,   286,
        21452, 10512,  1438,   262,   326,   257])
accuracy:  0.25612745098039214
no movement , no yuks
 ,  ,

whether seen on a 10-inch
 television  screen

a taut , intelligent psychological drama
 .  that

there are times when a rumor of
 angels  a

greene delivers a typically solid performance
 in  ,

some movies are like a tasty hors
-  d

the visuals alone make metropolis worth
 seeing  a

an experience so engrossing it
 is  is

 

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

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

相关文章

论文笔记:Gradient Episodic Memory for Continual Learning

1. Contribution 提出了一组指标来评估模型在连续数据上的学习情况。这些指标不仅通过测试准确性来表征模型&#xff0c;还通过其跨任务迁移知识的能力来表征模型。针对持续学习任务&#xff0c;提出了GEM模型&#xff08;Gradient Episodic Memory&#xff09;&#xff0c;它…

True NAS禁用ipv6

在 TrueNAS Scale 中&#xff0c;禁用 IPv6 的方法如下&#xff1a;12 进入 System->Advanced->Sysctl&#xff0c;设置一个 sysctl 可调整变量 net.ipv6.conf.all.disable_ipv6&#xff0c;值为 1&#xff0c;以完全禁用 IPv6。\

SOMEIP_ETS_139: SD_Options_Array_too_short

测试目的&#xff1a; 验证DUT能够拒绝一个选项数组长度短于所需的SubscribeEventgroup消息&#xff0c;并以SubscribeEventgroupNAck作为响应。 描述 本测试用例旨在确保DUT遵循SOME/IP协议&#xff0c;当接收到一个选项数组长度不足以包含所有必需选项的SubscribeEventgro…

【C++篇】启航——初识C++(上篇)

目录 引言 一、C的起源和发展史 1.起源 2.C版本更新 二、C在⼯作领域中的应⽤ 三、C入门建议 1.参考文档 2.推荐书籍 四、C的第一个程序 1.C语言写法 2.C写法 五、命名空间 1.为什么要有命名空间 2.定义命名空间 3.主要特点 4.使用示例 六、C输⼊&输出 …

【muduo源码分析】「阻塞」「非阻塞」「同步」「异步」

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 引言何为「muduo库」安装muduo库阻塞、非阻塞、同步、异步数据准备数据准备 引言 从本篇博客开始&#xff0c;我会陆续发表muduo库源码分析的相关文章。感谢大家的持续关注&#xff01;&#xff01;…

Vue|插件

在 Vue.js 中&#xff0c;插件是用来扩展 Vue 功能的一种方式&#xff0c;能够帮助开发者扩展和复用功能。通过合理使用插件&#xff0c;可以提高代码的组织性和可维护性 目录 如何使用插件?插件的定义创建及使用插件插件的参数插件的扩展 总结 如何使用插件? 插件的定义 插…

2-107 基于matlab的hsv空间双边滤波去雾图像增强算法

基于matlab的hsv空间双边滤波去雾图像增强算法&#xff0c;原始图像经过光照增强后&#xff0c;将RGB转成hsv&#xff0c;进行图像增强处理&#xff0c;使图像更加清晰。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a; 2-107 基于matlab的hsv空间双边滤…

论文阅读 | 可证安全隐写(网络空间安全科学学报 2023)

可证安全隐写&#xff1a;理论、应用与展望 一、什么是可证安全隐写&#xff1f; 对于经验安全的隐写算法&#xff0c;即使其算法设计得相当周密&#xff0c;隐写分析者&#xff08;攻击者&#xff09;在观察了足够数量的载密&#xff08;含有隐写信息的数据&#xff09;和载体…

推荐4款2024年热门的PDF转ppt工具

有时候&#xff0c;我们为了方便&#xff0c;需要将PDF里面的内容直接转换的PPT的格式&#xff0c;既方便自己演示和讲解&#xff0c;也让我们可以更加灵活的进行文件的编辑和修改。如果大家不知道要如何进行操作的话&#xff0c;我可以为大家推荐几个比窘方便实用的PDF转换工具…

html TAB、table生成

1. 代码 <!DOCTYPE html> <head> <meta charset"UTF-8"> <title>Dynamic Tabs with Table Data</title> <style> /* 简单的样式 */ .tab-content { display: none; border: 10px solid #ccc; padding: 30px; mar…

赛氪作媒体支持单位受邀参加首届科普翻译与跨学科专业学术研讨会

2024年9月22日&#xff0c;正值全国科普日之际&#xff0c;首届科普翻译与跨学科专业学术研讨会在上海健康与营养研究所信息中心励志厅成功举行并圆满结束。此次研讨会汇聚了来自全国各地的近60名专家学者、学界及企业界代表&#xff0c;共同探讨科普翻译与跨学科专业的发展。作…

BaseCTF2024 web

Web [Week1] HTTP 是什么呀 GET: ?basectf%77%65%31%63%25%30%30%6d%65POST: BaseflgX-Forwarded-For:127.0.0.1Referer: BaseCookie: c00k13i cant eat itUser-Agent: Base有Location跳转, 抓包得到flag: QmFzZUNURntkZGUzZjA0Yy1hMDg5LTQwNGMtOTFjNi01ODZjMzAxMzM3Y2J9Cg…

Springboot jPA+thymeleaf实现增删改查

项目结构 pom文件 配置相关依赖&#xff1a; 2.thymeleaf有点类似于jstlel th:href"{url}表示这是一个链接 th:each"user : ${users}"相当于foreach&#xff0c;对user进行循环遍历 th:if进行if条件判断 {变量} 与 ${变量}的区别: 4.配置好application.ym…

基于SpringBoot+Vue+MySQL的体育商城系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网的飞速发展&#xff0c;电子商务已成为人们日常生活中不可或缺的一部分。体育用品市场作为其中的一个重要分支&#xff0c;也逐渐向线上转移。基于SpringBootVueMySQL的体育商城系统应运而生&#xff0c;旨在通过构建…

E34.【C语言】位段练习题

1.题目 分析下列代码中位段在内存中的排布(已知测试平台为VS2022) struct S {int a : 2;int b : 5;int c : 10;int d : 30; };int main() {struct S s { 0 };return 0; } 有关位段的知识点见64.【C语言】再议结构体(下)文 2.提示 VS满足:由低地址向高地址存储,按浪费空间…

Halo 专业版,含推荐码

立即体验 准备好体验 Halo 了吗&#xff1f;你可以查阅我们完整的部署文档&#xff0c;或者在线使用 Demo 进行体验。 部署指南&#xff1a;www.halo.run Halo 专业版在购买界面输入优惠码&#xff1a; lqMawh8t 使用优惠码优惠码购买专业版&#xff0c;单件 7 折&#xff…

【在Linux世界中追寻伟大的One Piece】进程间通信

目录 1 -> 进程间通信介绍 1.1 -> 进程间通信目的 1.2 -> 进程间通信发展 1.3 -> 进程间通信分类 1.3.1 -> 管道 1.3.2 -> System V IPC 1.3.3 -> POSIX IPC 2 -> 管道 2.1 -> 什么是管道 2.2 -> 匿名管道 2.3 -> 实例代码 2.4 -…

Java | Leetcode Java题解之第436题寻找右区间

题目&#xff1a; 题解&#xff1a; class Solution {public int[] findRightInterval(int[][] intervals) {int n intervals.length;int[][] startIntervals new int[n][2];int[][] endIntervals new int[n][2];for (int i 0; i < n; i) {startIntervals[i][0] inter…

回归预测 | Matlab基于SO-SVR蛇群算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于SO-SVR蛇群算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SO-SVR蛇群算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于SO-SVR蛇群算法优化支持向量机的数据多…

828华为云征文|华为云Flexus云服务器X实例——部署EduSoho网校系统、二次开发对接华为云视频点播实现CDN加速播放

EduSoho 是一款功能强大的网校系统&#xff0c;能够帮助教育机构快速搭建在线学习平台。本文将详细介绍如何在华为云服务器上安装和部署 EduSoho 网校系统&#xff0c;以及二次开发对接华为云视频点播VOD来实现CDN加速播放。 edusoho本地存储的视频播放存在诸多弊端。一方面&a…