文本分类动转静预测错误分析和挖掘稀疏数据和建立新数据集.ipynb

import os
import paddle
from paddlenlp.transformers import AutoModelForSequenceClassification

params_path='checkpoint/text_classes/'
output_path='output/text_class'

model = AutoModelForSequenceClassification.from_pretrained(params_path)

model.eval()
# 转换为具有特定输入描述的静态图
model = paddle.jit.to_static(
    model,
    input_spec=[
        paddle.static.InputSpec(shape=[None, None],
                                dtype="int64"),  # input_ids
        paddle.static.InputSpec(shape=[None, None],
                                dtype="int64")  # segment_ids
    ])

# Save in static graph model.
save_path = os.path.join(output_path, "float32")
paddle.jit.save(model, save_path)

import functools
import numpy as np
from sklearn.metrics import top_k_accuracy_score, classification_report
import paddle.nn.functional as F
from paddlenlp.data import DataCollatorWithPadding
from paddlenlp.datasets import load_dataset
from paddlenlp.transformers import  AutoTokenizer
from paddlenlp.utils.log import logger
import re
import json
import random
import time
from paddle.io import DataLoader, BatchSampler, DistributedBatchSampler
from paddlenlp.transformers import AutoModelForSequenceClassification, AutoTokenizer, LinearDecayWithWarmup
from paddlenlp.dataaug import WordSubstitute, WordInsert, WordDelete, WordSwap
from trustai.interpretation import FeatureSimilarityModel

paddle.set_device('gpu')

dataset_dir='datasets/KUAKE_QIC'

label_list = {}
label_path = os.path.join(dataset_dir, 'label.txt')

train_path = os.path.join(dataset_dir, 'train.txt')
dev_path = os.path.join(dataset_dir, 'dev.txt')

with open(label_path, 'r', encoding='utf-8') as f:
    for i, line in enumerate(f):
        l = line.strip()
        label_list[l] = i

from q_a_utils import utils

import importlib
importlib.reload(utils)

train_ds = load_dataset(utils.read_local_dataset,
                            path=train_path,
                            label_list=label_list,
                            lazy=False)

dev_ds = load_dataset(utils.read_local_dataset,
                          path=dev_path,
                          label_list=label_list,
                          lazy=False)

params_dir='checkpoint/text_classes'

model = AutoModelForSequenceClassification.from_pretrained(
        params_dir)

tokenizer = AutoTokenizer.from_pretrained(params_dir)

max_seq_length=128

trans_func = functools.partial(utils.preprocess_function,
                                   tokenizer=tokenizer,
                                   max_seq_length=max_seq_length)

train_dataset = train_ds.map(trans_func)
dev_dataset = dev_ds.map(trans_func)

batch_size=16
bad_case_path=dataset_dir+'/bad_case.txt'

# batchify dataset
collate_fn = DataCollatorWithPadding(tokenizer)

train_batch_sampler = BatchSampler(train_ds,
                                       batch_size=batch_size,
                                       shuffle=False)
train_data_loader = DataLoader(dataset=train_ds,
                               batch_sampler=train_batch_sampler,
                               collate_fn=collate_fn)
dev_batch_sampler = BatchSampler(dev_ds,
                                 batch_size=batch_size,
                                 shuffle=False)
dev_data_loader = DataLoader(dataset=dev_ds,
                             batch_sampler=dev_batch_sampler,
                             collate_fn=collate_fn)

len(train_data_loader.dataset)

model.eval()
probs = [] #保存模型预测的当前样本的概率分布
labels = [] # 保存真实类别标签
for batch in train_data_loader:
    label = batch.pop("labels") # 弹出labels (16,1)
    logits = model(**batch) # (16,11)
    prob = F.softmax(logits, axis=1)
    # print(label.shape)
    labels.extend(label.numpy())
    probs.extend(prob.numpy())
# print(len(probs)) # 6931
# print(probs[0].shape) # (11,)
probs = np.array(probs)
labels = np.array(labels)
preds = probs.argmax(axis=-1)
report_train = classification_report(labels,
                                     preds,
                                     digits=4,
                                     output_dict=True)

