读书笔记:多Transformer的双向编码器表示法(Bert)-4
多Transformer的双向编码器表示法
Bidirectional Encoder Representations from Transformers,即Bert;
第二部分 探索BERT变体
从本章开始的诸多内容,以理解为目标,着重关注对音频相关的支持(如果有的话);
BERT变体:ALBERT、RoBERTTa、ELECTRA、SpanBERT、基于知识蒸馏;
-
ALBERT,A Lite version of BERT,意为BERT模型的精简版;它对BERT的架构做了一些改变,以尽量缩短训练时间;
-
RoBERTTa,Robustly Optimized BERT Pretraining Approach,意为稳健优化的BERT预训练方法,是目前比较流行的BERT变体,被应用到许多先进系统,其工作原理与BERT类似,但预训练步骤商有一些变化;
-
ELECTRA,Efficiently Learning an Encoder that Classifies Token Replacements Accurately,意为高效训练编码器如何准确分类替换标记,特别的ELECTRA使用一个生成器(generator)和一个判别器(discriminator),并使用替换标记检测这一新任务进行预训练;
-
SpanBERT,它被广泛应用于问答任务和关系提取任务;
ALBERT
《ALBERT:A Lite BERT for Self-supervised Learning of Language Representations》
BERT-base有1.1亿个参数,这使得它很难训练,且推理时间较长;
ALBERT的参数量更少,它通过:跨层参数共享、嵌入层参数因子分解,来减少参数量;
这两种方式可以有效缩短BERT模型训练时间和推理时间;
跨层参数共享
我们知道BERT-base由12层编码器组成,所有编码器层的参数将通过训练获得,但在跨层参数共享的情况下,不是学习所有编码器层的参数,而是只学习第一层编码器的参数,然后将第一层编码器的参数与其他所有编码器层共享;
应用跨层参数共享时的几种方式:
- 全共享:其他编码器的所有子层共享编码器1的所有参数(默认所使用的);
- 共享前馈网络层:只将编码器1的前馈网络层的参数与其他编码器的前馈网络层共享;
- 共享注意力层:只将编码器1的多头注意力层的参数与其他编码器的多头注意力层共享;
嵌入层参数因子分解
BERT使用WordPiece词元分析器创建WordPiece标记,WordPiece标记的嵌入大小被设定为与隐藏层嵌入的大小(特征大小)相同,但WordPiece嵌入式无上下文信息的特征,它是从词表的独热(one-hot)编码向量中习得的,而隐藏层嵌入是由编码器返回的有上下文信息的特征;
使用:
- V表示词表大小(BERT词表大小为30000)
- H表示隐藏层嵌入大小
- E表示WordPiece嵌入的大小;
为了将更多信息编码到隐藏层嵌入中,通常将隐藏层嵌入的大小设置为较大的一个数(BERT-base是768);
WordPiece嵌入和 隐藏层嵌入都是通过训练学习的,将二者大小设置的相同,会增加需要学习的参数数量;为避免这种情况,可以使用“嵌入层参数因子分解方法”,将嵌入矩阵分解成更小的矩阵;
通过分解:
- 我们将独热编码向量投射到低维嵌入空间V x E;
- 然后将这个低维嵌入投射到隐藏空间 E x H
- 即不是直接将词表的独热编码向量投射到隐藏空间V x H;
也就是说,我们不是直接投射V x H,而是将这一步分解为 V x E和 E x H;
V = 30000、E = 128、H = 768,可以通过如下步骤投射 V x H
- 将词表V的独热编码向量投射到低维WordPiece嵌入的大小E,即V x E;
- 再将WordPiece嵌入大小E投射到隐藏层H中,即E x H;
ALBERT的训练
ALBERT使用了掩码语言模型构建任务
进行了预训练,但并没有用下句预测任务,而是使用“句序预测任务
”(sentence order prediction,SOP)这一新任务;
研究人员指出:相比掩码语言模型,下句预测并不是一个难的任务;句序预测是基于句子间连贯性,而不是基于主题预测;
句序预测也是一个二分类任务:在给定句子对中,两个句子的顺序是否被调换;模型的目标是分析句子对事属于正例(句子顺序没有互换)还是负例(句子顺序互换);
相比BERT,ALBERT的参数比较少;ALBERT-xxlarge配置的模型在多个语言基准数据集上的性能表现明显优于BERT-large;可以作为BERT的一个很好的替代品;
# 可以像使用BERT那样使用ALBERT模型
from transformers import AlbertTokenizer, AlbertModelmodel = AlbertModel.from_pretrained('albert-base-v2')
tokenizer = AlbertTokenizer.from_pretrained('albert-base-v2')sentence = "I am good"
imputs = tokenizer(sentence, reutrn_tensors = 'pt')# inputs
# {
# 'input_ids':
# 'token_type_ids':
# 'attention_mask':
# }hidden_rep, cls_head = model(**inputs)
RoBERTTa
《RoBERTa:A Robustly Optimized BERT Pretraining Approach》
RoBERTTa本质还是BERT,只是在预训练过程中有如下变化:
- 在掩码语言模型构建任务重使用动态掩码而非静态掩码;
- 不执行下句预测任务;
- 以大批量的方式进行训练;
- 使用
字节级字节对编码
作为子词词元化算法;
静态掩码,指在预处理阶段完成随机掩盖15%标记的处理只做了一次,在多次迭代训练中预测的都是相同的掩码标记;
复制10次句子并进行随机掩盖,然后在多轮遍历训练中,依次使用每个掩盖后的句子;
研究发现,下句预测任务对预训练BERT模型并不是真的有用;因此RoBERTa中,只用了掩码语言模型构建任务来训练模型,输入是一个完整的句子,它是从一个或多个文件中连续采样而得得,输入最多由512个标记组成,如果输入达到一个文件的末尾,那么就从下一个文件开始采样;
BERT的预训练有100万步,批量大小为256;而RoBERTa的批量大小为8000,共30万步(用较大的批量进行训练可以提高模型的速度和性能);
字节级字节对编码:使用字节级序列,所使用的词表有50000个标记;
from transformers import RobertaConfig, RobertaModel, RobertaTokenizermodel = RobertaModel.from_pretrained('roberta-base')
model.config
tokenizer = RobertaTokenizer..from_pretrained('roberta-base')tokenizer.tokenize("I am good")
ELECTRA
ELECTRA没有使用掩码语言模型构建任务作为预训练目标,而是使用一个叫做替换标记检测的任务
进行预训练(并且仅使用了这个任务,下句预测也没用);
使用另一个标记进行替换,并训练模型判断标记是实际标记还是替换后的标记;
之所以这样做是因为,掩码语言模型构建使用了[MASK]
标记,但在下有任务中,这个标记并不存在,这导致了预训练和微调之间的不匹配,使用替换标记检测的任务
解决了预训练和微调之间的不匹配问题;
“判断标记是实际标记还是替换后的标记”的模型成为判别器
,仅做分类;
- 将一个句子随机使用
[MASK]
标记进行替换,然后送入另一个BERT模型,以预测被掩盖的标记,这个模型叫生成器
,它会返回标记的概率分布; - 使用生成器生成的标记 替换给定句子中的
[MASK]
标记; - 训练判别器,训练它对标记进行分类;
- 使用判别器,每个标记都会得到一个判别/分类结果,表示各个表示是替换标记还是实际标记;
基本上来说,判别器就是ELECTRA模型,训练结束后生成器可以移除;
- 生成器执行的是 掩码语言模型构建任务
- 生成器使用sigmoid函数的前馈网络层,返回标记是实际标记还是替换标记;
为了更高效的训练ELECTRA模型,可以在生成器和判别器之间共享权重,前提是二者大小相同,如果不同的话,可以使用较小的生成器,仅共享生成器和判别器之间的嵌入层(标记嵌入和位置嵌入);
from transformers import ElectraTokenizer, ElectraModel# electra-small判别器
model = ElectraModel.from_pretrained("google/electra-small-discriminator")# electra-small生成器
model = ElectraModel.from_pretrained("google/electra-small-generator")
SpanBERT预测文本段
SpanBERT主要用于文本区间的问答任务
- 区别与随机掩盖,SpanBERT是随机地对连续区间进行掩码;
- 然后将其送入SpanBERT,返回每个标记的特征;
为了预测[MASK]
所代表的标记,使用掩码语言模型构建目标和区间边界目标(span boundary objective, SBO)来训练SpanBERT模型;
- 区间边界标记特征
- 使用
[MASK]
的位置嵌入
SpanBERT使用两个目标:
- 一个是掩码语言模型构建目标,为预测掩码标记,只使用相应的标记特征;
- 另一个是区间边界目标,为预测掩码标记,只使用区间边界标记特征和掩码标记的位置嵌入;
# pipeline API 用于无缝地执行从文本分类任务到问答任务等各类复杂任务
from transformers import pipelineqa_pipeline = pipeline("question-answering",model = "mrm8488/spanbert-large-finetuned-squadv2",tokenizer = "SpanBERT/spanbert-large-cased"
)# 输入问题和上下文 即可得到答案
results = qa_pipeline({'question': "What is AI?",'context': "AI is ...."
})results["answer"]
基于知识蒸馏
使用知识蒸馏法可以实现 将知识从预训练的大型BERT模型迁移到小型BERT模型;本章将了解基于知识蒸馏的BERT变体;
- 知识蒸馏
- DistilBERT——BERT模型的知识蒸馏版本
- TunyBERT
- 知识迁移到简单的神经网络
知识蒸馏
知识蒸馏(knowledge distillation)是一种模型压缩技术,指训练一个小模型来重现大型预训练模型的行为;也被称为师生学习,大模型是老师,小模型是学生;
假设通过一个预训练大模型(教师网络)来预测句子中的下一个单词,输入一个句子,网络预测将返回词表中所有单词是下一个单词的概率分布(softmax作用于输出层);
从返回的概率分布中除了概率最高的词,还有一些词的概率也相对较高;这体现了相关单词与输入句子的相关性更高,这就是所谓的隐藏知识
;在知识蒸馏过程中,我们希望学生网络能从教师网络学到这些隐藏知识;
但实际的可用模型,往往会为正确的结果返回一个接近1的高概率,而对其他单词,概率都接近于0,此时概率分布中已经没有太多信息了;为此需要使用带有温度系数的softmax函数
,即softmax温度
;在输出层使用softmax温度,来平滑概率分布(增加T值可以是概率分布更平滑,T=1时即为标准的softmax函数);
通过softmax温度,就可以获得隐藏知识;即先用softmax温度对教师网络进行预训练,获得隐藏知识,然后在知识蒸馏中,将这些隐藏知识从教师网络迁移至学生网络;
训练学生网络
经过预训练的教师网络,在其预训练过程中使用了softmax温度;
将句子送入教师网络和学生网络,其中:
- 教师网络返回的概率分布是我们的目标,教师网络的输出称为
软目标
; - 学生网络做出的预测称为
软预测
; - 最后计算软目标和软预测之间的交叉熵损失,并通过反向传播训练学生网络;
软目标和软预测之间的交叉熵损失也被称为蒸馏损失
;
注意:教师网络和学生网络中,softmax层的T值需保持一致(如T=5),且都大于1;
除了蒸馏损失外,我们还是用另一个损失,称为学生损失;
- 相比软目标,硬目标就是将高概率设置为1,其余概率设置为0;
- 相比软预测,硬预测就是softmax T=1得到的概率分布(标准softmax函数);
学生损失:
- 即硬目标 与 硬预测之间的交叉熵损失;
计算过程:
- 教师网络 使用T=5的softmax函数,得到软目标;
- 对软目标,将具有高概率的位置设置为1,其余设置为0,得到硬目标;
- 学生网络 使用T=5的softmax函数,得到软预测;
- 学生网络 使用T=1的softmax函数,得到硬预测;
- 软目标和软预测之间的交叉熵损失即蒸馏损失;
- 硬目标与硬预测之间的交叉熵损失即学生损失;
最终的损失函数是 两个损失的加权和,权重分别为α和β两个超参数;
总结下:在知识蒸馏中,我们使用预训练网络作为教师网络,训练学生网络通过蒸馏从教师中获得知识;
DistilBERT模型
Hugging Face的研发开发了DistilBERT,是一个更小、更快的轻量级BERT模型;
- 使用BERT-base作为教师
- 一个更少层数的BERT模型,作为学生,隐藏层大小保持在768;
- 可以使用相同的数据集进行训练;
实际训练除了蒸馏损失和学生损失,还需要计算余弦嵌入损失
(cosine embedding loss):它是教师模型和学生模型所学的特征向量
之间的距离,最小化该损失将使学生网络的特征向量更加准确;
损失函数是3中损失之和:
- 蒸馏损失
- 掩码语言模型损失(学生损失)
- 余弦嵌入损失
通过最小化损失之和来训练学生BERT模型,即DistilBERT模型,他可以达到BERT-base 97%的准确度,在8块V100(16G)上进行了大约90小时的训练,该预训练模型Hugging Face也以公开,模型大小仅207MB;
TinyBERT模型
在TinyBERT模型,除了从教师BERT模型的输出层(预测层)向学生BERT模型迁移知识,还可以嵌入层和编码层迁移知识;
具体内容略过;
将知识从BERT模型迁移到神经网络中
《Distilling Tash-Specific Knowledge from BERT into Simple Neural Networks》
教师BERT模型
- 使用预训练的BERT-large模型,需要注意的是,要将特定任务的知识从教师迁移给学生,需要先针对特定任务微调预训练的BERT-large模型,然后再将其作为教师;
学生网络:
- 是一个简单的双向LSTM,学生网络可以根据不同任务而变化;
以句子的情感分析任务为例:
- 将句子嵌入送入双向LSTM,得到前向、后向的隐藏状态;
- 再将前向、后向的隐藏状态;送入带有ReLU激活函数的全连接层,返回logit向量作为输出;
- 将logit向量送入softmax函数,得到该句是正面还是负面的概率;
损失是 学生损失 和 蒸馏损失的加权和;这里使用均方损失(MSE) 作为蒸馏损失,因为它比交叉熵损失的表现更好;学生损失还是硬目标和硬预测之间的标准交叉熵损失;
第三部分 BERT模型的应用
这里我们略过第6章和第7章;
- 第8章 Sentence-BERT模型和特定领域的BERT模型
- 第9章 VideoBERT模型和BART模型
第8章 Sentence-BERT模型和特定领域的BERT模型
主要学习 ClinicalBERT模型,其他内容略过;
我们知道BERT模型是使用维基百科语料库进行的预训练,对于特定领域,也可以使用特定的语料库重新训练BERT;
ClinicalBERT模型就是一个使用大型临床语料库(MIMIC-III)进行预训练的针对临床领域的BERT模型;可以应用到死亡风险评估、诊断预测等下游任务;
ClinicalBERT模型使用掩码语言模型构建任务(penicillin)和下句预测任务(isNext)进行预训练,与BERT一致;
对于超过最大标记长度512的长序列,可以将其拆分成多个子序列,然后使用公式计算分数;
t分布随机邻域嵌入法(t-SNE)被用来绘制使用ClinicalBERT模型获得的医学术语特征,以评估该模型所学到的特征;
第9章 VideoBERT模型和BART模型
VideoBERT模型
- 是第一个联合学习视频特征及语言特征的模型,可应用于图像字幕生成、视频字幕添加、预测视频下一帧等任务;
预训练任务:
- 掩码语言模型构建(完形填空)
语言-视觉对其
任务
旁白和视频画面的对应 有助于联合学习语言及视频的特征;
提取视频中语言标记和视觉标记:
- 使用自动语音识别(ASR)工具,从视频中提取音频,再将音频转换为文本;
- 对文本进行标记,就形成了语言标记;
- 以20帧/秒的速度对视频中图像帧进行采样,然后将图像帧转换成1.5s的视频标记;
语言标记和视频标记结合,使用特殊标记间隔:
- 在语言标记开头添加
[CLS]
标记; [SEP]
标记在视觉标记末尾添加,中间使用[>]
标记间隔;- 使用
[MASK]
进行随机掩蔽,送入VideoBERT,返回所有标记特征;
掩码语言模型构建(完形填空)我们已经了解,对于语言-视觉对其
任务:
- 它也是一个分类任务,预测的是语言标记和视觉标记是否在时间上吻合(对齐),即预测文本是否与视频画面匹配;
- 提取
[CLS]
标记特征,送入一个分类器,对是否一致进行分类;
VideoBERT模型使用了三个目标进行预训练:
- 纯文本
- 纯视频
- 文本-视频
最终预训练目标是上述3个目标的加权组合;
数据源和预处理:
- 使用YouTube教学视频,时长少于15min,共312000个,23186小时;
- 使用YouTube API提供的自动语音识别工具,返回文本和时间戳;不同目标所使用的数据集不同;
对于从视频中采样的图像帧,使用预训练的视频卷积神经网络提取视觉特征,并使用分层的K均值算法对视觉特征进行标记;
VideoBERT模型应用:
- 预测下一个视觉标记;
- 由文本生成视频;
- 生成视频字幕;
BART模型
基于Transformer架构,本质是一个降噪自编码器,通过重建受损文本进行训练的;
带有编码器和解码器的Transformer模型,将受损文本送入编码器学习,将学习得到的特征发送给解码器;解码器获得编码器生成的特征,重建原始文本;
- 双向编码器
- 自回归解码器(单向的)
BART模型通过最小化重建损失来训练,也就是原始文本和解码器的生成文本之间的交叉熵损失
BART模型与BERT模型不同,在BERT中,只是将被掩盖的标记送入编码器,然后将编码器的结果送入前馈网络层,用前馈网络层来预测被掩盖的标记;而在BART中,将编码器的结果反馈给解码器,由其生成或构建原始句子;
集中破坏文本增噪方法:
- 标记掩盖:用
[MASK]
随机替换一些标记 - 标记删除
- 标记填充:用一个
[MASK]
掩盖连续的标记 - 句子重排:随机打乱橘子顺序
- 文档论换:随机选择文档中的一个标记作为文档的开始,然后将所选标记之前的所有标记添加到文档的末尾;
# 文本摘要任务应用
from transformers import BartTokenizer, BartForConditionalGenerationmodel = BartForConditionalGeneration.from_pretrained('facebook/bart-large-cnn')
tokenizer = BartTokenizer.from_pretrained('facebook/bart-large-cnn')text = """
...
"""# 对文本进行标记
inputs = tokenizer([text], max_length=1025, return_tensors='pt')# 获取摘要ids(即模型生成的标记ID)
summary_ids = model.generate(inputs['input_ids'], num_beams=4, max_length=100, early_stopping=True)# 对摘要进行解码
summary = ([tokenizer.decode(i, skip_special_tokens=True, clean_up_tokenization_spaces=False) for i in summary_ids])print(summary)
相关文章:

