【PaddleNLP】千言数据集:情感分析——SKEP

本项目使用预训练模型SKEP完成千言数据集:情感分析比赛
包含三种子任务,句子级情感分类、评价对象级情感分类、观点抽取
欢迎大家点赞、fork、关注!

重磅更新!!!

2021/6/24   V1.5   新增👉Ernie_gram和SKEP预测结果融合(评价对象提取任务)👈   效果显著!!!

若需要Ernie_gram观点提取教程,请参考 江流:【paddlenlp】千言数据集:情感分析
别忘了给他也点个star和fork哦!!!

前言

大家好
该比赛为NLP打卡营的大作业。以下为通过本次课程所学内容,实现情感分析任务的代码。




先上结果:
图片名称




刚刚入门+没有任何机器学习的基础,还有很大的调参和处理空间。

强烈推荐大家参考以下源码:

  • SKEP example非常重要!!!
  • load_dataset
  • 可以给上面PaddleNLP的链接点个star哦!

发现的好东西,但还没使用:VisualDL2.2可以实现超参可视化

数据集准备

把所有数据集压缩包放在work文件夹下

# 解压数据集到data文件夹, 注意每次打开都要执行,重启无需执行
!unzip -q work/ChnSentiCorp.zip -d data
!unzip -q work/NLPCC14-SC.zip -d data
!unzip -q work/SE-ABSA16_CAME.zip -d data
!unzip -q work/SE-ABSA16_PHNS.zip -d data
!unzip -q work/COTE-BD.zip -d data
!unzip -q work/COTE-DP.zip -d data
!unzip -q work/COTE-MFW.zip -d data
# 更新paddlenlp
!pip install --upgrade paddlenlp -i https://pypi.org/simple 

一、 句子级情感分析

对给定的一段文本进行情感极性分类,常用于影评分析、网络论坛舆情分析等场景。

数据读入–句子级数据

包含:

  • load_ds:可从训练集划分验证集
  • load_test:读入test
import os
import random
from paddlenlp.datasets import MapDataset# for train and dev sets
def load_ds(datafiles, split_train=False, dev_size=0):'''intput:datafiles -- str or list[str] -- the path of train or dev setssplit_train -- Boolean -- split from train or notdev_size -- int -- split how much data from train output:MapDataset'''datas = []def read(ds_file):with open(ds_file, 'r', encoding='utf-8') as fp:next(fp)  # Skip headerfor line in fp.readlines():data = line[:-1].split('\t')if len(data)==2:yield ({'text':data[1], 'label':int(data[0])})elif len(data)==3:yield ({'text':data[2], 'label':int(data[1])})def write_tsv(tsv, datas):with open(tsv, mode='w', encoding='UTF-8') as f:for line in datas:f.write(line)# 从train切出一部分给devdef spilt_train4dev(train_ds, dev_size):with open(train_ds, 'r', encoding='UTF-8') as f:for i, line in enumerate(f):datas.append(line)datas_tmp=datas[1:] # title line should not shufflerandom.shuffle(datas_tmp) if 1-os.path.exists(os.path.dirname(train_ds)+'/tem'):os.mkdir(os.path.dirname(train_ds)+'/tem')# remember the title linewrite_tsv(os.path.dirname(train_ds)+'/tem/train.tsv', datas[0:1]+datas_tmp[:-dev_size])write_tsv(os.path.dirname(train_ds)+'/tem/dev.tsv', datas[0:1]+datas_tmp[-dev_size:])if split_train:if 1-isinstance(datafiles, str):print("If you want to split the train, make sure that \'datafiles\' is a train set path str.")return Noneif dev_size == 0:print("Please set size of dev set, as dev_size=...")return Nonespilt_train4dev(datafiles, dev_size)datafiles = [os.path.dirname(datafiles)+'/tem/train.tsv', os.path.dirname(datafiles)+'/tem/dev.tsv']if isinstance(datafiles, str):return MapDataset(list(read(datafiles)))elif isinstance(datafiles, list) or isinstance(datafiles, tuple):return [MapDataset(list(read(datafile))) for datafile in datafiles]def load_test(datafile):'''intput:datafile -- str -- the path of test set output:MapDataset'''def read(test_file):with open(test_file, 'r', encoding='UTF-8') as f:for i, line in enumerate(f):if i==0:continuedata = line[:-1].split('\t')yield {'text':data[1], 'label':'', 'qid':data[0]}return MapDataset(list(read(datafile)))

1. ChnSentiCorp

一次只能执行一个数据集!!!
32 256 2e-5 6

# 可以直接使用官方的load_dataset更加方便
# 本文将从train分出一部分做dev,为统一格式,故采用自己定义的load函数# from paddlenlp.datasets import load_dataset
# train_ds, dev_ds, test_ds = load_dataset("chnsenticorp", splits=["train", "dev", "test"])
train_ds, dev_ds= load_ds(datafiles=['./data/ChnSentiCorp/train.tsv', './data/ChnSentiCorp/dev.tsv'])
print(train_ds[0])
print(dev_ds[0])
print(type(train_ds[0]))test_ds = load_test(datafile='./data/ChnSentiCorp/test.tsv')
print(test_ds[0])

2. NLPCC14-SC

train_ds, dev_ds = load_ds(datafiles='./data/NLPCC14-SC/train.tsv', split_train=True, dev_size=1000)
print(train_ds[0])
print(dev_ds[0])
test_ds = load_test(datafile='./data/NLPCC14-SC/test.tsv')
print(test_ds[0])

SKEP模型构建

PaddleNLP已经实现了SKEP预训练模型,可以通过一行代码实现SKEP加载。

句子级情感分析模型是SKEP fine-tune 文本分类常用模型SkepForSequenceClassification。其首先通过SKEP提取句子语义特征,之后将语义特征进行分类。