# digits=4参数指定了在输出报告中保留的小数位数。这意味着对于精确度(precision)、召回率(rec
# all)、F1分数(F1-score)等性能指标,将展示到小数点后四位
# output_dict=True参数则指定了函数的输出格式。当设置为True时,classification_report
# 将返回一个字典(dict)而不是打印到控制台。这个字典包含了分类报告的所有信息,包括每个类别的精确度、
# 召回率、F1分数以及支持度(即该类别的真实样本数)。

report_train # 返回11个类别的报告

probs = []
labels = []
for batch in dev_data_loader:
    label = batch.pop("labels")
    logits = model(**batch)
    prob = F.softmax(logits, axis=1)
    labels.extend(label.numpy())
    probs.extend(prob.numpy())
probs = np.array(probs)
labels = np.array(labels)
preds = probs.argmax(axis=-1) #获取最大概率对应的索引,也就是模型预测的类别
report = classification_report(labels, preds, digits=4, output_dict=True)

print(len(probs),len(labels))

logger.info("-----Evaluate model-------")
logger.info("Train dataset size: {}".format(len(train_ds)))
logger.info("Dev dataset size: {}".format(len(dev_ds)))
logger.info("Accuracy in dev dataset: {:.2f}%".format(report['accuracy'] *
                                                      100))
logger.info("Top-2 accuracy in dev dataset: {:.2f}%".format(
    top_k_accuracy_score(labels, probs, k=2) * 100))
logger.info("Top-3 accuracy in dev dataset: {:.2f}%".format(
    top_k_accuracy_score(labels, probs, k=3) * 100))

label_map=dict(zip(range(len(label_list)),label_list.keys()))

for i in label_map: # 相当于遍历dict的keys()
    logger.info("Class name: {}".format(label_map[i]))
    # i对应当前类别,从0--10
    logger.info(
        "Evaluation examples in train dataset:\
        {}({:.1f}%) | precision: {:.2f} | recall: {:.2f} | F1 score {:.2f}"
        .format(report_train[str(i)]['support'], #当前类别的训练样本数
                100 * report_train[str(i)]['support'] / len(train_ds),
                report_train[str(i)]['precision'] * 100,
                report_train[str(i)]['recall'] * 100,
                report_train[str(i)]['f1-score'] * 100))
    logger.info(
        "Evaluation examples in dev dataset: {}({:.1f}%) | \
        precision: {:.2f} | recall: {:.2f} | F1 score {:.2f}"
        .format(report[str(i)]['support'],# 当前类别的评估样本数
                100 * report[str(i)]['support'] / len(dev_ds),
                report[str(i)]['precision'] * 100,
                report[str(i)]['recall'] * 100,
                report[str(i)]['f1-score'] * 100))
    logger.info("----------------------------")

with open(bad_case_path, 'w', encoding="utf-8") as f:
    f.write("Confidence\tPrediction\tLabel\tText\n")
    for i, (p, l) in enumerate(zip(preds, labels)):
        p, l = int(p), int(l)
        if p != l: # 把预测错的存入文件
            # 模型预测类别对应的模型置信度,预测对应的类别,真实类别,预测文本
            f.write("{:.2f}".format(probs[i][p]) + "\t" + label_map[p] +
                    "\t" + label_map[l] + "\t" + dev_ds.data[i]["text"] +
                    "\n")
logger.info("Bad case in dev dataset saved in {}".format(
    bad_case_path))

# 现在我们进行稀疏数据识别--数据增强,得到新增训练数据

# choices=["duplicate", "substitute", "insert", "delete", "swap"]
aug_strategy='substitute'
annotate=True

seed=1000
# 每个示例的基本原理数量。
support_threshold=0.7

unlabeled_file='data.txt'

sparse_file='sparse.txt'
support_file='support.txt'

utils.set_seed(seed)

