当前位置: 首页 > news >正文

【大模型实战篇】高质量数据过滤及一种BoostedBaggingFilter处理方法的介绍

1. 高质量数据过滤  

1.1 背景介绍

        数据质量对于大模型的训练至关重要,经常会听到一句话:数据决定模型的上限。模型的性能上限通常受到训练数据的质量限制。如果数据集不够好,模型可能无法学习到泛化的特征,导致其在新数据上的表现不佳。在大模型场景这个道理也通用,训练大模型依然需要喂入高质量的数据。否则造成大量计算资源的浪费,而且学习效果也差强人意。高质量的数据可以提高大型语言模型(LLMs)的最新技术水平,同时显著减少数据集的大小和训练计算量。重要的是需要较少训练的较小模型可以显著降低LLMs的环境成本【1,2】。

        训练大模型之前需要收集大量的文本数据。在收集了大量的文本数据后,为确保数据的质量和有效性,还需进行预处理,以清除低质量、冗余、无关甚至可能有害的数据【3】。目前业内出现了一些系统化的数据处理框架,比如开源库Data-Juicer 【4】来保证预训练数据的质量。       

        【3,4,6,7】中介绍了一系列常用的数据预处理方法和步骤。下图是典型的大语言模型预训练数据的预处理流程,可以参考加深对于预处理过程的了解。

        接下来,详细介绍其中的重要步骤,本文会重点关注质量过滤环节。

        收集到的原始文本数据通常包含大量低质量的内容,例如,从网页抓取的数据中可能包含机器生成的广告网页。为了提升模型学习的性能,有必要从语料库中剔除这些低质量数据。目前,研究人员主要使用两种数据清洗方法:(1)基于启发式规则的方法,和(2)基于分类器的方法。

1.2 基于启发式规则的方法

        通过设计针对性的规则来识别和剔除低质量文本数据是一种常见做法。不同类型的文本数据通常需要不同的清洗规则。例如,在处理问答数据时,可以通过过滤点赞数过少的帖子来剔除低质量内容;在处理代码语料时,可以过滤掉与代码无关的数据格式。以下是对一些常见数据集的清洗规则的总结【3】,仅供参考。

  • 基于语种的过滤:在训练以特定语言为主的大语言模型时,通常需要过滤掉其他语言的文本数据。例如,为了训练非英文主导的大语言模型(如中英双语模型),不仅要保留特定目标语言的数据,还需要保留高质量的英文数据。在训练过程中,使用语言识别器过滤非中英文的网页数据。

  • 基于简单统计指标的过滤:可以通过语料中的标点符号分布、符号与单词比率、句子长度等特征来衡量文本质量,并过滤低质量数据。例如:

    1. 过滤掉任何包含超过100个重复单词或句子的网页数据。
    2. 过滤掉符号与词元比大于0.1的网页数据。
    3. 过滤掉点赞数少于3的评论。
    4. 利用已有的语言模型计算文档的困惑度,作为过滤依据。
    5. 使用FastText分类器检测并删除有害或仇恨言论。
  • 基于关键词的过滤:预训练语料中可能存在大量重复文本模式,如HTML标签、超链接和模板等,还可能包含攻击性或冒犯性的信息。为解决这些问题,可以使用特定的关键词集对文本进行扫描和过滤。例如:

    1. 过滤掉任何少于25个UTF-8单词的页面。
    2. 过滤掉网页数据中的HTML标签。
    3. 过滤掉不含常用词汇(如the, be, to, of, and, that, have, with,的,是,到,的,和,那个,有,与。)的文档。
    4. 过滤掉所有数据中的电话号码、邮箱地址及IP地址等隐私信息。