from paddlenlp.transformers import SkepForSequenceClassification, SkepTokenizer
# num_classes: 两类,0和1,表示消极和积极
model = SkepForSequenceClassification.from_pretrained(pretrained_model_name_or_path="skep_ernie_1.0_large_ch", num_classes=2)
tokenizer = SkepTokenizer.from_pretrained(pretrained_model_name_or_path="skep_ernie_1.0_large_ch")

SkepForSequenceClassification可用于句子级情感分析和目标级情感分析任务。其通过预训练模型SKEP获取输入文本的表示,之后将文本表示进行分类。

  • pretrained_model_name_or_path:模型名称。支持"skep_ernie_1.0_large_ch",“skep_ernie_2.0_large_en”。

    • “skep_ernie_1.0_large_ch”:是SKEP模型在预训练ernie_1.0_large_ch基础之上在海量中文数据上继续预训练得到的中文预训练模型;
    • “skep_ernie_2.0_large_en”:是SKEP模型在预训练ernie_2.0_large_en基础之上在海量英文数据上继续预训练得到的英文预训练模型;
  • num_classes: 数据集分类类别数。

关于SKEP模型实现详细信息参考:https://github.com/PaddlePaddle/PaddleNLP/tree/develop/paddlenlp/transformers/skep

import os
from functools import partialimport numpy as np
import paddle
import paddle.nn.functional as F
from paddlenlp.data import Stack, Tuple, Padfrom utils import create_dataloaderdef convert_example(example,tokenizer,max_seq_length=512,is_test=False):"""Builds model inputs from a sequence or a pair of sequence for sequence classification tasksby concatenating and adding special tokens. And creates a mask from the two sequences passed to be used in a sequence-pair classification task.A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence has the following format:::- single sequence: ``[CLS] X [SEP]``- pair of sequences: ``[CLS] A [SEP] B [SEP]``A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence pair mask has the following format:::0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1| first sequence    | second sequence |If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s).Args:example(obj:`list[str]`): List of input data, containing text and label if it have label.tokenizer(obj:`PretrainedTokenizer`): This tokenizer inherits from :class:`~paddlenlp.transformers.PretrainedTokenizer` which contains most of the methods. Users should refer to the superclass for more information regarding methods.max_seq_len(obj:`int`): The maximum total input sequence length after tokenization. Sequences longer than this will be truncated, sequences shorter will be padded.is_test(obj:`False`, defaults to `False`): Whether the example contains label or not.Returns:input_ids(obj:`list[int]`): The list of token ids.token_type_ids(obj: `list[int]`): List of sequence pair mask.label(obj:`int`, optional): The input label if not is_test."""encoded_inputs = tokenizer(text=example["text"], max_seq_len=max_seq_length)input_ids = encoded_inputs["input_ids"]token_type_ids = encoded_inputs["token_type_ids"]if not is_test:label = np.array([example["label"]], dtype="int64")return input_ids, token_type_ids, labelelse:qid = np.array([example["qid"]], dtype="int64")return input_ids, token_type_ids, qidbatch_size = 32
max_seq_length = 256
trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length)
batchify_fn = lambda samples, fn=Tuple(Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input_idsPad(axis=0, pad_val=tokenizer.pad_token_type_id),  # token_type_idsStack()  # labels
): [data for data in fn(samples)]train_data_loader = create_dataloader(train_ds,mode='train',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)
dev_data_loader = create_dataloader(dev_ds,mode='dev',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)

模型训练和评估(把每个数据集的结果分开存!!!)

定义损失函数、优化器以及评价指标后,即可开始训练。

推荐超参设置:

  • max_seq_length=256
  • batch_size=32
  • learning_rate=2e-5
  • epochs=10

实际运行时可以根据显存大小调整batch_size和max_seq_length大小。

import timefrom utils import evaluateepochs = 10
ckpt_dir = "skep_sentence"
num_training_steps = len(train_data_loader) * epochs# optimizer = paddle.optimizer.AdamW(
#     learning_rate=2e-5,
#     parameters=model.parameters())decay_params = [p.name for n, p in model.named_parameters()if not any(nd in n for nd in ["bias", "norm"])]
optimizer = paddle.optimizer.AdamW(learning_rate=2e-6,parameters=model.parameters(),weight_decay=0.01, # test weight_decayapply_decay_param_fun=lambda x: x in decay_params # test weight_decay)criterion = paddle.nn.loss.CrossEntropyLoss()
metric = paddle.metric.Accuracy()global_step = 0
tic_train = time.time()
for epoch in range(1, epochs + 1):for step, batch in enumerate(train_data_loader, start=1):input_ids, token_type_ids, labels = batchlogits = model(input_ids, token_type_ids)loss = criterion(logits, labels)probs = F.softmax(logits, axis=1)correct = metric.compute(probs, labels)metric.update(correct)acc = metric.accumulate()global_step += 1if global_step % 10 == 0:print("global step %d, epoch: %d, batch: %d, loss: %.5f, accu: %.5f, speed: %.2f step/s"% (global_step, epoch, step, loss, acc,10 / (time.time() - tic_train)))tic_train = time.time()loss.backward()optimizer.step()optimizer.clear_grad()if global_step % 100 == 0:save_dir = os.path.join(ckpt_dir, "model_%d" % global_step)if not os.path.exists(save_dir):os.makedirs(save_dir)evaluate(model, criterion, metric, dev_data_loader) model.save_pretrained(save_dir)tokenizer.save_pretrained(save_dir)

预测结果(注意更改模型的路径)

使用训练得到的模型还可以对文本进行情感预测。

import numpy as np
import paddlebatch_size=24trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length,is_test=True)
batchify_fn = lambda samples, fn=Tuple(Pad(axis=0, pad_val=tokenizer.pad_token_id),  # inputPad(axis=0, pad_val=tokenizer.pad_token_type_id),  # segmentStack() # qid
): [data for data in fn(samples)]
test_data_loader = create_dataloader(test_ds,mode='test',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)# 根据实际运行情况,更换加载的参数路径
params_path = 'skep_sentence2t_weight_2e-6/model_1800_83700/model_state.pdparams'
if params_path and os.path.isfile(params_path):state_dict = paddle.load(params_path)model.set_dict(state_dict)print("Loaded parameters from %s" % params_path)label_map = {0: '0', 1: '1'}
results = []
model.eval()
for batch in test_data_loader:input_ids, token_type_ids, qids = batchlogits = model(input_ids, token_type_ids)probs = F.softmax(logits, axis=-1)idx = paddle.argmax(probs, axis=1).numpy()idx = idx.tolist()labels = [label_map[i] for i in idx]qids = qids.numpy().tolist()results.extend(zip(qids, labels))res_dir = "./results/2_weight_2e-6/1800_83700"
if not os.path.exists(res_dir):os.makedirs(res_dir)with open(os.path.join(res_dir, "NLPCC14-SC.tsv"), 'w', encoding="utf8") as f:f.write("index\tprediction\n")for qid, label in results:f.write(str(qid[0])+"\t"+label+"\n")