读书笔记:多Transformer的双向编码器表示法(Bert)-4
多Transformer的双向编码器表示法 Bidirectional Encoder Representations from Transformers,即Bert; 第二部分 探索BERT变体 从本章开始的诸多内容,以理解为目标,着重关注对音频相关的支持(如果有的话)…...

Stable Diffusion XL搭建
本文参考:Stable Diffusion XL1.0正式发布了,赶紧来尝鲜吧-云海天教程 Stable Diffision最新模型SDXL 1.0使用全教程 - 知乎 1、SDXL与SD的区别 (1)分辨率得到了提升 原先使用SD生成图片,一般都是生成512*512&…...
面试题-React(十一):性能优化之PureComponent和memo
一、React性能优化的重要性 随着应用的复杂性增加,React组件的渲染可能成为性能瓶颈。频繁的渲染可能导致不必要的性能开销和卡顿。为了确保应用的高性能和流畅用户体验,我们需要采取一些措施来优化组件的渲染。 二、PureComponent-自动浅比较 PureCo…...

<图像处理> Fast角点检测
Fast角点检测 基本原理是使用圆周长为N个像素的圆来判定其圆心像素P是否为角点,如下图所示为圆周长为16个像素的圆(半径为3);OpenCV还提供圆周长为12和8个像素的圆来检测角点。 相对中心像素的位置信息 //圆周长为16 static c…...
基于centos、alpine制作Java JDK基础镜像
文章目录 前言一、 简介二、制作JDK/Java基础镜像1.准备事项2.制作Dockerfile脚本2.1.基于centos作为基础镜像2.2.基于alpine作为基础镜像3.构建镜像4.测试验证前言 在日常开发中,但凡项目需要docker容器化部署,制作项目镜像前都需要在Dockerfile中配置Java基础镜像。为什么…...