1.3 基于分类器的方法

        除了启发式规则,还可以训练文本分类器来判断数据质量并进行清洗。具体来说,可以对部分代表性数据进行质量标注,以此训练一个精准的文本质量分类器。例如,可将高质量数据作为正样本,从网页中筛选出含有不良或低质量数据的样本作为负样本。使用这种分类器可以精确识别并过滤低质量数据,从而显著提升语料库的整体质量。当然这里面涉及到一系列工作,比如需要明确什么样的数据被认为是高质量的。这可能包括数据的完整性、准确性、一致性、相关性和时效性。根据你的数据类型和质量标准,选择合适的分类器模型。提取有助于分类器区分高质量和低质量数据的特征,这可能包括统计特征、文本特征、图像特征等。

        基于分类器的方法可能会无意中删除一些低资源但高质量的文本(如文言文数据)。为减少误筛,可以使用多个分类器进行联合过滤或召回。此外,还可根据不同的评估维度训练不同的分类器,采用类似集成的方式进行全面过滤。目前常用的分类器方法包括轻量级模型(如FastText等)、可微调的预训练语言模型(如BERT、LLaMA3等)以及闭源大语言模型API(如GPT-4o、Claude 3.5)。

1.4 效率与准确性的平衡

        在数据清洗过程中,过滤效率也是需要考虑的重要因素。例如,基于启发式规则的方法由于其规则设计相对简单,可以迅速过滤大量文档集;而基于分类器的方法尽管能提供更高的精确度,但需要消耗更多的计算资源。因此,可以结合使用这两种方法以达到平衡——先通过启发式规则进行初筛,快速排除不符合要求的文档,再使用分类器进一步精细过滤,以确保最终语料的高质量。

2. BoostedBaggingFilter处理方法

2.1 项目目标

        关于基于分类器的数据过滤方法,想起很多年前自己做的一个项目中也涉及到类似的任务,需要从用户标注的数据中筛选出可靠性强的样本数据,过滤掉噪声数据,虽然时间久远,但思路也许还是可以参考,这里做下简单的介绍。该方法其实是基于多层次集成分类器的思想,称为BoostedBaggingFilter。

        当时项目的目标是增加对用户标注数据的自学习,提高算法自适应能力,使算法能够应对新数据的分类任务,并且能够有效提升现有算法的分类准确性。基本思路如下:

 (1)增加与原有数据相似的样本数据,即使用样本数据训练产生的算法模型,去识别更多的能够支持样本数据分类准确度的用户标注数据。也就是同类型但可能表达形式差异的数据。


 (2)增加原有样本数据不存在的新的分类数据。比如原有数据中不存在"Uber#交通出行",现有分类算法会使得Uber被判别为其他。用户对该流水Uber人为改为Uber#交通出行,那么通过识别算法可以将该正确的数据识别出来,将Uber#交通出行这条新的信息补充到训练样本中,使得现有分类算法具备对新数据的识别能力。

2.2 算法思路描述

总体算法框架示意图如下:

说明:

解决的问题:
用户标注数据(反馈信息)的有效利用。

方法:
采用两层标注数据过滤算法,识别和利用正确的用户标注数据。

  1. 第一层过滤算法:旨在识别与现有样本数据存在交叉信息的标注数据,有助于提高分类的准确性。
  2. 第二层过滤算法:旨在识别全新的、未在样本数据中出现过的标注数据,帮助分类算法更好地应对全新的数据来源情况。
  • 第一层过滤算法(橙色椭圆):使用 Biterm 特征结合多分类逻辑回归(OvsR),以样本数据作为训练集,识别出与样本数据存在交叉信息的数据来源。
  • 第二层过滤算法(红色椭圆):采用 Boosted Bagging Filter 算法,针对第一层算法未能识别的标注数据。这些数据可能包括明显存在分类误差的样本以及在现有样本数据中没有对应信息的全新数据,从而有效识别出用户标注的新数据。

算法测试结果:

  1. 对于备注特征与样本特征存在一定交集的用户标注数据,通过交叉验证测试,过滤后的用户标注数据准确率平均达到了 99%。
  2. 对于备注特征与样本特征没有交集的全新用户标注数据,过滤后的类别准确率为 99.3%,错误数据的召回率为 97.8%。

2.3 标注数据过滤算法详述

目的:通过算法对用户标注数据进行清洗,去除噪声数据。

2.3.1 第一层过滤算法流程

目标: 使用样本集训练一个基本的分类器 f,这里选择逻辑回归(Logistic Regression)作为分类器,策略为“一对多”(One-vs-Rest)。