二、 目标级情感分析

在电商产品分析场景下,除了分析整体商品的情感极性外,还细化到以商品具体的“方面”为分析主体进行情感分析(aspect-level),如下、:

  • 这个薯片口味有点咸,太辣了,不过口感很脆。

关于薯片的口味方面是一个负向评价(咸,太辣),然而对于口感方面却是一个正向评价(很脆)。

  • 我很喜欢夏威夷,就是这边的海鲜太贵了。

关于夏威夷是一个正向评价(喜欢),然而对于夏威夷的海鲜却是一个负向评价(价格太贵)。

数据读入–目标级数据集

与句子级方法类似

import os
import randomfrom paddlenlp.datasets import MapDatasetdef load_ds(datafiles, split_train=False, dev_size=0):datas = []def read(ds_file):with open(ds_file, 'r', encoding='utf-8') as fp:# if fp.readline().split('\t')[0] == 'label':next(fp)  # Skip headerfor line in fp.readlines():data = line[:-1].split('\t')yield ({'text':data[1], 'text_pair':data[2], 'label':int(data[0])})def write_tsv(tsv, datas):with open(tsv, mode='w', encoding='UTF-8') as f:for line in datas:f.write(line)def spilt_train4dev(train_ds, dev_size):with open(train_ds, 'r', encoding='UTF-8') as f:for i, line in enumerate(f):datas.append(line)datas_tmp=datas[1:] # title line should not shufflerandom.shuffle(datas_tmp) if 1-os.path.exists(os.path.dirname(train_ds)+'/tem'):os.mkdir(os.path.dirname(train_ds)+'/tem')# remember the title linewrite_tsv(os.path.dirname(train_ds)+'/tem/train.tsv', datas[0:1]+datas_tmp[:-dev_size])write_tsv(os.path.dirname(train_ds)+'/tem/dev.tsv', datas[0:1]+datas_tmp[-dev_size:])if split_train:if 1-isinstance(datafiles, str):print("If you want to split the train, make sure that \'datafiles\' is a train set path str.")return Noneif dev_size == 0:print("Please set size of dev set, as dev_size=...")return Nonespilt_train4dev(datafiles, dev_size)datafiles = [os.path.dirname(datafiles)+'/tem/train.tsv', os.path.dirname(datafiles)+'/tem/dev.tsv']if isinstance(datafiles, str):return MapDataset(list(read(datafiles)))elif isinstance(datafiles, list) or isinstance(datafiles, tuple):return [MapDataset(list(read(datafile))) for datafile in datafiles]def load_test(datafile):def read(test_file):with open(test_file, 'r', encoding='UTF-8') as f:for i, line in enumerate(f):if i==0:continuedata = line[:-1].split('\t')yield {'text':data[1], 'text_pair':data[2]}return MapDataset(list(read(datafile)))

3. SE-ABSA16_PHNS

一次只能执行一个数据集!!!

train_ds, dev_ds = load_ds(datafiles='./data/SE-ABSA16_PHNS/train.tsv', split_train=True, dev_size=100)
print(train_ds[0])
print(dev_ds[0])test_ds = load_test(datafile='./data/SE-ABSA16_PHNS/test.tsv')
print(test_ds[0])

4. SE-ABSA16_CAME

train_ds, dev_ds = load_ds(datafiles='./data/SE-ABSA16_CAME/train.tsv', split_train=True, dev_size=100)
print(train_ds[0])
print(dev_ds[0])test_ds = load_test(datafile='./data/SE-ABSA16_CAME/test.tsv')
print(test_ds[0])

SKEP模型构建

目标级情感分析模型同样使用SkepForSequenceClassification模型,但目标级情感分析模型的输入不单单是一个句子,而是句对。一个句子描述“评价对象方面(aspect)”,另一个句子描述"对该方面的评论"。如下图所示。