【AI视野·今日Robot 机器人论文速览 第五十二期】Wed, 11 Oct 2023
AI视野今日CS.Robotics 机器人学论文速览 Wed, 11 Oct 2023 Totally 31 papers 👉上期速览✈更多精彩请移步主页 Daily Robotics Papers RoboHive: A Unified Framework for Robot Learning Authors Vikash Kumar, Rutav Shah, Gaoyue Zhou, Vincent Moens, Vittor…...

hive 知识总结
编辑 社区公告教程下载分享问答JD 登 录 注册 01 hive 介绍与安装 1 hive介绍与原理分析 Hive是一个基于Hadoop的开源数据仓库工具,用于存储和处理海量结构化数据。它是Facebook 2008年8月开源的一个数据仓库框架,提供了类似于SQL语法的HQL…...

golang/云原生/Docker/DevOps/K8S/持续 集成/分布式/etcd 教程
3-6个月帮助学员掌握golang后端开发岗位必备技术点 教程时长: 150小时 五大核心专栏,原理源码案例分析项目实战直击工作岗位 golang:解决go语言编程问题 工程组件:解决golang工程化问题 分布式中间件:解决技术栈单一及分布式开发问题 云原生…...

jeecg库login登录过程分析笔记
jeecg库(版本jeecg-boot-v3.5.1last)实现了用户登录功能,二开时为了借鉴jeecg用户登录的方法,跑了一遍登录方法: org.jeecg.modules.system.controller.LoginController#login 定义这个方法的类的路径是:…...