流程:

  1. 对于每一个新的用户标注数据实例 x_i​,使用分类器f(x_i)进行预测,获得预测概率的最大值 \text{max}(f(x_i)),对应的类别为 y'_i
  2. 获取用户实际标注的类别 y_i。
  3. 如果\text{max}(f(x_i)) > ty'_i = y_i,则将该用户标注数据添加到训练集中,继续用于分类器训练;否则,将该数据放入候选标注数据集,交由第二层过滤算法处理。

测试结果:过滤算法对测试集中数据的预测类别与实际类别的平均匹配度达到了 99%。匹配准确率是指类别正确标注的比例。

2.3.2 第二层过滤算法

目标:基于带噪声的标注数据集 D = \{(x_i, y_i) \mid 1 \leq i \leq n\},通过迭代和加权抽样的方法识别并过滤掉噪声数据。实验参数设置为 Bootstrap 样本数 m = 10,迭代次数 T = 10,并使用逻辑回归(Logistic Regression)作为基本分类器。

流程:

  1. 初始化错误分类计数 TNC

    \text{TNC}(i) 表示第 i 个实例的错误分类次数,初始状态为 0:\text{TNC}(i) = 0, \, i = 1, \ldots, n
  2. 初始化实例选择权重 W

    W(i) 表示第 i 个实例的选择权重,初始状态为均匀分布:W(i) = \frac{1}{n}, \, i = 1, \ldots, n
  3. 迭代过程(从 t = 1 到 T):

    • 对每次迭代:
      • 对每次 Bootstrap 采样(从 j = 1 到 m):
        • 从数据集中根据权重 W 抽样生成样本集 S_j = \text{ResampleWithWeight}(D, W)
        • 用样本集 S_j 训练分类器 h_j = \text{buildClassifier}(S_j)
      • 重置局部错误计数 NC\text{NC}(i) = 0
      • 对每个实例 x_i​:
        • 检查所有分类器 hjh_jhj​ 的预测结果:
          • 如果 h_j(x_i) \neq y_i,则增加相应的错误计数:\text{NC}(i)++
        • 更新全局错误计数:\text{TNC}(i) = \text{TNC}(i) + \text{NC}(i)
      • 更新实例权重:
        • W(i) \leftarrow W(i) \times e^{-\text{NC}(i)}
        • 归一化权重:W(i) \leftarrow \frac{W(i)}{\sum W(i)}​。
  4. 返回按 TNC 升序排列的实例。

  5. 根据 TNC 结果:

    • TNC 为 0 的实例标记为正确分类。
    • TNC 大于等于 10 的实例标记为错误分类。

算法测试方式:

  • 从样本集中随机抽取 5000 个实例,设置噪声比例(Noise Rate)来模拟带噪数据。例如,噪声比例为 0.2 表示 5000 个样本中有 20% 的数据被标记为错误类别。

  • 计算准确率(Precision)和召回率(Recall):这里的准确率表示TNC为0的实例中被正确标注的实例个数与TNC为0的实例总个数的比例。而召回率是指TNC 非 0 的实例中包含的噪声实例个数与所有噪声实例总个数的比例。

算法测试结果:

噪音率准确率(Precision)召回率(Recall)
0.10.9980.986
0.20.9970.989
0.30.9920.985
0.60.9600.982
0.80.8750.985

代码示例(java),仅供参考:

package com.yuanquan.userlabelcleaning;import com.yuanquan.liblinear.FeatureNode;
import com.yuanquan.liblinear.Model;
import com.yuanquan.utils.Utils;
import com.yuanquan.utils.SysCfgUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.*;/*** <p>* Title:BoostedBaggingFilter* </p>* <p>* Description:* 第二层过滤算法BBF, 提取出新的用户标注信息* 通过bootstrap抽样,训练多个子分类器, 并通过调整每一个实例的权重使得最正确的数据可以被选择.* 由于用户标注数据经过第一层算法过滤后, 会更新到第二层算法数据池, 因此每次使用都需要重新训练,针对不同的现有数据池.* </p>**/
public class BoostedBaggingFilter {private static final Logger LOGGER = LoggerFactory.getLogger(BoostedBaggingFilter.class);private static int T;  //BBF模型迭代次数private static int NUM_BOOTSTRAP_SAMPLE; //bootstrap抽样次数private static int THRESHOLD_TRUE; //BBF算法中错误数小于该值,则被认为用户分类正确的可能性极大private static int THRESHOLD_FALSE; //BBF算法中错误数大于该值,则被认为用户分类错误的可能性极大private static String PRE_PATH;private static String BASIC_INFO;private HashMap<String, String> BasicInfo;public BoostedBaggingFilter(){try {PRE_PATH = SysCfgUtils.getInstance().getValue("PRE_PATH");BASIC_INFO = PRE_PATH + "basicInfo.txt";BasicInfo = loadBasicInfo();T = Integer.parseInt(SysCfgUtils.getInstance().getValue("T"));NUM_BOOTSTRAP_SAMPLE = Integer.parseInt(SysCfgUtils.getInstance().getValue("NUM_BOOTSTRAP_SAMPLE"));THRESHOLD_TRUE = Integer.parseInt(SysCfgUtils.getInstance().getValue("THRESHOLD_TRUE"));THRESHOLD_FALSE = Integer.parseInt(SysCfgUtils.getInstance().getValue("THRESHOLD_FALSE"));} catch (IOException e) {e.printStackTrace();}}public HashMap<String, String> loadBasicInfo() throws IOException {BufferedReader inputReader = new BufferedReader(new InputStreamReader(new FileInputStream(BASIC_INFO)));try {return loadBasicInfo(inputReader);} finally {inputReader.close();}}//基于集成bagging过滤算法, 筛选出能够可信度大的正确及错误数据public  ArrayList<ArrayList<Integer>> ClassifyByBoostedBaggingFilter(List<CategoryAndFeatures> noiseInstances) throws IOException {int lenOfNoiseInstances = noiseInstances.size();int[] TNC = new int[lenOfNoiseInstances];double[] Weights = new double[lenOfNoiseInstances];int[] instances = new int[lenOfNoiseInstances];for(int i=0;i<lenOfNoiseInstances;i++){TNC[i] = 0;instances[i] = i;Weights[i] = 1.0/lenOfNoiseInstances;}for(int t=0;t<T;t++){Model[] LRmodels = new Model[NUM_BOOTSTRAP_SAMPLE];LOGGER.info("T:"+t);for(int j=0;j<NUM_BOOTSTRAP_SAMPLE;j++){LOGGER.info("NUM_BOOTSTRAP_SAMPLE:"+t+"-"+j);int[] newInstances = resampleWithWeights(Weights, instances);String modelFilePath = "BBF_"+j+".txt";TrainingDataFormat TDF = constructTrainingFeature(noiseInstances, newInstances);Model model = BaseOvsRLogisticRegression.trainingByLR(TDF.getFeatures(),Integer.parseInt(BasicInfo.get("NumberOfFeature")), TDF.getGROUPS_ARRAY(), modelFilePath, false);LRmodels[j] = model;}int[] NC = new int[lenOfNoiseInstances];//noise data classificationfor(int i=0;i<lenOfNoiseInstances;i++){CategoryAndFeatures currTestInstance = noiseInstances.get(i);for(int j=0;j<NUM_BOOTSTRAP_SAMPLE;j++){Model model = LRmodels[j];double[] prediction = BaseOvsRLogisticRegression.predict(model, currTestInstance.getFeatures());double preClass = prediction[0];if(preClass != currTestInstance.getCategory()){NC[i] = NC[i] + 1;}}TNC[i] = TNC[i] + NC[i];}for(int i=0;i<lenOfNoiseInstances;i++){Weights[i] = Weights[i] * Math.exp(-NC[i]);}Weights = normalize(Weights, sum(Weights));}// 按照TNC值升序返回noise InstancesMap<Integer, Integer> TNC_instance = new HashMap<Integer, Integer>();for(int i=0;i<lenOfNoiseInstances;i++){TNC_instance.put(i, TNC[i]);}TNC_instance = Utils.sortByValue(TNC_instance);ArrayList<Integer> TrueInstance = new ArrayList<Integer>();ArrayList<Integer> FalseInstance = new ArrayList<Integer>();for(Map.Entry<Integer, Integer> entry : TNC_instance.entrySet()) {LOGGER.info(entry.getKey()+"\t"+TNC_instance.get(entry.getKey()));if(entry.getValue() < THRESHOLD_TRUE){TrueInstance.add(entry.getKey());}if(entry.getValue() > THRESHOLD_FALSE){FalseInstance.add(entry.getKey());}}//返回最正确的,和最错误的instance indexArrayList<ArrayList<Integer>> TrueFalseInstanceIndex = new ArrayList<ArrayList<Integer>>();TrueFalseInstanceIndex.add(TrueInstance);TrueFalseInstanceIndex.add(FalseInstance);return TrueFalseInstanceIndex;}public HashMap<String, String> loadBasicInfo(Reader inputReader) throws IOException {BufferedReader reader;if (inputReader instanceof BufferedReader) {reader = (BufferedReader)inputReader;} else {reader = new BufferedReader(inputReader);}HashMap<String, String> infos = new HashMap<String, String>();String line;while ((line = reader.readLine()) != null) {String[] split = line.split(SysCfgUtils.getInstance().getValue("SEPARATOR_sys"));infos.put(split[0],split[1]);}reader.close();return infos;}public TrainingDataFormat constructTrainingFeature(List<CategoryAndFeatures> noiseInstances, int[] newInstances) {int lenOfInstances = newInstances.length;FeatureNode[][] trainingFeature = new FeatureNode[lenOfInstances][];double[] targetArray = new double[lenOfInstances];for (int i = 0; i < lenOfInstances; i++) {int index = newInstances[i];trainingFeature[i] = noiseInstances.get(index).getFeatures();targetArray[i] = noiseInstances.get(index).getCategory();}TrainingDataFormat TDF = new TrainingDataFormat();TDF.setFeatures(trainingFeature);TDF.setGROUPS_ARRAY(targetArray);return TDF;}public int[] resampleWithWeights(double[] weights, int[] instances) {if (weights.length != instances.length) {throw new IllegalArgumentException("weights.length != numOfInstances.");}int numInstances = instances.length;int[] newData = new int[numInstances];if (numInstances == 0) {return newData;}Random random = new Random();double[] probabilities = new double[numInstances];double sumProbs = 0, sumOfWeights = sum(weights);for (int i = 0; i < numInstances; i++) {sumProbs += random.nextDouble();probabilities[i] = sumProbs;}normalize(probabilities, sumProbs / sumOfWeights);probabilities[numInstances - 1] = sumOfWeights;int k = 0; int l = 0;sumProbs = 0;int count = -1;while ((k < numInstances && (l < numInstances))) {if (weights[l] < 0) {throw new IllegalArgumentException("Weights have to be positive.");}sumProbs += weights[l];while ((k < numInstances) && (probabilities[k] <= sumProbs)) {count++;newData[count] = instances[l];k++;}l++;}return newData;}public double sum(double[] weights) {double summation = 0;for (double weight : weights) {summation = summation + weight;}return summation;}public double[] normalize(double[] doubles, double summation) {for (int i = 0, len = doubles.length; i < len; i++) {doubles[i] = doubles[i] * 1.0 / summation;}return doubles;}
}