from paddlenlp.transformers import SkepForSequenceClassification, SkepTokenizer
# num_classes: 两类,0和1,表示消极和积极
model = SkepForSequenceClassification.from_pretrained('skep_ernie_1.0_large_ch', num_classes=2)
tokenizer = SkepTokenizer.from_pretrained('skep_ernie_1.0_large_ch')
from functools import partial
import os
import timeimport numpy as np
import paddle
import paddle.nn.functional as F
from paddlenlp.data import Stack, Tuple, Padfrom utils import create_dataloaderdef convert_example(example,tokenizer,max_seq_length=512,is_test=False,dataset_name="chnsenticorp"):"""Builds model inputs from a sequence or a pair of sequence for sequence classification tasksby concatenating and adding special tokens. And creates a mask from the two sequences passed to be used in a sequence-pair classification task.A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence has the following format:::- single sequence: ``[CLS] X [SEP]``- pair of sequences: ``[CLS] A [SEP] B [SEP]``A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence pair mask has the following format:::0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1| first sequence    | second sequence |If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s).note: There is no need token type ids for skep_roberta_large_ch model.Args:example(obj:`list[str]`): List of input data, containing text and label if it have label.tokenizer(obj:`PretrainedTokenizer`): This tokenizer inherits from :class:`~paddlenlp.transformers.PretrainedTokenizer` which contains most of the methods. Users should refer to the superclass for more information regarding methods.max_seq_len(obj:`int`): The maximum total input sequence length after tokenization. Sequences longer than this will be truncated, sequences shorter will be padded.is_test(obj:`False`, defaults to `False`): Whether the example contains label or not.dataset_name((obj:`str`, defaults to "chnsenticorp"): The dataset name, "chnsenticorp" or "sst-2".Returns:input_ids(obj:`list[int]`): The list of token ids.token_type_ids(obj: `list[int]`): List of sequence pair mask.label(obj:`numpy.array`, data type of int64, optional): The input label if not is_test."""encoded_inputs = tokenizer(text=example["text"],text_pair=example["text_pair"],max_seq_len=max_seq_length)input_ids = encoded_inputs["input_ids"]token_type_ids = encoded_inputs["token_type_ids"]if not is_test:label = np.array([example["label"]], dtype="int64")return input_ids, token_type_ids, labelelse:return input_ids, token_type_idsmax_seq_length=512
batch_size=16
trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length)
batchify_fn = lambda samples, fn=Tuple(Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input_idsPad(axis=0, pad_val=tokenizer.pad_token_type_id),  # token_type_idsStack(dtype="int64")  # labels
): [data for data in fn(samples)]train_data_loader = create_dataloader(train_ds,mode='train',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)
dev_data_loader = create_dataloader(dev_ds,mode='dev',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)

模型训练和评估

定义损失函数、优化器以及评价指标后,即可开始训练。

from utils import evaluateepochs = 12
num_training_steps = len(train_data_loader) * epochs# optimizer = paddle.optimizer.AdamW(
#     learning_rate=2e-6,
#     parameters=model.parameters())decay_params = [p.name for n, p in model.named_parameters()if not any(nd in n for nd in ["bias", "norm"])]
optimizer = paddle.optimizer.AdamW(learning_rate=1e-6,parameters=model.parameters(),weight_decay=0.01, # test weight_decayapply_decay_param_fun=lambda x: x in decay_params # test weight_decay)criterion = paddle.nn.loss.CrossEntropyLoss()
metric = paddle.metric.Accuracy()ckpt_dir = "skep_aspect"
global_step = 0
tic_train = time.time()
for epoch in range(1, epochs + 1):for step, batch in enumerate(train_data_loader, start=1):input_ids, token_type_ids, labels = batchlogits = model(input_ids, token_type_ids)loss = criterion(logits, labels)probs = F.softmax(logits, axis=1)correct = metric.compute(probs, labels)metric.update(correct)acc = metric.accumulate()global_step += 1if global_step % 10 == 0:print("global step %d, epoch: %d, batch: %d, loss: %.5f, accu: %.5f, speed: %.2f step/s"% (global_step, epoch, step, loss, acc,10 / (time.time() - tic_train)))tic_train = time.time()loss.backward()optimizer.step()optimizer.clear_grad()if global_step % 50 == 0:save_dir = os.path.join(ckpt_dir, "model_%d" % global_step)if not os.path.exists(save_dir):os.makedirs(save_dir)#这里的evaluate直接复制的上面项目的,可能不对evaluate(model, criterion, metric, dev_data_loader)model.save_pretrained(save_dir)tokenizer.save_pretrained(save_dir)

预测结果

使用训练得到的模型还可以对评价对象进行情感预测。

@paddle.no_grad()
def predict(model, data_loader, label_map):"""Given a prediction dataset, it gives the prediction results.Args:model(obj:`paddle.nn.Layer`): A model to classify texts.data_loader(obj:`paddle.io.DataLoader`): The dataset loader which generates batches.label_map(obj:`dict`): The label id (key) to label str (value) map."""model.eval()results = []for batch in data_loader:input_ids, token_type_ids = batchlogits = model(input_ids, token_type_ids)probs = F.softmax(logits, axis=1)idx = paddle.argmax(probs, axis=1).numpy()idx = idx.tolist()labels = [label_map[i] for i in idx]results.extend(labels)return resultslabel_map = {0: '0', 1: '1'}
trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length,is_test=True)
batchify_fn = lambda samples, fn=Tuple(Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input_idsPad(axis=0, pad_val=tokenizer.pad_token_type_id),  # token_type_ids
): [data for data in fn(samples)]batch_size=16test_data_loader = create_dataloader(test_ds,mode='test',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)# 根据实际运行情况,更换加载的参数路径
params_path = 'skep_aspect4_weight_1e-6/model_500_73000/model_state.pdparams'
if params_path and os.path.isfile(params_path):state_dict = paddle.load(params_path)model.set_dict(state_dict)print("Loaded parameters from %s" % params_path)results = predict(model, test_data_loader, label_map)res_dir = "./results/4_weight_1e-6/500_73000"
if not os.path.exists(res_dir):os.makedirs(res_dir)with open(os.path.join(res_dir, "SE-ABSA16_CAME.tsv"), 'w', encoding="utf8") as f:f.write("index\tprediction\n")for idx, label in enumerate(results):f.write(str(idx)+"\t"+label+"\n")

三、 评价对象提取

数据读入–对象数据集

对象 = [ ]
😦