def get_sparse_data(analysis_result, sparse_num): # 获取稀疏数据
    # 参数:解析结果,稀疏数据
    idx_scores = {} #保存样本索引序号和其对应的分析中的正样本相似度分数
    preds = [] # 保存预测类别
    for i in range(len(analysis_result)):
        # 分析结果中的正例分数
        scores = analysis_result[i].pos_scores  
        # 计算出平均分数
        idx_scores[i] = sum(scores) / len(scores)
        # 把分析结果的预测类别加进去
        preds.append(analysis_result[i].pred_label)
    # 按分析结果分数的分数高低排序,后面是截取一定数目,按分数正序排列
    #这样分数低的是稀疏样本数据
    idx_socre_list = list(sorted(idx_scores.items(),
                                 key=lambda x: x[1]))[:sparse_num]
    ret_idxs, ret_scores = list(zip(*idx_socre_list))
    return ret_idxs, ret_scores, preds

#少样本分析中返回的标签是字符串文字形式,不是数字
def read_local_dataset(path):
    with open(path, 'r', encoding='utf-8') as f:
        for line in f:
            items = line.strip().split('\t')
            if len(items) == 2:
                yield {'text': items[0], 'label': items[1]}
            elif len(items) == 1:
                yield {'text': items[0]}
            else:
                logger.info(line.strip())
                raise ValueError("{} should be in fixed format.".format(path))

def preprocess_function(examples, tokenizer, max_seq_length):
    result = tokenizer(text=examples["text"], max_seq_len=max_seq_length)
    return result

# Batchify dataset
collate_fn = utils.LocalDataCollatorWithPadding(tokenizer)

# 特别注意:进行稀疏样本分析时,这里的标签不是数字,而是真实类别

# 所以这里加载读取的是字符串文本标签

train_ds = load_dataset(read_local_dataset, path=train_path, lazy=False)
dev_ds = load_dataset(read_local_dataset, path=dev_path, lazy=False)
trans_func = functools.partial(preprocess_function,
                               tokenizer=tokenizer,
                               max_seq_length=max_seq_length)

#这里转换成数字形式时,没有标签,只读取输入

train_ds = train_ds.map(trans_func)
dev_ds = dev_ds.map(trans_func)

train_batch_sampler = BatchSampler(train_ds,
                                   batch_size=batch_size,
                                   shuffle=False)

dev_batch_sampler = BatchSampler(dev_ds,
                                     batch_size=batch_size,
                                     shuffle=False)

# collate_fn是返回列表形式的collate_fn

rain_data_loader = DataLoader(dataset=train_ds,
                               batch_sampler=train_batch_sampler,
                               collate_fn=collate_fn)
dev_data_loader = DataLoader(dataset=dev_ds,
                             batch_sampler=dev_batch_sampler,
                             collate_fn=collate_fn)

for i in dev_data_loader:
    print(i)
    break

# 用FeatureSimilarityModel的模型来分析特征的相似度,并基于这些分析从开发集(
# dev_data_loader)中选择稀疏数据。这个过程大致可以分为几个步骤:特征相似度分
# 析、稀疏数据选择和结果获取。

# 这个步骤使用FeatureSimilarityModel类来处理模型model和训练数据加载器train_data_loader
# ,并指定了分类器的最后一层名称("classifier")。这个模型可能通过某种方式(如梯度信息、激活
# 值或注意力机制)来评估特征的重要性或它们之间的相似性。

# Classifier_layer_name为最后一个输出层的层名
feature_sim = FeatureSimilarityModel(model,
                                     train_data_loader,
                                     classifier_layer_name="classifier")

# 通过遍历dev_data_loader中的每个批次(batch),使用feature_sim对象对每个批
# 次进行分析,并可能根据某些条件(如rationale_num)选择或评估特定数量的样本。

# 基于analysis_result,使用get_sparse_data函数选择稀疏数据。稀疏数据通常指的是在特
# 征空间中具有独特或稀疏表示的数据点,它们可能对模型的学习特别重要或具有代表性。