3. 参考材料

【1】Textbooks Are All You Need

【2】LLM and Dataset Quality

【3】Data Collection and Preprocessing for Large Language Models

【4】RUC AI box-《大语言模型》

【5】Data-Juicer: A One-Stop Data Processing System for Large Language Models

【6】Towards Trustable Language Models: Investigating Information Quality of Large Language Models

【7】A Survey of Large Language Models

相关文章:

【大模型实战篇】高质量数据过滤及一种BoostedBaggingFilter处理方法的介绍

1. 高质量数据过滤 1.1 背景介绍 数据质量对于大模型的训练至关重要&#xff0c;经常会听到一句话&#xff1a;数据决定模型的上限。模型的性能上限通常受到训练数据的质量限制。如果数据集不够好&#xff0c;模型可能无法学习到泛化的特征&#xff0c;导致其在新数据上的表…...

使用Python和Proxy302代理IP高效采集Bing图片

目录 项目背景一、项目准备环境配置 二、爬虫设计与实现爬虫设计思路目标网站分析数据获取流程 代码实现1. 初始化爬虫类&#xff08;BingImageSpider&#xff09;2. 创建存储文件夹3. 获取图像链接4. 下载图片5. 使用Proxy302代理IP6. 主运行函数 运行截图 三、总结 项目背景 …...