echarts仪表盘vue
<div class"ybptx" ref"btryzb"></div>mounted() {this.getBtData();},getBtData() {var chart this.$echarts.init(this.$refs.btryzb);var data_czzf 88;var option {series: [{name: 内层数据刻度,type: gauge,radius: 80%,min: 0,max: 1…...
管道和重定向分号-连接符
本文介绍shell脚本常用命令连接符:管道符( | )、重定向( < 、>、>>、2> 、&> )、分号( ; ) 本文内容同微信公众号【凡登】,关注不迷路,学习上高速,欢迎关注共同学习。 1、管道 进程的通信方式之一…...
WSL VScode连接文件后无法修改(修改报错)
权限问题 usrname:用户名 dirpath:要修改的文件夹路径 sudo chown -R usrname /dirpath...

迷你Ceph集群搭建(超低配设备)
我的博客原文链接:https://blog.gcc.ac.cn/post/2023/%E8%BF%B7%E4%BD%A0ceph%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA/ 环境 机器列表: IP角色说明10.0.0.15osdARMv7,512M内存,32G存储,百兆网口10.0.0.16clientARM64…...

Python数据挖掘项目实战——自动售货机销售数据分析
摘要:本案例将主要结合自动售货机的实际情况,对销售的历史数据进行处理,利用pyecharts库、Matplotlib库进行可视化分析,并对未来4周商品的销售额进行预测,从而为企业制定相应的自动售货机市场需求分析及销售建议提供参…...

TortoiseGit使用教程
文章目录 一. 创建仓库二. Clone仓库三. 查看修改记录四. 版本回溯五. 创建分支六. 切换分支七. 合并分支八. 删除分支九. TortoiseGit配置1. 常规配置2. 配置远程仓库账户密码3. 配置远程仓库 一. 创建仓库 在需要创建仓库的文件上右键→Git Create repository here… 创建仓…...

如何测量GNSS信号和高斯噪声功率及载波比?
引言 本文将介绍如何测量德思特Safran GSG-7或GSG-8 GNSS模拟器的输出信号功率。此外,还展示了如何为此类测量正确配置德思特Safran Skydel仿真引擎以及如何设置射频设备,从而使用频谱分析仪准确测量信号的射频功率。 什么是载波噪声密度C/N0 GNSS接收…...

动态壁纸软件iWall mac中文特色
iWall for mac是一款动态壁纸软件,它可以使用任何格式的漂亮视频(无须转换),音频(可视化功能),图片,动画,Flash,gif,swf,程序,网页,网站做为您的动态壁纸&…...

xtrabackup全备 增备
版本针对mysql8.0版本 官方下载地址 https://www.percona.com/downloads 自行选择下载方式 yum安装方式 1、下载上传服务器 安装软件 [rootmaster mysql]# ll percona-xtrabackup-80-8.0.33-28.1.el7.x86_64.rpm -rw-r--r--. 1 root root 44541856 Oct 10 13:25 percona-x…...

【广州华锐互动】灭火器使用VR教学系统应用于高校消防演练有什么好处?
在科技发展的大潮中,虚拟现实(VR)技术以其独特的沉浸式体验赢得了各个领域的青睐,其中包括教育和培训。在高校消防演练中,VR也成为了一种新的消防教育方式。 由广州华锐互动开发的VR消防演练系统,就包含了校…...
Pymol做B因子图
分子动力学模拟结束后,获得蛋白的平均结构, 比如获得的平均结构为WT-average.pdb 然后将平均结构导入到Pymol 中,可以得到B因子图。 gmx rmsf -f md_0_100_noPBC.xtc -s md_0_100.tpr -o rmsf-per-residue.xvg -ox average.pdb -oq bfactors…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...