# get_sparse_data(analysis_result, sparse_num)函数根据某种标准(如特征相似度评分的分布
# 、特征值的方差等)从analysis_result中选择sparse_num个最稀疏的数据点。

# 返回三个主要元素:稀疏数据的索引(sparse_indexs)、稀疏度评分(sparse_scores)
# 和这些数据的预测结果(preds)

rationale_num=8

# 特征相似度分析及稀疏数据选择
analysis_result = []
for batch in dev_data_loader:
    analysis_result += feature_sim(batch, sample_num=rationale_num)

analysis_result[8] #pos_scores大概率是相似度分数

print((len(analysis_result)),len(dev_data_loader.dataset))

# 设置返回评估集中稀疏数据的样本数
sparse_num=300

sparse_indexs, sparse_scores, preds = get_sparse_data(
    analysis_result, sparse_num)

sparse_indexs[:10]

len([i for i in is_true if i==1])

# 我是全评估集抽取,后边的预测都正确,说明他们不是稀疏样本
#前面的预测很多不正确,是稀疏样本,说明这些类别缺乏训练数据
is_true

# 分数低的都是稀疏样本
sparse_scores

#稀疏数据是某个分类类别缺乏足够的训练数据,导致资料不足,所以模型在评估这些数据时会预测错误

# Save the sparse data
is_true = []
with open(os.path.join(dataset_dir,sparse_file), 'w') as f:
    for idx in sparse_indexs:
        data = dev_ds.data[idx] # 获取稀疏样本和其真实类别
        f.write(data['text'] + '\t' + str(data['label']) + '\n')
        # 如果预测标签和真实标签相同,设置标记1,表示预测正确,否则设置0
        is_true.append(1 if str(preds[idx]) ==
                       str(label_list[data['label']]) else 0)

logger.info("Sparse data saved in {}".format(
    os.path.join(dataset_dir, sparse_file)))
logger.info("Accuracy in sparse data: {:.2f}%".format(100 * sum(is_true) /
                                                      len(is_true)))
logger.info("Average score in sparse data: {:.4f}".format(
    sum(sparse_scores) / len(sparse_scores)))

# sparse_num`:筛选稀疏数据数量,建议为开发集的10%~20%,默认为100
# support_num`:用于数据增强的支持数据数量,建议为训练集的10%~20%,默认为100
# support_threshold`:支持数据的阈值,只选择支持证据分数大于阈值作为支持数据,默认为0.7。
# `sparse_file`:保存在本地数据集路径中稀疏数据文件名;默认为"sparse.txt"。
# `support_file`:保存在本地数据集路径中支持训练数据文件名;默认为"support.txt"。

 将得到增强支持数据`support.txt`与训练集数据`train.txt`合并得到新的训练集`
# train_sparse_aug.txt`重新进行训练:
# cat ../data/train.txt ../data/support.txt > ../data/train_sparse_aug.txt

#获取支持数据:分析结果,支持数据条数,阈值
def get_support_data(analysis_result, support_num, support_threshold=0.7):
    ret_idxs = [] # 保存相似样本索引
    ret_scores = [] # 保存相似样本索引对应的分数
    rationale_idx = 0
    try:
        while len(ret_idxs) < support_num: #退出内循环时,这里会自动判断,退出循环
            for i in range(len(analysis_result)):
                # 选取相似度分数
                score = analysis_result[i].pos_scores[rationale_idx]
                # 大于支持阈值才行
                if score > support_threshold:
                    # 选取相似样本索引
                    idx = analysis_result[i].pos_indexes[rationale_idx]
                    # idx不在里面的话添加,不添加重复的
                    if idx not in ret_idxs:
                        ret_idxs.append(idx)
                        ret_scores.append(score)
                    # 如果选够了样本,就退出内循环
                    if len(ret_idxs) >= support_num:
                        break
            # 这种情况是里面根据rationale_idx查到的idx已经在ret_idxs里面了
            # 这里就会加1,再次进入内循环查找
            rationale_idx += 1
    except IndexError:
        logger.error(
            f"The index is out of range, please reduce support_num or increase support_threshold. Got {len(ret_idxs)} now."
        )

    return ret_idxs, ret_scores