Python酷库之旅-第三方库Pandas(118)

目录 一、用法精讲 521、pandas.DataFrame.drop_duplicates方法 521-1、语法 521-2、参数 521-3、功能 521-4、返回值 521-5、说明 521-6、用法 521-6-1、数据准备 521-6-2、代码示例 521-6-3、结果输出 522、pandas.DataFrame.duplicated方法 522-1、语法 522-2…...

讨论人机交互研究中大语言模型的整合与伦理问题

概述 论文地址&#xff1a;https://arxiv.org/pdf/2403.19876.pdf 近年来&#xff0c;大规模语言模型发展迅速。它们给研究和教育领域带来了许多变化。这些模型也是对人机交互&#xff08;HCI&#xff09;研究过程的有力补充&#xff0c;可以分析定性和定量数据&#xff0c;再…...

OpenCV结构分析与形状描述符(23)确定一个点是否位于多边形内的函数pointPolygonTest()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 进行点在轮廓内的测试。 该函数确定点是在轮廓内、轮廓外&#xff0c;还是位于一条边上&#xff08;或与顶点重合&#xff09;。它返回正值&…...

GitLab CI_CD 从入门到实战笔记

第1章 认识GitLab CI/CD 1.3 GitLab CI/CD的几个基本概念 GitLab CI/CD由以下两部分构成。 &#xff08;1&#xff09;运行流水线的环境。它是由GitLab Runner提供的&#xff0c;这是一个由GitLab开发的开源软件包&#xff0c;要搭建GitLab CI/CD就必须安装它&#xff0c;因…...

微服务实战系列之玩转Docker(十五)

前言 博主的玩转Docker系列&#xff0c;今天正式开启第十五篇的征程&#xff01; 在过去的十四篇中&#xff0c;涉及的内容有知识、有原理、有工具、更有实践。当你打开每一篇文章时&#xff0c;均会获得一个特定主题的知识和技巧&#xff0c;助你在云原生的世界里&#xff0c…...

本地调试spark,访问kerberos鉴权的hdfs、hive

文章目录 准备连接hive的配置申请kerberos tgt在scala项目启动本地spark本地Jupyter Notebook启动pyspark 解决在wsl下进行开发、调试时&#xff0c;需要连接kerberos鉴权的hdfs、hive的问题 准备连接hive的配置 core-site.xml、hdfs-site.xml、yarn-site.xml、hive-site.xml复…...

Ubuntu 安装包下载(以20版本 阿里镜像站为例子)

Ubuntu安装包下载 上一篇文章写了一些国内常用的镜像站&#xff0c;这篇以阿里云镜像站Ubuntu20版本为例。 https://mirrors.aliyun.com/ubuntu-releases/ 1.点击自己想要下载的版本 2.点击以amd64.iso为结尾的文件&#xff0c;这个是安装文件&#xff0c;如果是桌面端&…...

会声会影Corel VideoStudio2025旗舰版最新中文旗舰版新功能讲解及使用会声会影使用教程

会声会影Corel VideoStudio2025旗舰版一款功能丰富的视频编辑软件。具有拖放式标题、转场、覆叠和滤镜&#xff0c;色彩分级、动态分屏视频和新增强的遮罩创建器&#xff0c;超越基本编辑&#xff0c;实现影院级效果。优化分屏剪辑功能&#xff0c;简化多时间轴编辑的工作流程&…...