import os
import random
from paddlenlp.datasets import MapDatasetdef load_ds(datafiles, split_train=False, dev_size=0):datas = []def read(ds_file):with open(ds_file, 'r', encoding='utf-8') as fp:# if fp.readline().split('\t')[0] == 'label':next(fp)  # Skip headerfor line in fp.readlines():# print('1\n')line_stripped = line.strip().split('\t')if not line_stripped:continue# dataset 中有 entity和text不在一行的。。。。。try:example = [line_stripped[indice] for indice in (0,1)]entity, text = example[0], example[1]start_idx = text.index(entity)except:# drop the dirty datacontinuelabels = [2] * len(text)labels[start_idx] = 0for idx in range(start_idx + 1, start_idx + len(entity)):labels[idx] = 1 yield {"tokens": list(text),"labels": labels,"entity": entity}def write_tsv(tsv, datas):with open(tsv, mode='w', encoding='UTF-8') as f:for line in datas:f.write(line)def spilt_train4dev(train_ds, dev_size):with open(train_ds, 'r', encoding='UTF-8') as f:for i, line in enumerate(f):datas.append(line)datas_tmp=datas[1:] # title line should not shufflerandom.shuffle(datas_tmp) if 1-os.path.exists(os.path.dirname(train_ds)+'/tem'):os.mkdir(os.path.dirname(train_ds)+'/tem')# remember the title linewrite_tsv(os.path.dirname(train_ds)+'/tem/train.tsv', datas[0:1]+datas_tmp[:-dev_size])write_tsv(os.path.dirname(train_ds)+'/tem/dev.tsv', datas[0:1]+datas_tmp[-dev_size:])if split_train:if 1-isinstance(datafiles, str):print("If you want to split the train, make sure that \'datafiles\' is a train set path str.")return Noneif dev_size == 0:print("Please set size of dev set, as dev_size=...")return Nonespilt_train4dev(datafiles, dev_size)datafiles = [os.path.dirname(datafiles)+'/tem/train.tsv', os.path.dirname(datafiles)+'/tem/dev.tsv']if isinstance(datafiles, str):return MapDataset(list(read(datafiles)))elif isinstance(datafiles, list) or isinstance(datafiles, tuple):return [MapDataset(list(read(datafile))) for datafile in datafiles]def load_test(datafile):def read(test_file):with open(test_file, 'r', encoding='UTF-8') as fp:# if fp.readline().split('\t')[0] == 'label':next(fp)  # Skip headerfor line in fp.readlines():# print('1\n')line_stripped = line.strip().split('\t')if not line_stripped:continue# example = [line_stripped[indice] for indice in field_indices]# example = [line_stripped[indice] for indice in (0,1)]# dataset 中有 entity和text不在一行的。。。。。try:example = [line_stripped[indice] for indice in (0,1)]entity, text = example[0], example[1]except:# drop the dirty datacontinueyield {"tokens": list(text)}return MapDataset(list(read(datafile)))

5. COTE-DP

train_ds = load_ds(datafiles='./data/COTE-DP/train.tsv')
print(train_ds[0])
test_ds = load_test(datafile='./data/COTE-DP/test.tsv')
print(test_ds[0])

6. COTE-BD

train_ds = load_ds(datafiles='./data/COTE-BD/train.tsv')
print(train_ds[0])
test_ds = load_test(datafile='./data/COTE-BD/test.tsv')
print(test_ds[0])

7. COTE-MFW

train_ds = load_ds(datafiles='./data/COTE-MFW/train.tsv')
print(train_ds[1])
test_ds = load_test(datafile='./data/COTE-MFW/test.tsv')
print(test_ds[0])

SKEP模型构建

和上面的有些不一样

from paddlenlp.transformers import SkepCrfForTokenClassification, SkepTokenizer, SkepModel
# num_classes: 三类,B/I/O
skep = SkepModel.from_pretrained('skep_ernie_1.0_large_ch')
model = SkepCrfForTokenClassification(skep, num_classes=3)
tokenizer = SkepTokenizer.from_pretrained(pretrained_model_name_or_path="skep_ernie_1.0_large_ch")
# # The COTE_DP dataset labels with "BIO" schema.
# label_map = {label: idx for idx, label in enumerate(train_ds.label_list)}
# # `no_entity_label` represents that the token isn't an entity.
# # print(type(no_entity_label_idx))
no_entity_label_idx = 2from functools import partial
import os
import timeimport numpy as np
import paddleimport paddle.nn.functional as F
from paddlenlp.data import Stack, Tuple, Padfrom utils import create_dataloaderdef convert_example_to_feature(example,tokenizer,max_seq_len=512,no_entity_label="O",is_test=False):"""Builds model inputs from a sequence or a pair of sequence for sequence classification tasksby concatenating and adding special tokens. And creates a mask from the two sequences passed to be used in a sequence-pair classification task.A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence has the following format:::- single sequence: ``[CLS] X [SEP]``- pair of sequences: ``[CLS] A [SEP] B [SEP]``A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence pair mask has the following format:::0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1| first sequence    | second sequence |If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s).Args:example(obj:`list[str]`): List of input data, containing text and label if it have label.tokenizer(obj:`PretrainedTokenizer`): This tokenizer inherits from :class:`~paddlenlp.transformers.PretrainedTokenizer` which contains most of the methods. Users should refer to the superclass for more information regarding methods.max_seq_len(obj:`int`): The maximum total input sequence length after tokenization.Sequences longer than this will be truncated, sequences shorter will be padded.no_entity_label(obj:`str`, defaults to "O"): The label represents that the token isn't an entity. is_test(obj:`False`, defaults to `False`): Whether the example contains label or not.Returns:input_ids(obj:`list[int]`): The list of token ids.token_type_ids(obj: `list[int]`): List of sequence pair mask.label(obj:`list[int]`, optional): The input label if not test data."""tokens = example['tokens']labels = example['labels']tokenized_input = tokenizer(tokens,return_length=True,is_split_into_words=True,max_seq_len=max_seq_len)input_ids = tokenized_input['input_ids']token_type_ids = tokenized_input['token_type_ids']seq_len = tokenized_input['seq_len']if is_test:return input_ids, token_type_ids, seq_lenelse:labels = labels[:(max_seq_len - 2)]encoded_label = np.array([no_entity_label] + labels + [no_entity_label], dtype="int64")return input_ids, token_type_ids, seq_len, encoded_labelmax_seq_length=256
batch_size=40
trans_func = partial(convert_example_to_feature,tokenizer=tokenizer,max_seq_len=max_seq_length,no_entity_label=no_entity_label_idx,is_test=False)
batchify_fn = lambda samples, fn=Tuple(Pad(axis=0, pad_val=tokenizer.vocab[tokenizer.pad_token]),  # input idsPad(axis=0, pad_val=tokenizer.vocab[tokenizer.pad_token]),  # token type idsStack(dtype='int64'),  # sequence lensPad(axis=0, pad_val=no_entity_label_idx)  # labels
): [data for data in fn(samples)]train_data_loader = create_dataloader(train_ds,mode='train',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)
# dev_data_loader = create_dataloader(
#     dev_ds,
#     mode='dev',
#     batch_size=batch_size,
#     batchify_fn=batchify_fn,
#     trans_fn=trans_func)