annotate=False

train_file='train.txt'

# Prepare & preprocess dataset
if annotate:
    candidate_path = os.path.join(dataset_dir, unlabeled_file)
else:
    candidate_path = os.path.join(dataset_dir,train_file)

sparse_path = os.path.join(dataset_dir, sparse_file)

support_path = os.path.join(dataset_dir,support_file)

candidate_ds = load_dataset(read_local_dataset,
                                path=candidate_path,
                                lazy=False)

# 加载稀疏数据
sparse_ds = load_dataset(read_local_dataset, path=sparse_path, lazy=False)

trans_func = functools.partial(preprocess_function,
                               tokenizer=tokenizer,
                               max_seq_length=max_seq_length)

candidate_ds = candidate_ds.map(trans_func)

sparse_ds = sparse_ds.map(trans_func)

print(len(sparse_ds),sparse_ds[0])

# Batchify dataset
collate_fn = utils.LocalDataCollatorWithPadding(tokenizer)

candidate_batch_sampler = BatchSampler(candidate_ds,
                                           batch_size=batch_size,
                                           shuffle=False)

sparse_batch_sampler = BatchSampler(sparse_ds,
                                        batch_size=batch_size,
                                        shuffle=False)

candidate_data_loader = DataLoader(dataset=candidate_ds,
                                       batch_sampler=candidate_batch_sampler,
                                       collate_fn=collate_fn)
sparse_data_loader = DataLoader(dataset=sparse_ds,
                                batch_sampler=sparse_batch_sampler,
                                collate_fn=collate_fn)

for i in sparse_data_loader:
    print(i)
    break

# Classifier_layer_name为最后一个输出层的层名
feature_sim = FeatureSimilarityModel(model,
                                     candidate_data_loader,
                                     classifier_layer_name="classifier")

# 特征相似度分析
analysis_result = [] # 分析结果
for batch in sparse_data_loader:
    analysis_result += feature_sim(batch, sample_num=-1)

support_num=300

support_indexs, support_scores = get_support_data(analysis_result,
                                                      support_num,
                                                      support_threshold)

# Save the support data
# 如果annotate=True,或者aug_strategy是重复
if annotate or aug_strategy == "duplicate":
    with open(support_path, 'w') as f:
        for idx in list(support_indexs):
            data = candidate_ds.data[idx]
            if 'label' in data:
                f.write(data['text'] + '\t' + data['label'] + '\n')
            else:
                f.write(data['text'] + '\n')
    f.close()
else:  
    create_n = 1
    aug_percent = 0.1 # 增强百分比
    if aug_strategy == "substitute": # substitute:替代
        aug = WordSubstitute('synonym',
                             create_n=create_n,
                             aug_percent=aug_percent)
    elif aug_strategy == "insert": # 插入
        aug = WordInsert('synonym',
                         create_n=create_n,
                         aug_percent=aug_percent)
    elif aug_strategy == "delete": # 删除
        aug = WordDelete(create_n=create_n, aug_percent=aug_percent)
    elif  aug_strategy == "swap": # swap:交换
        aug = WordSwap(create_n=create_n, aug_percent=aug_percent)

    with open(support_path, 'w') as f:
        for idx in list(support_indexs):
            data = candidate_ds.data[idx]
            augs = aug.augment(data['text'])
            for a in augs:
                f.write(a + '\t' + data['label'] + '\n')
    f.close()

data = candidate_ds.data[support_indexs[0]]

logger.info("support data saved in {}".format(support_path))
logger.info("support average scores: {:.4f}".format(
    float(sum(support_scores)) / len(support_scores)))

# 将得到增强支持数据`support.txt`与训练集数据`train.txt`合并得到新的训练集`train_sparse_aug.txt`重新进行训练:

# ```shell
# cat ../data/train.txt ../data/support.txt > ../data/train_sparse_aug.txt
# ```

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

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