【人工智能】OpenAI发布GPT-o1模型:推理能力的革命性突破,这将再次刷新编程领域的格局!

在人工智能领域&#xff0c;推理能力的提升一直是研究者们追求的目标。就在两天前&#xff0c;OpenAI正式发布了其首款具有推理能力的大语言模型——o1。这款模型的推出&#xff0c;不仅标志着AI技术的又一次飞跃&#xff0c;也为开发者和用户提供了全新的工具来解决复杂问题。…...

2024年TCGA基因表达数据下载(最新版)

文章目录 前言一、如何使用TCGA数据库获取公共数据?二、使用步骤1.点击Cohort Builder2.数据筛选3. Repository4.数据下载4.1 继续选择筛选条件4.2 添加cart并进入4.3 下载 总结 前言 TCGA 全称 The Cancer Genome Atlas &#xff0c;即癌症基因组图谱。它是一个大型的癌症研…...

1. 运动控制指令概要(omron 机器自动化控制器)

机器自动化控制器——第一章 运动控制指令概要 1-1 运动控制指令PLCopen运动控制用功能块运动控制指令概要▶ 运动控制指令的种类▶ 状态变化▶ 运动控制指令的启动和状态▶ 异常处理▶ 执行运动控制指令时输入变量的变更(指令重启)▶ 通过选择缓存模式执行指令多重启动▶ 通过…...

依赖注入(Dependency Injection)

依赖注入是一种设计原则&#xff0c;主要用于减少类之间的紧耦合度&#xff0c;通过将对象的选择和创建逻辑外包给一个容器来实现动态注入。 适用场景&#xff1a; 当需要将对象的生命周期管理和依赖关系外包给外部容器时&#xff08;如Spring DI容器&#xff09;。当应用程序…...

PHP环境搭建

PHP环境搭建教程 PHP 是一种流行的后端开发语言&#xff0c;用于构建动态网站和 Web 应用程序。在开发和部署 PHP 项目之前&#xff0c;您需要设置一个适当的 PHP 环境。本教程将帮助您在不同操作系统上快速搭建 PHP 环境。 1. 环境准备 1.1 操作系统 本教程将介绍在以下操作…...

小叶OJ 2716: 过河问题 ← 贪心算法

【题目来源】http://xiaoye.ac.cn/problem.php?id2716【题目描述】 有 n 个人要渡河&#xff0c;但只有一条小船&#xff0c;这条小船一次只能坐下最多两个人&#xff0c;并且只有一副船桨。每个人划船的速度不一样&#xff0c;如果两个人一起上船&#xff0c;由于重量变大&am…...

LeetCode509:斐波那契数列