模型训练

import time
from utils import evaluate
from paddlenlp.metrics import ChunkEvaluatorepochs = 10
num_training_steps = len(train_data_loader) * epochs# # test weight_decay
# decay_params = [
#         p.name for n, p in model.named_parameters()
#         if not any(nd in n for nd in ["bias", "norm"])
#     ]
# optimizer = paddle.optimizer.AdamW(
#     learning_rate=1e-5,
#     parameters=model.parameters(),
#     weight_decay=0.01, # test weight_decay
#     apply_decay_param_fun=lambda x: x in decay_params # test weight_decay
#     )optimizer = paddle.optimizer.AdamW(learning_rate=1e-6,parameters=model.parameters(),)# metric = ChunkEvaluator(label_list=train_ds.label_list, suffix=True)
metric = ChunkEvaluator(label_list=['B', 'I', 'O'], suffix=True)ckpt_dir = "skep_opinion7_1e-6"
global_step = 0
tic_train = time.time()
for epoch in range(1, epochs + 1):for step, batch in enumerate(train_data_loader, start=1):input_ids, token_type_ids, seq_lens, labels = batchloss = model(input_ids, token_type_ids, seq_lens=seq_lens, labels=labels)avg_loss = paddle.mean(loss)global_step += 1if global_step % 10 == 0:print("global step %d, epoch: %d, batch: %d, loss: %.5f, speed: %.2f step/s"% (global_step, epoch, step, avg_loss,10 / (time.time() - tic_train)))tic_train = time.time()loss.backward()optimizer.step()optimizer.clear_grad()if global_step % 200 == 0:save_dir = os.path.join(ckpt_dir, "model_%d" % global_step)if not os.path.exists(save_dir):os.makedirs(save_dir)file_name = os.path.join(save_dir, "model_state.pdparam")# Need better way to get inner model of DataParallelpaddle.save(model.state_dict(), file_name)

预测结果

import redef convert_example_to_feature(example, tokenizer, max_seq_length=512, is_test=False):"""Builds model inputs from a sequence or a pair of sequence for sequence classification tasksby concatenating and adding special tokens. And creates a mask from the two sequences passed to be used in a sequence-pair classification task.A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence has the following format:::- single sequence: ``[CLS] X [SEP]``- pair of sequences: ``[CLS] A [SEP] B [SEP]``A skep_ernie_1.0_large_ch/skep_ernie_2.0_large_en sequence pair mask has the following format:::0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1| first sequence    | second sequence |If `token_ids_1` is `None`, this method only returns the first portion of the mask (0s).Args:example(obj:`list[str]`): List of input data, containing text and label if it have label.tokenizer(obj:`PretrainedTokenizer`): This tokenizer inherits from :class:`~paddlenlp.transformers.PretrainedTokenizer` which contains most of the methods. Users should refer to the superclass for more information regarding methods.max_seq_len(obj:`int`): The maximum total input sequence length after tokenization. Sequences longer than this will be truncated, sequences shorter will be padded.Returns:input_ids(obj:`list[int]`): The list of token ids.token_type_ids(obj: `list[int]`): List of sequence pair mask. """tokens = example["tokens"]encoded_inputs = tokenizer(tokens,return_length=True,is_split_into_words=True,max_seq_len=max_seq_length)input_ids = encoded_inputs["input_ids"]token_type_ids = encoded_inputs["token_type_ids"]seq_len = encoded_inputs["seq_len"]return input_ids, token_type_ids, seq_lendef parse_predict_result(predictions, seq_lens, label_map):"""Parses the prediction results to the label tag."""pred_tag = []for idx, pred in enumerate(predictions):seq_len = seq_lens[idx]# drop the "[CLS]" and "[SEP]" tokentag = [label_map[i] for i in pred[1:seq_len - 1]]pred_tag.append(tag)return pred_tag@paddle.no_grad()
def predict(model, data_loader, label_map):"""Given a prediction dataset, it gives the prediction results.Args:model(obj:`paddle.nn.Layer`): A model to classify texts.data_loader(obj:`paddle.io.DataLoader`): The dataset loader which generates batches.label_map(obj:`dict`): The label id (key) to label str (value) map."""model.eval()results = []for input_ids, token_type_ids, seq_lens in data_loader:preds = model(input_ids, token_type_ids, seq_lens=seq_lens)tags = parse_predict_result(preds.numpy(), seq_lens.numpy(), label_map)results.extend(tags)return results# The COTE_DP dataset labels with "BIO" schema.
label_map = {0: "B", 1: "I", 2: "O"}
# `no_entity_label` represents that the token isn't an entity. 
no_entity_label_idx = 2batch_size=96trans_func = partial(convert_example_to_feature,tokenizer=tokenizer,max_seq_length=max_seq_length)
batchify_fn = lambda samples, fn=Tuple(Pad(axis=0, pad_val=tokenizer.vocab[tokenizer.pad_token]),  # input idsPad(axis=0, pad_val=tokenizer.vocab[tokenizer.pad_token]),  # token type idsStack(dtype='int64'),  # sequence lens
): [data for data in fn(samples)]test_data_loader = create_dataloader(test_ds,mode='test',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)# 根据实际运行情况,更换加载的参数路径,!!!注意有没有加载成功!!!
params_path = 'skep_opinion7_1e-6/model_10200_10/model_state.pdparam'
if params_path and os.path.isfile(params_path):state_dict = paddle.load(params_path)model.set_dict(state_dict)print("Loaded parameters from %s" % params_path)
else:print("MODEL LOAD FAILURE")exitresults = predict(model, test_data_loader, label_map)# 处理符号
punc = '~`!#$%^&*()_+-=|\';":/.,?><~·!@#¥%……&*()——+-=“:’;、。,?》《{}'res_dir = "./results/7_1e-6/10200_10"
if not os.path.exists(res_dir):os.makedirs(res_dir)with open(os.path.join(res_dir, "COTE_MFW.tsv"), 'w', encoding="utf8") as f:f.write("index\tprediction\n")for idx, example in enumerate(test_ds.data):tag = []# to find "B...I...I"for idx1, letter in enumerate(results[idx]):if letter == 'B':i = idx1try:while(results[idx][i+1]=='I'):i = i+1except:passtag.append(re.sub(r"[%s]+" %punc, "", "".join(example['tokens'][idx1:i+1])))if tag == []:# 找不到实体要预测为无,不然比赛对比会异常tag.append('无')f.write(str(idx)+"\t"+"\x01".join(tag)+"\n")