相关文章

(十三)Spring教程——依赖注入之工厂方法注入

1.工厂方法注入 工厂方法是在应用中被经常使用的设计模式&#xff0c;它也是控制反转和单例设计思想的主要实现方法。由于Spring IoC容器以框架的方式提供工厂方法的功能&#xff0c;并以透明的方式开放给开发者&#xff0c;所以很少需要手工编写基于工厂方法的类。正是因为工厂…

如何从网站获取表格数据

1.手动复制粘贴 最简单的方法是直接在网页上手动选择表格内容&#xff0c;然后复制粘贴到Excel或其他表格处理软件中。这种方法适用于表格较小且不经常更新的情况。 2.使用浏览器插件 有许多浏览器插件可以帮助从网页中提取表格数据&#xff0c;例如&#xff1a; -TableCapt…

SSRF过滤攻击

SSRF绕过&#xff1a; 靶场地址&#xff1a;重庆橙子科技SSRF靶场 这个是毫无过滤的直接读取&#xff0c;但是一般网站会设置有对SSRF的过滤&#xff0c;比如将IP地址过滤。 下面是常用的绕过方式&#xff1a; 1.环回地址绕过 http://127.0.0.1/flag.php http://017700…

相机怎么选(不推荐,只分析)

title: 相机怎么选 tags: [相机, 单反相机] categories: [其他, 相机] 最近准备购买&#xff0c;相机怎么选&#xff0c;我去搜索了许多文章&#xff0c;整理了一篇小白挑选技术篇&#xff0c;供大家参考。 分类 胶片相机 需要装入胶卷才能使用的相机&#xff0c;拍照后可直…

永磁同步电机无速度算法--非线性磁链观测器

非线性磁链观测器顾名思义观测器的状态变量为磁链值&#xff0c;观测的磁链值收敛于电机实际磁链值&#xff0c;观测器收敛。非线性是由于观测器存在sin和cos项&#xff0c;所以是非线性观测器 一、原理介绍 表贴式永磁同步电机αβ轴电压方程: 将公式变换 定义状态变量X: 定…

Milvus 向量数据库进阶系列丨部署形态选型

本系列文章介绍 在和社区小伙伴们交流的过程中&#xff0c;我们发现大家最关心的问题从来不是某个具体的功能如何使用&#xff0c;而是面对一个具体的实战场景时&#xff0c;如何选择合适的向量数据库解决方案或最优的功能组合。在 “Milvus 向量数据库进阶” 这个系列文章中&…

Java实现打印功能

JPG图片文件格式打印实现 打印JPG图片格式的文件&#xff0c;本次采用的Java原生的打印方式。 public static void main(String[] argv) throws Exception {File file new File("E:\\a.jpg");String printerName "HP MFP M436 PCL6";//打印机名包含字串…

vite+vue3项目,开发时候正常,打包后router-view不渲染

这是个很奇怪的问题&#xff0c;但是基本上命名或者引入文件的方式导致的。要么文件名与系统的某些标签名一样&#xff0c;要么就是routes写成了routers。还有一种就是导入方式错误的 错误截图&#xff1a; 正确引入截图&#xff1a;

Flink大状态作业调优——DataStream篇

一、Flink 状态&#xff08;State&#xff09;简介 在流式计算中有些操作一次处理一个独立的事件(比如解析一个事件), 有些操作却需要记住多个事件的信息(比如窗口操作)。那些需要记住多个事件信息的操作就是有状态的。流式计算分为无状态计算和有状态计算两种情况。状态可以理…

Word题库转Excel关键字快速查询题库

一、前言 内部培训会有Word版本题库&#xff0c;考核时如果使用Word、Excel、PDF等文档进行关键字查询题目体验不佳。so&#xff0c;撸个软件吧&#xff01;   20240728更新&#xff1a;支持更多题库类型。 二、Word题库转Excel 1、Word题库格式要求 内容格式要求事例题目…

在 Postman 中设置全局 token

