端到端语音识别案例
《DeepSeek大模型高性能核心技术与多模态融合开发(人工智能技术丛书)》(王晓华)【摘要 书评 试读】- 京东图书
语音识别这一技术正如其名,是通过精密地解析说话人的语音来识别并准确转写出其所说的内容。它不仅仅是一个简单的转录过程,更是一项融合了声学、语言学、计算机科学等多个学科领域精华的高科技产物。在现代社会中,随着人工智能技术的飞速发展,语音识别技术正日益显现出其巨大的应用潜力和广阔的市场前景。
无论是在智能手机上的语音助手,还是在家庭中的智能音箱,甚至是在车载系统中,语音识别技术都扮演着举足轻重的角色。它能够将人们的口头语言迅速转化为文字信息,从而极大地提高了交互的便捷性和效率。不仅如此,语音识别还在无障碍沟通、语音搜索、自动化客服等众多领域发挥着不可或缺的作用,为人们的生活和工作带来了前所未有的便利。
11.3.1 全中文音频数据集的准备
我们将使用全中文的音频信号进行转换,这里首选使用aidatatang_200zh数据集作为我们的音频转换目标。aidatatang_200zh是一个用于语音识别的数据集,包含30万条口语化句子,由6408人录制,涵盖不同年龄段和34个省级行政区域。录音环境为安静的室内,采用16kHz 16bit的wav单声道格式,总大小为18G。该数据集适用于语音识别、机器翻译和声纹识别等场景,标注准确率不低于98%。
Aidatatang_200zh是一套开放式中文普通话电话语音库。语料库长达200小时,由Android系统手机(16kHz,16位)和iOS系统手机(16kHz,16位)记录。邀请来自中国不同重点区域的600名演讲者参加录音,录音是在安静的室内环境或环境中进行,其中包含不影响语音识别的背景噪音。参与者的性别和年龄均匀分布。语料库的语言材料是设计为音素均衡的口语句子。每个句子的手动转录准确率大于98%。
读者很容易在互联网上搜索到这个数据集的相关内容,下载解压后的单个文件如图11-8所示。
图11-8 载解压后的单个文件示例
我们说过,对于第一步单文本生成来说,并不需要对语音数据进行批匹配,因此在这一步进行数据读取时仅仅读取txt文本文件中的数据即可。
通过解压后的文件可以看到,Aidatatang_200zh提供了600个文件夹,每个文件夹中存放若干个文本与语音对应的文件,其通过文件名进行一一对应。
首先,第一步是读取所有的文件,代码如下所示。
import os
# 这个是列出所有目录下文件夹的函数
def list_folders(path):"""列出指定路径下的所有文件夹名"""folders = []for root, dirs, files in os.walk(path):for dir in dirs:folders.append(os.path.join(root, dir))return folders
from torch.utils.data import DataLoader, Datasetdef list_files(path):files = []for item in os.listdir(path):file = os.path.join(path, item)if os.path.isfile(file):files.append(file)return files#这里作者使用的是自定义的数据集存放位置,读者可以改成自己所对应的语音数据集位置
dataset_path = "D:/语音识别_数据集/aidatatang_200zh/dataset"folders = list_folders(dataset_path) #获取了所有文件夹for folder in tqdm(folders):_files = list_files(folder) for _file in _files:if _file.endswith("txt"):with open(_file,encoding="utf-8") as f:line = f.readline().strip()
其中folders是Aidatatang_200zh目录下所有文件夹,list_folders的作用是对每个文件夹进行重新读取。
接下来,一个非常重要的内容就是建立相应的字库文件,这里我们可以在读取全部文本数据之后使用set结构对每个字符进行存储。
vocab = set()
……
for folder in tqdm(folders):_files = list_files(folder)for _file in _files:if _file.endswith("txt"):with open(_file,encoding="utf-8") as f:line = f.readline().strip()for char in line:vocab.add(char)
vocab = list(sorted(vocab))
11.3.2 音频特征的提取与融合
梅尔频谱作为音频提取的主要方法,其作用在于对提取的音频信号进行高效的转换与分析。通过模拟人类听觉系统的特性,梅尔频谱能够将复杂的音频数据转化为易于处理和解读的频域表示,从而揭示出音频信号中的关键特征和潜在结构。这种转换不仅有助于简化音频处理流程,还能提高特征提取的准确性和效率,为后续的音频识别、分类和合成等任务奠定坚实基础。因此,梅尔频谱在音频处理领域具有广泛的应用价值,是研究人员和工程师们不可或缺的工具之一。
梅尔频谱的独特之处在于其基于梅尔刻度的频率划分方式。与传统的线性频率刻度相比,梅尔刻度更符合人类听觉系统对频率的感知特性。在梅尔频谱中,低频段的分辨率较高,能够捕捉到更多的细节信息,而高频段的分辨率则相对较低,以适应人类对高频声音的不敏感性。这种特性使得梅尔频谱在处理具有丰富低频成分的音频信号时表现出色,如语音和音乐等。
此外,梅尔频谱还具有良好的抗噪性能和稳定性。在音频信号受到噪声干扰或质量下降时,梅尔频谱仍能有效地提取出有用的特征信息,保持较高的识别准确率。这使得梅尔频谱在实际应用中具有更强的鲁棒性和可靠性,能够满足各种复杂场景下的音频处理需求。
基于librosa库完成的特征信号提取,其代码如下所示。
# 计算梅尔频率图
def compute_melspec(y, sr, n_mels, fmin, fmax):""":param y:传入的音频序列,每帧的采样:param sr: 采样率:param n_mels: 梅尔滤波器的频率倒谱系数:param fmin: 短时傅里叶变换(STFT)的分析范围 min:param fmax: 短时傅里叶变换(STFT)的分析范围 max:return:"""# 计算Mel频谱图的函数melspec = lb.feature.melspectrogram(y=y, sr=sr, n_mels=n_mels, fmin=fmin, fmax=fmax) # (128, 1024) 这个是输出一个声音的频谱矩阵# 是Python中用于将音频信号的功率值转换为分贝(dB)值的函数melspec = lb.power_to_db(melspec).astype(np.float32)# 计算MFCCmfccs = lb.feature.mfcc(S=melspec)return melspec,mfccs
从上面代码可以看到,我们通过梅尔频谱获取到了梅尔特征以及梅尔频率倒谱系数,这是从不同的角度对语音特征进行提取。
接下来就是我们希望将提取到的特征进行融合,具体融合的方式可以在数据特征输入到模型之前完成,即在特征提取后,经过一个正则化处理使用在特定维度拼接的方式完成,代码如下所示。
# 对输入的频谱矩阵进行正则化处理
def mono_to_color(X, eps=1e-6, mean=None, std=None):mean = mean or X.mean()std = std or X.std()X = (X - mean) / (std + eps)_min, _max = X.min(), X.max()if (_max - _min) > eps:V = np.clip(X, _min, _max)V = 255. * (V - _min) / (_max - _min)V = V.astype(np.uint8)else:V = np.zeros_like(X, dtype=np.uint8)return V
……
def audio_to_image(audio, sr, n_mels, fmin, fmax):melspec,mfccs = compute_melspec(audio, sr, n_mels, fmin, fmax) #(128, 688)melspec = mono_to_color(melspec)mfccs = mono_to_color(mfccs)spec = np.concatenate((melspec, mfccs), axis=0)return spec
这里需要注意,我们获取到的音频特征,由于其采样的方式不同,其数值大小也千差万别。因此,在进行concatenate拼接之前,需要进行正则化处理。
获取数据的完整代码如下:
from tqdm import tqdm
import os# 这个是列出所有目录下文件夹的函数
def list_folders(path):"""列出指定路径下的所有文件夹名"""folders = []for root, dirs, files in os.walk(path):for dir in dirs:folders.append(os.path.join(root, dir))return folders
from torch.utils.data import DataLoader, Datasetdef list_files(path):files = []for item in os.listdir(path):file = os.path.join(path, item)if os.path.isfile(file):files.append(file)return filesdataset_path = "D:/语音数据库/aidatatang_200zh"
#dataset_path = "../dataset/aidatatang_200zh/"
folders = list_folders(dataset_path)
folders = folders[:5]max_length = 18
sampling_rate = 16000
wav_max_length = 22#这里的计数单位是秒
context_list = []
token_list = []
wav_image_list = []for folder in tqdm(folders):_files = list_files(folder)for _file in _files:if _file.endswith("txt"):#_file = "D:/aidatatang_200zh/G0084/T0055G0084S0496.txt"with open(_file,encoding="utf-8") as f:line = f.readline().strip()if len(line) <= max_length:wav_name = _file.replace("txt", "wav")audio, orig_sr = sf.read(wav_name, dtype="float32") # 这里均值是 1308338, 0.8中位数是1730351,所以我采用了中位数的部分audio = sound_untils.crop_or_pad(audio, length=sampling_rate * wav_max_length) # 我的想法是把audio做一个整体输入,在这里就所有的都做了输入wav_image = sound_untils.audio_to_image(audio, sampling_rate, 128, 0, sampling_rate//2) #输出的是(128, 688)wav_image_list.append(wav_image)#token_list.append(token)np.save("./saver/wav_image_list.npy",wav_image_list)
这里为了加速模型的训练,我们首先读取了音频,并创建了融合后的音频特征,将其进行存储。为了将数据输入到模型中,还需要实现torch.utils.data.Dataset数据类。代码如下:
class TextSamplerDataset(torch.utils.data.Dataset):def __init__(self, token_list = token_list,wav_image_list = wav_image_list):super().__init__()self.token_list = token_listself.wav_image_list = wav_image_listdef __getitem__(self, index):token = self.token_list[index]token = torch.tensor(token).long()token_inp, token_tgt = token[:-1], token[1:]wav_image = self.wav_image_list[index]#sound_untils.audio_to_image(audio, sampling_rate, 128, 0, sampling_rate//2) #输出的是(128, 688)wav_image = torch.tensor(wav_image,dtype=torch.float).float()return token_inp,wav_image,token_tgtdef __len__(self):return len(self.token_list)
11.3.3 基于生成模型的端到端语音识别任务
我们需要完成的是基于端到端的语音识别任务,特别是使用生成模型将输入的语音特征转化为文本内容,遇到的第一个问题将会是如何将可变的生成文本与语音特征信号进行融合。
首先,我们采用将语音特征压缩特性的方式进行融合,即将多维的语音特征压缩成一维后与输入的可变长度的文本信息相加后进行处理,代码如下:
class ReshapeImageLayer(torch.nn.Module):def __init__(self):super().__init__()self.reshape_layer = torch.nn.Linear(688,model_cfg.dim * 2)self.norm = layers.LayerNorm(model_cfg.dim * 2)self.act = layers.SwiGLU()def forward(self,image):image = self.reshape_layer(image)image = self.norm(image)image = self.act(image)image = torch.permute(image,[0,2,1])image = torch.nn.AdaptiveAvgPool1d(1)(image)image = torch.permute(image,[0,2,1])return image
上面代码创建了一个简单的卷积层对信号进行提取,之后通过了AvgPool对特征进行压缩,在调整维度后进行返回。
对于生成模型来说,其核心就是采用注意力机制建立跨区域关注。因此,我们可以在创建因果掩码后完成生成模型的设计。代码如下:
class GLMSimple(torch.nn.Module):def __init__(self,dim = model_cfg.dim,num_tokens = model_cfg.num_tokens,device = all_config.device):super().__init__()self.num_tokens = num_tokensself.causal = model_cfg.causalself.device = deviceself.token_emb = torch.nn.Embedding(num_tokens,dim)self.layers = torch.nn.ModuleList([])for _ in range(model_cfg.depth):block = GLMBlock()self.layers.append(block)self.to_logits = torch.nn.Linear(dim, num_tokens, bias=False)self.reshape_layer = ReshapeImageLayer()self.merge_norm = layers.LayerNorm(dim)def forward(self,x,image = None):if not self.causal:mask = x > 0x = x.masked_fill(~mask, 0)else:mask = Nonex = self.token_emb(x)image = self.reshape_layer(image)for layer in self.layers:x += imagex = self.merge_norm(x)x = x + layer(x, mask = mask)x = torch.nn.Dropout(0.1)(x)logits = self.to_logits(x)return logits
在上面代码中,GLMBlock是我们实现的经典的因果注意力模型,目的是将向量化处理后的可变文本特征与一维的语音特征相加后,输入到因果注意力模型进行计算。
为了配合因果注意力机制的输入,对于文本的最终输入,我们也可以采用比较巧妙的设计,代码如下:
@torch.no_grad()
def generate(self, seq_len, image=None, temperature=1., filter_logits_fn=top_k,filter_thres=0.99, pad_value=0., eos_token=2, return_seq_without_prompt=True, #这个的作用是在下面随机输出的时候,把全部的字符输出):# 这里是我后加上去的,输入进来可以是listimage = torch.tensor(image,dtype=torch.float).float()image = torch.unsqueeze(image,dim=0)image = image.to(self.device)prompt = torch.tensor([1])prompt = prompt.to(self.device)prompt, leading_dims = pack([prompt], '* n')n, out = prompt.shape[-1], prompt.clone()#wrapper_fn = identity if not use_tqdm else tqdmsample_num_times = max(1, seq_len - prompt.shape[-1])for _ in (range(sample_num_times)):logits = self.forward(out,image)logits = logits[:, -1]sample = gumbel_sample_once(logits, temperature=temperature, dim=-1)out, _ = pack([out, sample], 'b *')if exists(eos_token):is_eos_tokens = (out == eos_token)if is_eos_tokens.any(dim=-1).all():breakout, = unpack(out, leading_dims, '* n')if not return_seq_without_prompt:return outreturn out[..., n:]
上面代码中,我们采用generate 函数来产生输入的文本内容,随后通过逐个添加字符的方式逐步扩充所给信息,进而利用下一个字符的预测来完成最终结果的构建。
相关文章:
端到端语音识别案例
《DeepSeek大模型高性能核心技术与多模态融合开发(人工智能技术丛书)》(王晓华)【摘要 书评 试读】- 京东图书 语音识别这一技术正如其名,是通过精密地解析说话人的语音来识别并准确转写出其所说的内容。它不仅仅是一个简单的转录过程&#…...
iOS自定义collection view的page size(width/height)分页效果
前言 想必大家工作中或多或少会遇到下图样式的UI需求吧 像这种cell长度不固定,并且还能实现的分页效果UI还是很常见的 实现 我们这里实现主要采用collection view,实现的方式是自定义一个UICollectionViewFlowLayout的子类,在这个类里对…...
CI/CD基础知识
什么是CI/CD CI:持续集成,开发人员频繁地将代码集成到主干(主分支)中每次集成都通过自动化构建和测试来验证,从而尽早发现集成错误,常用的CI工具包括Jenkins、Travis CI、CircleCI、GitLab CI等 CD&#…...
MySQL 的 SQL 语句执行顺序
MySQL 的 SQL 语句执行顺序并不完全按照代码的书写顺序执行,而是遵循一套固定的逻辑流程 1. FROM 和 JOIN 作用:确定查询的数据来源,包括表和它们的连接方式(如 INNER JOIN, LEFT JOIN 等)。 细节: 先执行…...
Dubbo(21)如何配置Dubbo的注册中心?
在分布式系统中,注册中心是一个关键组件,用于服务的注册和发现。Dubbo 支持多种注册中心,包括 ZooKeeper、Nacos、Consul、Etcd 等。下面详细介绍如何配置 Dubbo 的注册中心,以 ZooKeeper 为例。 配置步骤 引入依赖:…...
AISEO中的JSON 如何部署?
一、JSON 是什么? JSON(JavaScript Object Notation) 是一种轻量级的数据格式,用于在不同系统之间传递结构化信息。它的核心特点是: 易读:用简单的 {键: 值} 对表示数据,例如: json…...
力扣hot100——最长连续序列(哈希unordered_set)
题目链接:最长连续序列 1、错解:数组做哈希表(内存超出限制) int longestConsecutive(vector<int>& nums) {vector<bool> hash(20000000010, false);for(int i0; i<nums.size();i){hash[1000000000nums[i]]t…...
几种常见的.NET单元测试模拟框架介绍
目录 1. Moq 2. NSubstitute 3. AutoFixture 4. FakeItEasy 总结对比 单元测试模拟框架是一种在软件开发中用于辅助单元测试的工具。 它的主要作用是创建模拟对象来替代真实对象进行测试。在单元测试中,被测试的代码可能依赖于其他组件或服务,如数…...
装饰器模式与模板方法模式实现MyBatis-Plus QueryWrapper 扩展
pom <dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 --> </dependency>MPJLambdaWrapperX /*** 拓展 MyBatis Plus Join QueryWrapper 类&…...
11-SpringBoot3入门-整合aop
1、概念(个人理解) AOP(Aspect Oriented Programming),面向切面编程。 1)切面(Aspect):提供切入连接点的方法 2)连接点(Joinpoint)…...
naive_admin项目实战03 基于Go语言的后端
01.使用Goland打开项目 02.使用Goland连接MySQL 03.执行SQL脚本 set names utf8mb4; set foreign_key_checks 0;-- ---------------------------- -- table structure for permission -- ---------------------------- drop table if exists permission; create table permiss…...
基于卷积神经网络的眼疾识别系统,resnet50,efficentnet(pytorch框架,python代码)
更多图像分类、图像识别、目标检测、图像分割等项目可从主页查看 功能演示: 眼疾识别系统resnet50,efficentnet,卷积神经网络(pytorch框架,python代码)_哔哩哔哩_bilibili (一)简介…...
Python数据可视化-第1章-数据可视化与matplotlib
环境 开发工具 VSCode库的版本 numpy1.26.4 matplotlib3.10.1 ipympl0.9.7教材 本书为《Python数据可视化》一书的配套内容,本章为第1章 数据可视化与matplotlib 本文主要介绍了什么是数据集可视化,数据可视化的目的,常见的数据可视化方式…...
Ansible playbook-ansible剧本
一.playbook介绍 便于功能的重复使用 本质上就是文本文件,一般都是以.yml结尾的文本文件。 1.遵循YAML语法 1.要求同级别代码要有相同缩进,建议4个空格。【同级别代码是同一逻辑的代码】 在计算机看来空格和Tob键是两个不同的字符。 2.一个键对应一…...
UDP网络通信
UDP网络通信: 步骤1 创建套接字: #include <sys/types.h> #include <sys/socket.h>int socket(int domain, int type, int protocol);参数一 domain: AF_UNIX Local communication unix(7) 本地通信 AF_INET IPv4 Inte…...
【学习笔记】计算机网络(六)
第6章应用层 文章目录 第6章应用层6.1 域名系统DNS6.1.1 域名系统概述6.1.2 互联网的域名结构6.1.3 域名服务器域名服务器的分区管理DNS 域名服务器的层次结构域名服务器的可靠性域名解析过程-两种查询方式DNS 高速缓存机制 6.2 文件传送协议6.2.1 FTP 概述6.2.2 FTP 的基本工作…...
RK3588使用笔记:系统算法依赖库安装
一、前言 嵌入式设备随着需求的提升,不再仅仅只只运行个单机程序那么简单了,社会发展设备升级,都会逐步引用人工智能,涉及到算法模型,这里基础的部分就是算法环境的安装,有的算法是C,大部分算法…...
数据结构C语言练习(单双链表)
本篇练习题(单链表): 1.力扣 203. 移除链表元素 2.力扣 206. 反转链表 3.力扣 876. 链表的中间结点 4.力扣 21. 合并两个有序链表 5. 牛客 链表分割算法详解 6.牛客 链表回文结构判断 7. 力扣 160. 相交链表 8. 力扣 141 环形链表 9. 力扣 142 环形链表 II…...
Linux驱动开发 中断处理
目录 序言 1.中断的概念 2.如何使用中断 中断处理流程 中断上下文限制 屏蔽中断/使能 关键区别与选择 上半部中断 下半部中断 软中断(SoftIRQ) 小任务(Tasklet) 工作队列(Workqueue) 线程 IRQ(Threaded IRQ…...
C++ set map
1.set和map是什么 set和map是 C STL 提供的容器,用于高效的查找数据,底层采用红黑树实现,其中set是Key模型,map是Key-Value模型 set和map的基本使用较为简单,这里不再叙述,直接进入实现环节 2.set和map的…...
Vue2和Vue3响应式的基本实现
目录 简介Vue2 响应式Vue2 响应式的局限性 Vue3 响应式Vue3 响应式的优点 Vue2 和 Vue3 响应式对比 简介 在 Vue 框架中,数据的响应式是其核心特性之一。当页面数据发生变化时,我们希望界面能自动更新,而不是手动操作 DOM。这就需要对数据进…...
PyQt6实例_批量下载pdf工具_界面开发
目录 前置: 代码: 视频: 前置: 1 本系列将以 “PyQt6实例_批量下载pdf工具”开头,放在 【PyQt6实例】 专栏 2 本系列涉及到的PyQt6知识点: 线程池:QThreadPool,QRunnable; 信号…...
FOC 控制笔记【三】磁链观测器
一、磁链观测器基础 1.1 什么是磁链 磁链(magnetic linkage)是电磁学中的一个重要概念,指导电线圈或电流回路所链环的磁通量。单位为韦伯(Wb),又称磁通匝。 公式为: 线圈匝数 穿过单匝数的…...
前端Material-UI面试题及参考答案
目录 Material-UI 的设计理念与 Material Design 规范的关系是什么? 如何通过 npm/yarn/pnpm 安装 Material-UI 的核心依赖? Material-UI 的默认主题系统如何实现全局样式管理? 如何在项目中配置自定义字体和颜色方案? 什么是 emotion 和 styled-components,它们在 Ma…...
【LeetCode基础算法】链表所有类型
1. 遍历链表 二进制链表转整数找出临界点之间的最小和最大距离 2. 删除节点 移除链表元素从链表中移除在数组中存在的节点删除排序链表中的重复元素删除排序链表中的重复元素 II 3. 插入节点 在链表中插入最大公约数 计算最大公约数的内置函数gcd(a,b),也可以m…...
备赛蓝桥杯之第十六届模拟赛第1期职业院校组第五题:回忆画廊
提示:本篇文章仅仅是作者自己目前在备赛蓝桥杯中,自己学习与刷题的学习笔记,写的不好,欢迎大家批评与建议 由于个别题目代码量与题目量偏大,请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题࿰…...
51 驱动 INA219 电流电压功率测量
文章目录 一、INA219简介二、引脚功能三、寄存器介绍1.配置寄存器 0x002.分流电压寄存器 0x013.总线电压寄存器 0x024.功率寄存器 0x035.电流寄存器 0x046.基准寄存器 0x05 四、IIC 时序说明1.写时序2.读时序 五、程序六、实验现象1.线路图2.输出数据 一、INA219简介 INA219是…...
JavaScript弹出框的使用:对话框、确认框、提示框、弹窗操作
关于 Window对象和 Document 对象的详细使用,系列文章: 《Window对象的常用属性和方法》 《Document对象的常用属性和方法:getElementById()、getElementsByName()、createElement()方法》 《Document获取元素并修改内容:getElementById()方法、value属性、innerHTML属性、…...
【设计模式】深入解析设计模式:门面模式(外观模式)的定义、优点和代码实现
门面模式(外观模式) SLF4J是门面模式的典型应用(但不仅仅使用了门面模式)。 门面模式定义 门面模式(Facade Pattern)又称为外观模式,提供了一个统一的接口,用来访问子系统中的一群…...
UE5学习笔记 FPS游戏制作34 触发器切换关卡
文章目录 搭建关卡制作触发器传送门显示加载界面 搭建关卡 首先搭建两个关卡,每个关卡里至少要有一个角色 制作触发器传送门 1 新建一个蓝图,父类为actor,命名为portal(传送门) 2 为portal添加一个staticMesh&#…...
UE5学习笔记 FPS游戏制作26 UE中的UI
文章目录 几个概念创建一个UI蓝图添加UI获取UI的引用 切换设计器和UI蓝图将UI添加到游戏场景锚点轴点slotSizeToContent三种UI数据更新方式(Text、Image)函数绑定属性绑定事件绑定 九宫格分割图片按钮设置图片绑定按下事件 下拉框创建添加数据修改样式常用函数 滚动框创建添加数…...
Spring Boot分布式项目重试实战:九种失效场景与正确打开方式
在分布式系统架构中,网络抖动、服务瞬时过载、数据库死锁等临时性故障时有发生。本文将通过真实项目案例,深入讲解Spring Boot项目中如何正确实施重试机制,避免因简单粗暴的重试引发雪崩效应。 以下是使用Mermaid语法绘制的重试架构图和决策…...
首个物业plus系列展 2025上海国际智慧物业博览会开幕
AI赋能服务升级!首个“物业plus”系列展 2025上海国际智慧物业博览会盛大开幕 3月31日,2025上海国际智慧物业博览会(简称“上海物博会”)在上海新国际博览中心N4馆隆重开幕。本届展会由广州旭杨国际展览有限公司主办,…...
《C++多线程下单例 “锁钥” 法则》
一、概述 本文章介绍了一段 C 代码,该代码实现了在多线程环境下的单例模式。单例模式确保一个类只有一个实例,并提供全局访问点。在多线程场景中,需要额外的同步机制来保证单例对象创建的线程安全性。单例模式在许多场景中都有重要应用&#…...
WEB或移动端常用交互元素及组件 | Axure / 元件类型介绍(表单元件、菜单和表格 、流程元件、标记元件)
文章目录 引言I Axure / 元件类型介绍基本元件表单元件菜单和表格流程元件标记元件II Axure 基础Axure / 常用功能介绍Axure / 常用元素实例Axure / 动态交互实例Axure / 常用设计分辨率推荐III Axure / 创建自己的元件库元件库作用元件库的创建及使用引言 I Axure / 元件类型介…...
开发环境解决Secure Cookie导致302重定向
问题现象与根源分析 故障现象 前端本地开发时(HTTP协议),调用接口返回302 Found状态码浏览器控制台警告:“Cookie被阻止,因为设置了Secure属性但未通过HTTPS传输”登录态无法保持,页面陷入重定向循环 技…...
华为三进制逻辑与高维量子计算的对比分析
此博客深入探讨华为三进制逻辑状态的技术意义,并与高维量子计算系统进行对比。文章将全面展开技术原理、实现机制、计算能力对比、未来应用前景等方面的内容。 目录 引言 华为三进制逻辑的创新意义 2.1 二进制逻辑的局限与历史探索 2.2 三进制逻辑的优势ÿ…...
网红指路机器人是否支持环境监测功能?
嘿呀,你可知道?如今的叁仟网红指路机器人那可太牛啦!它们可不单单局限于为行人指明方向,还纷纷兼职当起了 “环境小卫士”,为咱们的城市生活注入了前所未有的超智能便利。就拿那个依托叁仟智慧杆打造的数智指路机器人来…...
【进阶】vscode 中使用 cmake 编译调试 C++ 工程
基于 MSYS2 的 MinGW-w64 GCC 工具链与 CMake 构建系统,结合VSCode及其扩展插件( ms-vscode.cmake-tools),可实现高效的全流程C开发调试。既可通过 VSCode 可视化界面(命令面板、状态栏按钮)便捷完成配置、…...
突发,国行 iPhone 17,支持 eSIM
古人云“无心生大用”,往往你感到绝望的时候,转机就莫名其妙的来了。 根据供应链的最新消息,国行 iPhone 17 Air,有望用上 eSIM。 不仅如此,国产手机厂商,也计划推出类似iPhone 17 Air的超薄机型…...
红宝书第二十二讲:详解JavaScript类型化数组与二进制数据处理
红宝书第二十二讲:详解JavaScript类型化数组与二进制数据处理 资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲 一、为什么需要类型化数组? 普通JavaScript数组(Array࿰…...
Elasticsearch安全与权限控制指南
在Elasticsearch维护中,安全管理是保障数据合规性和集群稳定性的关键。本文将详细介绍用户与角色管理、索引/字段级权限控制、HTTPS加密通信、审计日志与合规性检查等核心安全实践,希望可以帮助你构建更安全的Elasticsearch环境。 1 用户与角色管理 1.1…...
SAP 学习笔记 - 系统移行业务 - MALSY(由Excel 移行到SAP 的收费工具)
以前有关移行,也写过一些文章,比如 SAP 学习笔记 - 系统移行业务 - Migration cockpit工具 - 移行Material(品目)-CSDN博客 SAP 学习笔记 - 系统移行业务 - Migration cockpit工具2 - Lot导入_sap cockpit-CSDN博客 SAP学习笔记…...
【群智能算法改进】一种改进的蜣螂优化算法IDBO[3](立方混沌映射Cubic、融合鱼鹰勘探策略、混合高斯柯西变异)【Matlab代码#92】
文章目录 【获取资源请见文章第5节:资源获取】1. 原始DBO算法2. 改进后的IDBO算法2.1 立方混沌映射Cubic种群初始化2.2 融合鱼鹰勘探策略2.3 混合高斯柯西变异 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节:资源获取】 1. 原始DB…...
《异常检测——从经典算法到深度学习》30. 在线服务系统中重复故障的可操作和可解释的故障定位
《异常检测——从经典算法到深度学习》 0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: …...
座舱与智驾“双轮驱动”,芯擎科技打造智能汽车“芯”标杆
在比亚迪、吉利、奇瑞等各大主机厂打响“全民智驾”的关键时期,以芯擎科技为代表中国芯片厂商开始“放大招”。 2025年3月27日,芯擎科技在南京举办了“擎随芯动、智融万象”生态科技日,重磅发布了“星辰一号”、“星辰一号Lite”,…...
观察者模式在Java单体服务中的运用
观察者模式主要用于当一个对象发生改变时,其关联的所有对象都会收到通知,属于事件驱动类型的设计模式,可以对事件进行监听和响应。下面简单介绍下它的使用: 1 定义事件 import org.springframework.context.ApplicationEvent;pu…...
html5时钟升级!支持切换深浅模式 Canvas实现现代化动态时钟
HTML5 Canvas实现现代化动态时钟 这里写目录标题 HTML5 Canvas实现现代化动态时钟项目介绍技术实现1. 项目架构2. Canvas绘图实现2.1 表盘绘制2.2 刻度绘制2.3 指针绘制 3. 动画效果4. 主题切换 项目亮点技术要点总结项目收获改进方向结语 项目介绍 本项目使用HTML5 Canvas技术…...
Scala(2)
For循环控制 循环守卫 基本语法 for(i <- 1 to 3 if i ! 2) { print(i " ") }println() 说明: 循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为 true 则进入循环体内部,为false 则跳…...
DataGear 5.3.0 制作支持导出表格数据的数据可视化看板
DataGear 内置表格图表底层采用的是DataTable表格组件,默认并未引入导出数据的JS支持库,如果有导出表格数据需求,则可以在看板中引入导出相关JS支持库,制作具有导出CSV、Excel、PDF功能的表格数据看板。 在新发布的5.3.0版本中&a…...