代码如下 class Solution { public:int fib(int n) {//这个是为了特殊n&#xff0c;当n 0时&#xff0c; 当 n 1时。if(n 0) return 0;if(n 1) return 1;//第一次开dp专题&#xff0c;连dp数组都忘记定义了。只写了下面&#xff0c;哭vector<int> dp(n 1, 0);dp[…...

5G前传-介绍

1. 引用 知识分享系列一&#xff1a;5G基础知识-CSDN博客 5G前传的最新进展-CSDN博客 灰光和彩光_通信行业5G招标系列点评之二&#xff1a;一文读懂5G前传-光纤、灰光、彩光、CWDM、LWDM、MWDM...-CSDN博客 术语&#xff1a; 英文缩写描述‌BBU&#xff1a;Building Baseba…...

【Python机器学习】循环神经网络(RNN)——超参数

几乎所有模型都可以根据数据和样本进行调整&#xff0c;它们都有各自的优势和相应的利弊权衡方式。寻找最优超参数集通常是一个棘手的问题&#xff0c;但是人类的直觉和经验可以为我们提供解决问题的方法。比如之前的例子&#xff1a; #设置任意输入序列的最大长度 maxlen100 …...

【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树

在安卓源码的设计中&#xff0c;将将屏幕分为了37层&#xff0c;不同的窗口将在不同的层级中显示。 对这一块的概念以及相关源码做了详细分析&#xff0c;整理出以下几篇。 【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树 【Android 13源码分析】WindowCon…...

Node.js的学习2——内置模块(一)

Node.js的内置模块 module模块global全局变量Console控制台Errors错误模块捕获异常异步方法通过回调函数传递异常事件触发器对象异常捕获 module模块 使用module模块可以查看Node.js所有的内置模块、在所有模块中都可以使用的全局变量、程序在运行过程中可能会出现的四类错误。…...

信息安全工程师(5)域名与域名解析

一、域名 1. 定义与功能 域名&#xff08;Domain Name&#xff09;是互联网上用于标识网站或服务器地址的名称&#xff0c;由一串由点分隔的字符组成&#xff0c;如“example.com”。域名的主要功能是提供一种便于记忆和输入的地址形式&#xff0c;以代替难以记忆的IP地址。域名…...

idear导入他人项目如何快速运行

最近idear经常导入别人的项目&#xff0c;结果永远在加载依赖项。网上查了一堆资料&#xff0c;什么jdk问题&#xff0c;环境变量问题&#xff0c;maven仓库路径问题&#xff0c;总之就是没啥用。那有没有什么简单粗暴的办法&#xff0c;能够导入项目后快速运行呢。 解决方法&a…...

直流无刷电机霍尔线序自学习解释

直流无刷电机霍尔线序自学习 步骤详解 1. 初始连接 连接电机的三相线&#xff1a;A、B、C。连接霍尔传感器线&#xff1a;HA、HB、HC。 2. 输入电压组合与霍尔信号记录 电机的电压输入组合和霍尔信号记录是电机控制系统中至关重要的一部分&#xff0c;它们决定了电机的运转…...

C++学习笔记(26)

七 、显示字符串中的字符 从界面上输入一个字符串&#xff08;C 风格&#xff09;&#xff0c;把字符串中的每个字符显示出来&#xff0c;如果输入的是"abc"&#xff0c;要求&#xff1a; 1&#xff09;正序显示&#xff1a;a b c 2&#xff09;逆序显示&#xff1a;…...

安卓14剖析SystemUI的ShadeLogger/LogBuffer日志动态控制输出dumpsy机制

背景&#xff1a; 看SystemUI的锁屏相关代码时候发现SystemUI有一个日志打印相关的方法调用&#xff0c;相比于常规的Log.i直接可以logcat查看方式还是比较新颖。 具体日志打印代码如下&#xff1a; 下面就来介绍一下这个ShadeLogger到底是如何打印的。 分析源码&#xff1…...

华为CNA VRM搭建(使用vmware worfstartion搭建)

创建虚拟机&#xff1a; 自定义→高级 选择硬件兼容性&#xff1a;默认安装版本&#xff0c;如果未来想要将此虚拟机安装到其他电脑&#xff0c;其他电脑版本过低&#xff0c;此时可以向下兼容&#xff0c;这里我们默认版本 稍后安装操作系统&#xff1a; CNA采用Euler OS系统…...

【WRF工具】WRF Domain Wizard第二期:使用教程

【WRF工具】WRF Domain Wizard第二期&#xff1a;使用教程 WRF Domain Wizard使用教程1&#xff09;Wizard Option&#xff1a;新建区域/打开已有区域2&#xff09;New Domain&#xff1a;新建区域3&#xff09;Horizontal Editor&#xff1a;水平编辑器4&#xff09;Namelist.…...

智能摄像头MP4格式化恢复方法

如果说生孩子扎堆&#xff0c;那很显然最近智能摄像头多碎片的恢复也扎堆了&#xff0c;这次恢复的是一个不知名的小品牌。其采用了mp4视频文件方案&#xff0c;不过这个案例的特殊之处在于其感染了病毒且不只一次&#xff0c;我们来看看这个小品牌的智能恢复头格式化的恢复方法…...

【C++】unordered系列

前言&#xff1a; 在C11及以后的标准中&#xff0c;unordered容器是标准模板库&#xff08;STL&#xff09;的一部分&#xff0c;提供了高效的数据结构选项&#xff0c;适用于需要快速查找和插入操作的场景。 unordered通常与关联容器一起使用&#xff0c;特别是unordered_map和…...