提交

将预测文件结果压缩至zip文件,提交千言比赛网站

总结

本项目为PaddleNLP打卡营的大作业,包含以下不足:
没用交叉检验,直接从训练集拿出一部分做验证集
没有对数据进行分析和处理
不会调参(没经验)

这个项目是本人第一个用Paddle完成的项目,也是第一个深度学习的项目。
通过实践学习到了很多,也发现还有很多要学习的。项目中有不足的地方,还望大家在评论区中指出。
也欢迎大家点赞、fork、关注!

我在AI Studio上获得白银等级,点亮4个徽章,来互关呀~ https://aistudio.baidu.com/aistudio/personalcenter/thirdview/815060

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 《SQL必知必会》拾遗 原创 Django Java工程师成长日记

    《SQL必知必会》拾遗 原创 Django Java工程师成长日记 2018-07-30 数据库&#xff08;database&#xff09; 保存有组织的数据的容器&#xff08;通常是一个文件或一组文件&#xff09;。 表&#xff08;table&#xff09; 某种特定类型数据的结构化清单。 模式 关于数据库和…...

    2024/4/5 5:46:56
  2. 给模板传递数据

    上一节我们给index方法创建了一个模板&#xff0c;并且返回了一个字符串 我现在想把h1里的字符串&#xff0c;从php里传递过去该如何做呢&#xff0c;看下面代码&#xff1a; 在php里&#xff0c;我们定义了一个$str的变量&#xff0c;并且赋值一个字符串。 用assign方法传递变…...

    2024/4/14 22:35:44
  3. IDEA又双叒叕抽风了,怎样避免一拳把屏幕打穿

    IDEA又双叒叕抽风了&#xff0c;怎样避免一拳把屏幕打穿 原创 Django Java工程师成长日记 8月18日 收录于话题#IDEA1个内容 IDEA号称宇宙第一IDEA&#xff0c;用过的人都说好。大而全是IDEA的特色&#xff0c;可是这也导致了IDEA时不时会抽风&#xff0c;每每让人百思不得其…...

    2024/4/14 22:36:59
  4. MYSQL 查询语法总结

    select 查询列表 from 表1 别名 连接类型 join 表2 别名 on 连接条件 where 筛选条件 group by 分组列表 having 筛选条件 order by 排序列表 limit 排序列表...

    2024/4/19 17:31:47
  5. centos7.3下安装openresty(nginx)+php7.3运行环境 超级详细

    OpenResty介绍&#xff1a; Nginx 是采用一个 master 进程管理多个 worker 进程&#xff08;master-worker&#xff09;的模式&#xff0c;基本的事件处理都在 woker 当中&#xff0c;master 负责一些全局初始化&#xff0c;以及对 worker 的管理的事情。在OpenResty中&#xf…...

    2024/4/14 22:37:09
  6. RuoYi框架使用手册

    第一步进入官网 RuoYi官网 下载图片上标识的 切记这里要改成本地的 下载到本地 5 . 6.新增菜单目录成功之后刷新页面会看到教师管理目录成功显示 7. 8.到ruoyi页面点击代码生成 9.导入会发现数据库的表被识别到 10. 11.点击生成代码 12. 13.将teacher包复制到…...

    2024/4/18 15:51:55
  7. 【洛谷P1349】广义斐波那契数列【矩阵乘法】

    LuogulinkLuogu~linkLuogu link 分析&#xff1a; 显然矩乘 普通斐波那契 转移矩阵&#xff1a; ∣1,1∣∣1,0∣|1,1|\\ |1,0|∣1,1∣∣1,0∣ 那么只需要把系数加上&#xff1a; ∣p,1∣∣q,0∣|p,1|\\ |q,0|∣p,1∣∣q,0∣ 以及递推矩阵改为[a2,a1][a_2,a_1][a2​,a1​]即可…...

    2024/4/19 11:41:20
  8. python第三方库--wordcloud库

    目录基本介绍基本使用常见函数案例&#xff1a;生成三国演义的词云案例&#xff1a;特殊图案的词云基本介绍 词云1展示第三方库 基本使用 wordcloud库把词云当做一个Wordcloud对象&#xff0c;比如&#xff1a;wwordcloud.Wordcloud()中&#xff0c;w便是一个Wordcloud对象 …...

    2024/4/14 22:36:34
  9. 《SQL必知必会》拾遗

    《SQL必知必会》拾遗 原创 Django Java工程师成长日记 2018-07-30 数据库&#xff08;database&#xff09; 保存有组织的数据的容器&#xff08;通常是一个文件或一组文件&#xff09;。 表&#xff08;table&#xff09; 某种特定类型数据的结构化清单。 模式 关于数据库和…...

    2024/4/14 22:36:39
  10. 2021研报目录更新

    大家好&#xff0c;我们每天全网搜集各行各业的研究报告&#xff0c;了解一个行业从阅读这个行业的研报开始&#xff0c;今日分享目录如下&#xff1a;———————————— 2020-2021年中国购物中心消费者洞察报告-61页.pdf 2021年中国购物者报告&#xff1a;中国快速消…...

    2024/4/15 7:01:27
  11. Redis未授权访问

    目录 前言&#xff1a; 一、Redis简介&#xff1a; 二、Redis未授权产生的原因&#xff1a; 三、Redis未授权复现&#xff1a; 1.使用ssh公钥登录目标服务器 2.如何利用redis未授权漏洞 四、防御措施&#xff1a; 前言&#xff1a; 漏洞复现的过程磕磕绊绊&#xff0c;但…...

    2024/4/14 22:37:04
  12. 粗略讲一下uniapp 中第三方小程序登录的过程做个大概笔记

    这里先只讲 第三方的小程序登录过程 理解透了登录过程 就可以脱离官方的uniapp 随便浪了 uniapp插件市场那么多的模板就可以随便玩了。 先从官方的uniapp 解读 pages\authorize\components\wx-mini.nvue 页面加载的时候就调用小程序登录 获取到code后执行 fastLogin 这里是最…...

    2024/4/16 1:15:16
  13. redis 操作

    redis 操作命令 连接&#xff1a;redis-cli -h 127.0.0.1 -p 6379 输入密码&#xff08;如设置了密码&#xff09;&#xff1a; 127.0.0.1:6379> auth “yourpassword”...

    2024/4/14 22:36:39
  14. Yii2中mongodb使用ActiveRecord的数据操作

    概况Yii2 一个高效安全的高性能PHP框架。mongodb 一个高性能分布式文档存储NOSQL数据库。 关于mongodb与mysql的优缺点,应该都了解过。 mysql传统关系数据库,安全稳定、数据完整、资源文档完善、使用群体多、支持事物,V5.7后支持原生Json速度不逊mongodb、分布式主从集群刚刚…...

    2024/4/20 7:10:15
  15. matlab的rand函数用法

    matlab中的rand&#xff08;&#xff09;_一帆船-CSDN博客...

    2024/4/5 5:47:11
  16. 梯度下降法,二维空间三维空间 代码实现

    目录 梯度下降法 问题定义 算法思想和推导 一维问题就是不断求导&#xff0c;直到达到我们设置的精度 Python 代码实现 一维问题 三维空间梯度下降 代码展示 梯度下降法 Python实现简单的梯度下降法 - 何雨龙 - 博客园 机器学习算法常常可以归结为求解一个最优化问题&…...

    2024/4/14 22:37:09
  17. leetcode 链表的合并和分割两道题

    leetcode 链表的合并和分割两道题1.合并两个有序链表1.1 题目描述1.2 接口函数1.3 大致框架1.3.1 思路分析1.3.2 具体步骤1.4 具体实现1.5 方法选择2. 分割链表2.1 题目描述2.2 接口函数2.3 大致框架2.3.1 思路分析2.3.2 具体步骤2.4 具体实现1.合并两个有序链表 1.1 题目描述…...

    2024/4/20 12:31:51
  18. js的逻辑运算符1

    js中任何计算都需要一个结果。 逻辑运算符输出的结果是两个&#xff1a;true 与 false <script> var a 1 > 2; var b 1 < 2; document.write(1 > 2的结果是&#xff1a; a <br>);//输出false document.write(1 < 2的结果是&#xff1a; b);//输出…...

    2024/4/18 14:36:42
  19. c++一元多项式加法及乘法(转)

    原文链接 使用介绍讲要进行计算的两个式子降幂排列 然后将每一项按系数 指数输入&#xff08;常数项指数为0&#xff09; 输入 0 0结束这一项 同理输入第二项 输出第一行为加法 第二行为乘法 代码如下 #include<iostream> using namespace std; struct node{int z…...

    2024/4/21 23:51:40
  20. HelloWorld

    1.随便新建一个文件夹&#xff0c;存放代码 2.新建一个java文件 文件后缀名为。java HelloWorld.java [注意点]系统可能没有显示后缀名&#xff0c;需要手动打开 3.编写代码 public class hello{public static void main(String[] args) {System.out.print("Hello,Wor…...

    2024/4/14 22:36:34