目录 问题描述解决方案 问题描述 在使用 Postman 进行接口测试时&#xff0c;经常会遇到在 Header 中添加 token 的情况。当接口数量较多时&#xff0c;需要为每个接口进行设置&#xff0c;而且当 token 失效时需要重新获取并设置&#xff0c;这样一来效率较低。 解决方案 下…

wpf中开发独立模块功能和左侧1个菜单的框架演示

此篇文章适用于有一定经验的wpf开发者&#xff0c;并且是团队协作开发模式&#xff0c;并且业务与此比较相近的话&#xff0c;用起来非常的方便。 我们在开发wpf程序的时候&#xff0c;比如1&#xff0c;2个人&#xff0c;那肯定随便怎么开发&#xff0c;都没事&#xff0c;代码…

Matlab M_map工具箱绘制Interrupted Mollweide Projection

GMT自带了许多的地图投影&#xff0c;但是对于Interrupted Mollweide投影效果却不好。 作为平替的m_map工具箱中带有的投影类型可完美解决这一问题。 Interrupted Mollweide Projection长这样 全球陆地 全球海洋 使用Matlab工具箱m_map展示全球海平面变化的空间分布 addpath(…

【Dart 教程系列第 49 篇】什么是策略设计模式?如何在 Dart 中使用策略设计模式

这是【Dart 教程系列第 49 篇】&#xff0c;如果觉得有用的话&#xff0c;欢迎关注专栏。 博文当前所用 Flutter SDK&#xff1a;3.22.1、Dart SDK&#xff1a;3.4.1 文章目录 一&#xff1a;什么是策略设计模式&#xff1f;二&#xff1a;为什么要使用策略设计模式&#xff1…

UG NX2406 安装教程

软件介绍 UG是一个交互式CAD/CAM(计算机辅助设计与计算机辅助制造)系统&#xff0c;它功能强大&#xff0c;可以轻松实现各种复杂实体及造型的建构。 它在诞生之初主要基于工作站&#xff0c;但随着PC硬件的发展和个人用户的迅速增长&#xff0c;在PC上的应用取得了迅猛的增长…

西蒙学习法

西蒙学习法 一根筋&#xff0c;挖死坑&#xff1b;会思考&#xff0c;持续不断的思考&#xff1b;会问问题&#xff0c;有深度的问题&#xff1b;一直想一个问题的解决办法&#xff1b; 资料 《世界十大学习方法》之西蒙学习法

【HarmonyOS】应用推送使用个推SDK如何实现?

【HarmonyOS】应用推送使用个推SDK如何实现&#xff1f; 前言 个推和极光都是市面上很成熟的推送第三方SDK了。今天讲讲个推SDK在鸿蒙中如何集成使用。 存在即合理&#xff0c;三方SDK推送给我们带来了极大的好处&#xff0c;首先在服务器后台处理一套API就可搞定&#xff0…

Matlab 命令行窗口默认输出(异常)

目录 前言Matlab 先验知识1 异常输出的代码2 正常输出的代码 前言 在单独调试 Matlab 写的函数时出现不想出现的异常打印值&#xff0c;逐个注释排查才找到是 if elseif else 代码块的问题&#xff0c;会默认打印输出 else 部分第一个返回值的值&#xff08;下方代码中的 P值&…

基于jeecgboot-vue3的Flowable流程仿钉钉流程设计器-抄送服务处理

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、因为仿钉钉设计器里抄送人是一个服务任务&#xff0c;所以要根据这个服务任务进行处理 2、前端就是一个抄送&#xff0c;选择人 3、这里用了jeecg的选择人组件 <el-form-item prop…

昇思25天学习打卡营第10天|xiaoyushao

从今天开始做一些实践应用&#xff0c;今天分享的是FCN图像语义分割。 全卷积网络&#xff08;Fully Convolutional Networks&#xff0c;FCN&#xff09;是UC Berkeley的Jonathan Long等人于2015年在Fully Convolutional Networks for Semantic Segmentation一文中提出的用于图…