最新文章

  1. Java混淆的重要性

    在软件开发领域&#xff0c;安全性与代码保护一直是备受关注的问题。特别是在Java这样的跨平台语言中&#xff0c;保护源代码的机密性和完整性显得尤为重要。Java混淆作为一种代码保护技术&#xff0c;其在现代软件开发中的地位日益凸显。本文将详细探讨Java混淆的重要性&#…...

    2024/4/26 17:27:48
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. N5171B是德科技N5171B信号发生器

    181/2461/8938产品概述&#xff1a; N5171B EXG 射频模拟信号发生器具有最佳的 EXG&#xff0c;旨在满足您对组件参数测试和接收器校准的信号需求。其出色的硬件性能可提供更快的吞吐量、更长的正常运行时间以及极好的准确性和可重复性。 Agilent / HP N5171B EXG 射频模拟信…...

    2024/4/23 6:23:34
  4. 【ARM 嵌入式 C 文件操作系列 20 -- 文件删除函数 remove 详细介绍】

    请阅读【嵌入式开发学习必备专栏 】 文章目录 文件删除函数 remove 文件删除函数 remove 在 C 语言中&#xff0c; 可以使用 remove 函数来删除一个文件&#xff0c;但在删除之前 可能想确认该文件是否存在。 可以使用 stat 函数来检查文件是否存在。 以下是如何实现这个功能…...

    2024/4/25 7:29:23
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/25 11:51:20
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/25 18:39:24
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/25 18:38:39
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/25 18:39:23
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/25 18:39:22
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/25 18:39:22
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/25 18:39:20
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/25 16:48:44
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/26 16:00:35
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/25 18:39:16
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/25 0:00:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/25 4:19:21
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/25 18:39:12
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/25 2:10:52
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/25 18:39:00
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/25 13:19:01
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/25 18:38:58
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/25 18:38:57
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57