从零开始训练Codebook:基于ViT的图像重建实践
完整代码在文末,可以一键运行。
1. 核心原理
Codebook是一种离散表征学习方法,其核心思想是将连续特征空间映射到离散的码本空间。我们的实现方案包含三个关键组件:
1.1 ViT编码器
class ViTEncoder(nn.Module):def __init__(self, codebook_dim=512):super().__init__()self.vit = ViTModel.from_pretrained("google/vit-base-patch16-224-in21k")self.proj = nn.Linear(768, codebook_dim)def forward(self, x):outputs = self.vit(x).last_hidden_statepatch_embeddings = outputs[:, 1:, :] # 移除CLS tokenreturn self.proj(patch_embeddings)
- 使用预训练的ViT-Base模型提取图像特征
- 移除CLS token,保留196个图像块特征
- 线性投影调整特征维度适配Codebook
1.2 Codebook量化层
class Codebook(nn.Module):def __init__(self, num_embeddings=1024, embedding_dim=512):super().__init__()self.codebook = nn.Embedding(num_embeddings, embedding_dim)def quantize(self, z):# 计算L2距离distances = z_norm - 2 * dot_product + e_norm.unsqueeze(0)# 最近邻查找indices = torch.argmin(distances, dim=1)return indices, self.codebook(indices)
- 使用可学习的Embedding层存储离散码本
- 通过L2距离计算实现最近邻查找
- 支持EMA更新(代码中已注释部分)
1.3 ViT解码器
class ViTDecoder(nn.Module):def __init__(self):self.head = nn.Sequential(nn.ConvTranspose2d(768, 384, 4, 2, 1),nn.ReLU(),... # 更多上采样层nn.Conv2d(48, 3, 1))
- 使用转置卷积逐步上采样
- 最终输出224x224分辨率图像
- 与编码器形成对称结构
2. 训练策略
2.1 多目标损失函数
total_loss = mse_loss + 0.1*percep_loss + codebook_loss + commitment_loss
- MSE Loss: 像素级重建误差
- Perceptual Loss: VGG16特征匹配
- Codebook Loss: 码本向量优化
- Commitment Loss: 编码器输出稳定性
2.2 优化技巧
opt = torch.optim.Adam([{'params': encoder.parameters()},{'params': decoder.parameters()},{'params': codebook.parameters(), 'lr': 1e-4}
], lr=3e-4)
- 分层学习率设置
- EMA指数平滑更新
- 混合精度训练支持
- 动态学习率调整
3. 完整训练流程
3.1 数据准备
transform_train = transforms.Compose([transforms.Resize(224),transforms.RandomCrop(224, padding=4),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize(...)
])
- CIFAR-10数据集
- 随机裁剪+翻转增强
- Batch Size=4适配显存
3.2 训练监控
# TensorBoard记录
writer.add_scalar('Loss/total', total_loss.item(), global_step)
writer.add_image('Reconstruction', grid, global_step)# 控制台日志
print(f"[Epoch {epoch+1:03d}] Loss: {total_loss.item():.4f}")
完整代码
from transformers import ViTModel, ViTConfig
import torch.nn as nn
import torch
import time
from tqdm import tqdm
class ViTEncoder(nn.Module):def __init__(self, codebook_dim=512):super().__init__()# 加载预训练ViT-Base模型self.vit = ViTModel.from_pretrained("google/vit-base-patch16-224-in21k")# 调整输出维度匹配Codebookself.proj = nn.Linear(768, codebook_dim) # 网页2/6中的线性嵌入策略def forward(self, x):outputs = self.vit(x).last_hidden_state # [batch, num_patches+1, 768]patch_embeddings = outputs[:, 1:, :] # 移除CLS tokenreturn self.proj(patch_embeddings) # [batch, 196, 512]class Codebook(nn.Module):def __init__(self, num_embeddings=16384, embedding_dim=512):super().__init__()self.codebook = nn.Embedding(num_embeddings, embedding_dim)nn.init.normal_(self.codebook.weight) # 网页1的EMA更新可在此扩展def quantize(self, z):"""量化输入特征向量参数:z: 输入特征 [batch, num_patches, embedding_dim]返回:indices: 最近邻码本索引 [batch, num_patches]quantized: 量化后的特征 [batch, num_patches, embedding_dim]"""# 重塑输入为二维矩阵 [batch*num_patches, embedding_dim]batch, num_patches, dim = z.shapez_flat = z.reshape(-1, dim) # [batch*num_patches, dim]# 计算L2距离 ||z - e||^2 = ||z||^2 - 2<z,e> + ||e||^2z_norm = torch.sum(z_flat ** 2, dim=1, keepdim=True) # [batch*num_patches, 1]e_norm = torch.sum(self.codebook.weight ** 2, dim=1) # [num_embeddings]dot_product = torch.matmul(z_flat, self.codebook.weight.t()) # [batch*num_patches, num_embeddings]distances = z_norm - 2 * dot_product + e_norm.unsqueeze(0)# 找到最近邻indices = torch.argmin(distances, dim=1) # [batch*num_patches]indices = indices.reshape(batch, num_patches) # 恢复原始形状quantized = self.codebook(indices) # [batch, num_patches, dim]return indices, quantized
class ViTDecoder(nn.Module):def __init__(self, in_dim=512):super().__init__()# 反向映射ViT的patch嵌入self.proj = nn.Linear(in_dim, 768)config = ViTConfig()config.is_decoder = True # 网页7中的解码器模式self.transformer = ViTModel(config).encoder self.head = nn.Sequential(# 14x14 -> 28x28nn.ConvTranspose2d(768, 384, kernel_size=4, stride=2, padding=1),nn.ReLU(),# 28x28 -> 56x56nn.ConvTranspose2d(384, 192, kernel_size=4, stride=2, padding=1),nn.ReLU(),# 56x56 -> 112x112 nn.ConvTranspose2d(192, 96, kernel_size=4, stride=2, padding=1),nn.ReLU(),# 112x112 -> 224x224nn.ConvTranspose2d(96, 48, kernel_size=4, stride=2, padding=1),nn.ReLU(),# 最终调整到3通道nn.Conv2d(48, 3, kernel_size=1))def forward(self, x):x = self.proj(x) # [batch, 196, 768]x = self.transformer(x).last_hidden_statex = x.permute(0, 2, 1).view(-1, 768, 14, 14) # 恢复空间布局return self.head(x) # 输出[1, 3, 224, 224]
# encoder = ViTEncoder()
# codebooker = Codebook()
# decoder = ViTDecoder()# data = torch.randn(1, 3, 224, 224)
# output = encoder(data)
# print(output.shape)
# indices, quantized = codebooker.quantize(output)
# print(indices.shape, quantized.shape)
# reconstructed = decoder(quantized)
# print(reconstructed.shape)from torchvision import transforms
import torchvision
import torch.nn.functional as F
# 数据增强和预处理
transform_train = transforms.Compose([transforms.Resize(224), # 调整图像尺寸适配模型transforms.RandomCrop(224, padding=4),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])transform_test = transforms.Compose([transforms.Resize(224),transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])
# trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
# trainloader = torch.DataLoader(trainset, batch_size=64, shuffle=True)
# 加载CIFAR-10数据集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)batch_size = 4 # 增大batch size加速训练
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True, num_workers=2)
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)import torchvision.utils as vutils
from torch.utils.tensorboard import SummaryWriter
from torchvision.models import vgg16# 初始化TensorBoard
writer = SummaryWriter('runs/codebook_experiment')# 改进的Codebook类(增加EMA更新)
class Codebook(nn.Module):def __init__(self, num_embeddings=1024, embedding_dim=512, commitment_cost=0.25, decay=0.99):super().__init__()self.codebook = nn.Embedding(num_embeddings, embedding_dim)nn.init.normal_(self.codebook.weight)self.commitment_cost = commitment_costself.decay = decayself.register_buffer('ema_cluster_size', torch.zeros(num_embeddings))self.ema_w = nn.Parameter(torch.Tensor(num_embeddings, embedding_dim))nn.init.normal_(self.ema_w)def quantize(self, z):# 重塑输入为二维矩阵 [batch*num_patches, embedding_dim]batch, num_patches, dim = z.shapez_flat = z.reshape(-1, dim) # [batch*num_patches, dim]# 计算L2距离 ||z - e||^2 = ||z||^2 - 2<z,e> + ||e||^2z_norm = torch.sum(z_flat ** 2, dim=1, keepdim=True) # [batch*num_patches, 1]e_norm = torch.sum(self.codebook.weight ** 2, dim=1) # [num_embeddings]dot_product = torch.matmul(z_flat, self.codebook.weight.t()) # [batch*num_patches, num_embeddings]distances = z_norm - 2 * dot_product + e_norm.unsqueeze(0)# 找到最近邻indices = torch.argmin(distances, dim=1) # [batch*num_patches]indices = indices.reshape(batch, num_patches) # 恢复原始形状quantized = self.codebook(indices) # [batch, num_patches, dim]# 新增EMA更新# if self.training:# with torch.no_grad():# encodings = F.one_hot(indices, self.codebook.num_embeddings).float()# self.ema_cluster_size = self.decay * self.ema_cluster_size + (1 - self.decay) * torch.sum(encodings, 0)# n = torch.sum(self.ema_cluster_size)# self.ema_cluster_size = ((self.ema_cluster_size + 1e-5) / (n + self.codebook.num_embeddings * 1e-5) * n)# dw = torch.matmul(encodings.t(), z_flat)# self.ema_w = nn.Parameter(self.ema_w * self.decay + (1 - self.decay) * dw)# self.codebook.weight.data = self.ema_w / self.ema_cluster_size.unsqueeze(1)return indices, quantized
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 初始化组件
encoder = ViTEncoder().to(device)
codebook = Codebook(commitment_cost=0.25, decay=0.95).to(device)
decoder = ViTDecoder().to(device)
vgg = vgg16(pretrained=True).features[:16].eval().to(device) # 用于感知损失# 优化器分开设置
opt = torch.optim.Adam([{'params': encoder.parameters()},{'params': decoder.parameters()},{'params': codebook.parameters(), 'lr': 1e-4} # 更小的学习率
], lr=3e-4)# 训练循环
for epoch in range(100):avg_loss = 0start_time = time.time() # 记录epoch开始时间for batch_idx, (images, _) in enumerate(tqdm(trainloader, desc=f"Epoch {epoch+1}", ncols=80)):images = images.to(device)# 前向传播z = encoder(images)indices, quantized = codebook.quantize(z)recon = decoder(quantized)# 多目标损失计算mse_loss = F.mse_loss(recon, images)# 感知损失(VGG特征匹配)with torch.no_grad():real_features = vgg(images)recon_features = vgg(recon)percep_loss = F.mse_loss(recon_features, real_features)# Codebook相关损失commitment_loss = codebook.commitment_cost * F.mse_loss(z.detach(), quantized)codebook_loss = F.mse_loss(z, quantized.detach())# 总损失total_loss = mse_loss + 0.1*percep_loss + codebook_loss + commitment_loss# 反向传播opt.zero_grad()total_loss.backward()opt.step()# 记录数据avg_loss += total_loss.item()if batch_idx % 50 == 0:# 记录TensorBoard数据writer.add_scalar('Loss/total', total_loss.item(), epoch*len(trainloader)+batch_idx)writer.add_scalars('Loss/components', {'mse': mse_loss.item(),'perceptual': percep_loss.item(),'codebook': codebook_loss.item(),'commitment': commitment_loss.item()}, epoch*len(trainloader)+batch_idx)# 保存重建样本comparison = torch.cat([images[:4], recon[:4]])grid = vutils.make_grid(comparison.cpu(), nrow=4, normalize=True)writer.add_image('Reconstruction', grid, epoch*len(trainloader)+batch_idx)# 打印epoch统计信息avg_loss /= len(trainloader)print(f"Epoch {epoch+1}: Avg Loss {avg_loss:.4f}")# 保存模型检查点if (epoch+1) % 10 == 0:torch.save({'encoder': encoder.state_dict(),'codebook': codebook.state_dict(),'decoder': decoder.state_dict(),'opt': opt.state_dict()}, f'checkpoint_epoch{epoch+1}.pth')writer.close()
通过本实践,我们实现了从特征提取到离散表征学习的完整流程。Codebook技术可广泛应用于图像压缩、生成模型等领域,期待读者在此基础上探索更多可能性。
相关文章:
从零开始训练Codebook:基于ViT的图像重建实践
完整代码在文末,可以一键运行。 1. 核心原理 Codebook是一种离散表征学习方法,其核心思想是将连续特征空间映射到离散的码本空间。我们的实现方案包含三个关键组件: 1.1 ViT编码器 class ViTEncoder(nn.Module):def __init__(self, codebo…...
每日一题洛谷P8664 [蓝桥杯 2018 省 A] 付账问题c++
P8664 [蓝桥杯 2018 省 A] 付账问题 - 洛谷 (luogu.com.cn) 思路:要使方差小,那么钱不能一下付的太多,可以让钱少的全付玩,剩下还需要的钱再让钱多的付(把钱少的补上)。 将钱排序,遍历一遍&…...
蓝桥杯真题——传送阵
原题连接:蓝桥杯2024年第十五届省赛真题-传送阵 - C语言网 知识点:并查集 题目描述 小蓝在环球旅行时来到了一座古代遗迹,里面并排放置了 n 个传送阵,进入第 i 个传送阵会被传送到第 ai 个传送阵前,并且可以随时选择…...
解释回溯算法,如何应用回溯算法解决组合优化问题?
一、回溯算法核心原理 回溯算法本质是暴力穷举的优化版本,采用"试错剪枝"策略解决问题。其核心流程如下: 路径构建:记录当前选择路径选择列表:确定可用候选元素终止条件:确定递归结束时机剪枝优化…...
opencv连接vs2015
需要改的地方: 1.debug x64 2.vc目录 包含目录:D:\softword\opencv\opencv3416\opencv\build\include 3.vc目录 库目录:D:\softword\opencv\opencv3416\opencv\build\x64\vc14\lib 4.链接器——输入:D:\softword\ope…...
用matlab搭建一个简单的图像分类网络
文章目录 1、数据集准备2、网络搭建3、训练网络4、测试神经网络5、进行预测6、完整代码 1、数据集准备 首先准备一个包含十个数字文件夹的DigitsData,每个数字文件夹里包含1000张对应这个数字的图片,图片的尺寸都是 28281 像素的,如下图所示…...
移动端六大语言速记:第6部分 - 错误处理与调试
移动端六大语言速记:第6部分 - 错误处理与调试 本文将对比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift这六种移动端开发语言在错误处理与调试方面的特性,帮助开发者理解和掌握各语言的异常处理机制。 6. 错误处理与调试 6.1 异常处理 各语言异常处理的语法对比:…...
【数据库】达梦arm64安装
话不多说,快速开始~ 1.下载 进入官网: 产品下载 | 达梦在线服务平台 下载安装包。 选飞腾、鲲鹏都可以,都是arm架构的。我选择的是: 直接下载地址是https://download.dameng.com/eco/adapter/DM8/202502/dm8_20250117_HWarm920…...
QTableWidget 中insertRow(0)(头插)和 insertRow(rowCount())(尾插)的性能差异
一、目的 在 Qt 的 QTableWidget 中,insertRow(0) (头插)和 insertRow(rowCount())(尾插)在性能上存在显著差异。 二、QAbstractItemModel:: insertRows 原文解释 QAbstractItemModel Class | Qt Core 5.15.18 AI 解…...
使用MFC ActiveX开发KingScada控件(OCX)
最近有个需求,要在KingScada上面开发一个控件。 原来是用的WinCC,WinCC本身是支持调用.net控件,就是winform控件的,winform控件开发简单,相对功能也更丰富。奈何WinCC不是国产的。 话说KingScada,国产组态软…...
大模型学习二:DeepSeek R1+蒸馏模型组本地部署与调用
一、说明 DeepSeek R1蒸馏模型组是基于DeepSeek-R1模型体系,通过知识蒸馏技术优化形成的系列模型,旨在平衡性能与效率。 1、技术路径与核心能力 基础架构与训练方法 DeepSeek-R1-Zero:通过强化学习(RL)训练&…...
通过 Markdown 改进 RAG 文档处理
通过 Markdown 改进 RAG 文档处理 作者:Tableau 原文地址:https://zhuanlan.zhihu.com/p/29139791931 通过 Markdown 改进 RAG 文档处理https://mp.weixin.qq.com/s/LOBOKNA71dANXHuwxe7yxw 如何将 PDF 转换为 Markdown 以获得更好的 LLM RAG 结果 Mar…...
Java学习总结-IO流
什么IO流? 以内存为主体。input:磁盘向内存输入内容。output:内存向磁盘输入内容。 IO流的分类:...
python发送qq邮件
1.发送邮件的前提是你的qq邮箱设置能够用程序访问 这个服务点打开 就在 设置->账号 中 可以找到 # 导入 smtplib 库,用于实现 SMTP 协议,可实现邮件的发送功能 import smtplib # 从 email.mime.multipart 模块导入 MIMEMultipart 类,用…...
使用Deployment运行无状态应用
使用Deployment运行无状态应用 文章目录 使用Deployment运行无状态应用[toc]一、工作负载资源与控制器二、ReplicationController、ReplicaSet和Deployment1. ReplicationController(已淘汰)2. ReplicaSet(ReplicationController 的增强版&am…...
QT Quick(C++)跨平台应用程序项目实战教程 6 — 弹出框
目录 1. Popup组件介绍 2. 使用 上一章内容完成了音乐播放器程序的基本界面框架设计。本小节完成一个简单的功能。单击该播放器顶部菜单栏的“关于”按钮,弹出该程序的相关版本信息。我们将使用Qt Quick的Popup组件来实现。 1. Popup组件介绍 Qt 中的 Popup 组件…...
Design Compiler:库特征分析(ALIB)
相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 简介 在使用Design Compiler时,可以对目标逻辑库进行特征分析,并创建一个称为ALIB的伪库(可以被认为是缓存)&…...
2025高频面试设计模型总结篇
文章目录 设计模型概念单例模式工厂模式策略模式责任链模式 设计模型概念 设计模式是前人总结的软件设计经验和解决问题的最佳方案,它们为我们提供了一套可复用、易维护、可扩展的设计思路。 (1)定义: 设计模式是一套经过验证的…...
41. 评论日记
越复杂的结构越脆弱,你不能因为有智驾有只能,你就全交给它了,手机永久了还发热呢,你全交给它那你要死了也怪不了谁。 这年头的手机基本都有防水,但是你天天拿着这个在泳池里玩,哪天炸了我都只能说炸的响炸的…...
Python第七章09:自定义python包.py
# 自定义python包# 从物理上看,包就是一个文件夹,在该文件夹下包含了一个_init_.py文件,该文件夹可用于包含多个模块文件 # 从逻辑上看,包的本质依然是模块 # _init_.py 标识python包,没有就是普通文件夹࿰…...
基于大模型预测升主动脉瘤的多维度诊疗研究报告
目录 一、引言 1.1 研究背景 1.2 研究目的与意义 二、升主动脉瘤概述 2.1 定义与分类 2.2 发病原因与机制 2.3 流行病学现状 三、大模型技术原理及应用现状 3.1 大模型基本原理 3.2 在医疗领域的应用进展 3.3 针对升主动脉瘤预测的独特价值 四、术前大模型预测方案…...
Lua中table函数使用详解
目录 1. table.concat(list [, sep [, i [, j]]])2. table.insert(list, [pos,] value)3. table.move(src, a, b, dest [, dest_pos]) (Lua 5.3)4. table.pack(...) (Lua 5.2)5. table.remove(list [, pos])6. table.sort(list [, comp])7. table.unpack(list [, i [, j]])总结…...
如何在Windows上找到Python安装路径?两种方法快速定位
原文:如何在Windows上找到Python安装路径?两种方法快速定位 | w3cschool笔记 在 Windows 系统上找到 Python 的安装路径对于设置环境变量或排查问题非常重要。本文将介绍两种方法,帮助你找到 Python 的安装路径:一种是通过命令提…...
图形库 EasyX - EasyX 初识(EasyX 概述、EasyX 下载与安装、打开一个窗口、打开一个彩色窗口、绘制简易图形、输出文字)
一、EasyX 概述 EasyX 是一款专为 C 开发者设计的轻量级图形库,主要面向 Windows 平台,它有如下特点 EasyX 的 API 设计简洁直观,易学易用,绘图效果所见即所得 二、EasyX 下载与安装 1、EasyX 下载 官方网址:https…...
《深度探秘:SQL助力经典Apriori算法实现》
在数据的广袤世界里,隐藏着无数有价值的信息,等待着我们去挖掘和发现。关联规则挖掘算法,作为数据挖掘领域的关键技术,能够从海量数据中找出事物之间潜在的关联关系,为商业决策、学术研究等诸多领域提供有力支撑。其中…...
AVR128单片机红外遥控8*8LED点阵屏显示
1)将接收到的红外解码信号用LCD液晶显示屏显示。 2)将接收到的5种红外解码信号分别控制88的液晶点阵屏MATRIX-88-GREEN (颜色可以自定)进行不同的显示:整行从上到下、从下到上轮流显示;整列从左到右、从右到左轮流显示;…...
前端Uniapp接入UviewPlus详细教程!!!
相信大家在引入UviewPlusUI时遇到很头疼的问题,那就是明明自己是按照官网教程一步一步的走,为什么到处都是bug呢?今天我一定要把这个让人头疼的问题解决了! 1.查看插件市场 重点: 我们打开Dcloud插件市场搜素uviewPl…...
【c++深入系列】:类与对象详解(中)
🔥 本文专栏:c 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 不是因为看到希望才坚持,而是坚持了才能看到希望 那么上一篇博客我讲解了什么是类和对象以及类和对象是怎么定义的࿰…...
【Linux】远程登录时,使用图形界面报错:MoTTY X11 proxy: Unsupported authorisation protocol
1、问题描述 使用 MobaXterm 远程登录Ubuntu后,使用sudo权限运行图形界面程序报错: MoTTY X11 proxy: Unsupported authorisation protocol (gpartedbin:10518): Gtk-WARNING **: 22:01:34.377: cannot open display: localhost:10.02、查看SSH配置 修改 SSH 服务端配置,…...
作用域与上下文:JavaScript魔法森林探秘
在JavaScript的魔法森林里,作用域和上下文是两位神秘的守护者,它们掌控着代码的逻辑流向和变量的生杀大权。今天,就让我们一起踏入这片神奇的土地,揭开全局作用域、函数作用域和闭包的神秘面纱,看它们如何影响我们的代…...
虚拟电商-话费充值业务(五)充值成功逻辑和网络异常重试逻辑
一、网络异常重试逻辑编写 如果在对接供应商的过程中出现了网络异常,我们需要做一个补偿机制,在任务类型枚举类:TaskTypeEnum中有一种业务状态码是针对远程调用失败的 步骤一:在对接供应商的方法:SupplierServiceImp…...
42.评论日记
怎么看待算命? 我能算到你今晚睡觉前会上一次厕所。 你可以选择相信我算的内容,也可以不信。 你也可以有感觉要上厕所的时候不去拉兜里。 也可以选择相信,早早的拿好纸做准备。 你今晚可能不止上一次,也可能今晚没吃没喝早早…...
MTK-GMS版本国内WIFI受限问题
MTK-GMS版本国内WIFI受限问题解决 文章目录 问题参考资料解决方案方案一 修改配置坑点 方案二 直接修改属性 问题 最近负责ROOM 产品,出现WIFI受限显示,但是网络是通畅的。 GMS 版本,在国外或者国内翻墙网络不会出现WIFI受限显示问题&#…...
C# System.Text.Json 中 JsonConverter 使用详解
总目录 前言 在 C# 开发中,System.Text.Json 是一个高性能的 JSON 处理库,广泛用于序列化和反序列化对象。当默认的序列化行为无法满足需求时,JsonConverter 提供了强大的自定义能力。本文将详细讲解 JsonConverter 的使用方法,帮…...
Leetcode 857 -- 贪心 | 数学
题目描述 雇佣 K 名工人的最低成本 思路 参考官方题解和这里。 代码1(正确) class Solution { public:double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int k) {int n wage.size();double res 0, totalq …...
基于 SpringBoot 的社区维修平台
收藏关注不迷路!! 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题(免费咨询指导选题),项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多…...
maven项目添加第三方JAR包
项目开发过程中,不可避免的需要用到一些maven库(公共库、司库等)中没有的冷门jar包依赖,这时,可以将这些第三方JAR包安装到本地maven仓库中,实现项目依赖的一致性。具体步骤如下: 1、下载jar包 …...
C#:接口(interface)
目录 接口的核心是什么? 1. 什么是接口(Interface),为什么要用它? 2. 如何定义和使用接口? 3.什么是引用接口? 如何“引用接口”? “引用接口”的关键点 4. 接口与抽象类的区…...
c#和c++脚本解释器科学运算
说明: 我希望用c#和c写一个脚本解释器,用于科学运算 效果图: step1: c# C:\Users\wangrusheng\RiderProjects\WinFormsApp3\WinFormsApp3\Form1.cs using System; using System.Collections.Generic; using System.Data; using System.Tex…...
2025年嵌入式大厂春招高频面试真题及解析
以下是 2025 年嵌入式大厂春招高频面试真题及解析,结合真题分类和核心知识点整理: 一、C/C++编程基础 1.1 指针与内存 野指针的成因及避免方法(未初始化、释放后未置空) malloc与calloc的区别(后者自动初始化为0) 指针与数组的区别(内存分配方…...
【C++】nlohmann::json 配置加载技术实践:从基础到高级应用
一、nlohmann::json 库概况与核心特性 nlohmann::json 是 C 社区最受欢迎的 JSON 库之一,其设计理念简洁即美,通过单头文件实现完整的 JSON 解析、序列化和操作功能。 1.1 基本特性 nlohmann::json是一个现代C编写的开源JSON库,采用MIT协议…...
ngx_regex_init
定义在 src\core\ngx_regex.c void ngx_regex_init(void) { #if !(NGX_PCRE2)pcre_malloc ngx_regex_malloc;pcre_free ngx_regex_free; #endif } NGX_PCRE21 #if !(NGX_PCRE2) 就为假 条件不成立 ngx_regex_init 函数就成了空实现 NGX_PCRE2 被定义,则表示 Ngin…...
【前端扫盲】postman介绍及使用
Postman 是一款专为 API 开发与测试设计的 全流程协作工具,程序员可通过它高效完成接口调试、自动化测试、文档管理等工作。以下是针对程序员的核心功能介绍和应用场景说明: 一、核心功能亮点 接口请求构建与调试 支持所有 HTTP 方法(GET/POS…...
Lua中os模块函数使用详解
目录 os.clock()os.date([format [, time]])os.difftime(t2, t1)os.execute(command)os.exit([code [, close]])os.getenv(varname)os.remove(filename)os.rename(oldname, newname)os.setlocale(locale [, category])os.time([table])os.tmpname()总结 以下是 Lua 中 os 模块的…...
量子计算与经典计算的拉锯战:一场关于计算未来的辩论
在计算科学领域,一场关于未来的激烈辩论正在上演。2025年3月,D-Wave量子公司的研究人员在《Science》杂志上发表了一项突破性成果,声称他们的量子退火处理器在几分钟内解决了一个经典超级计算机需要数百万年才能完成的复杂现实问题。这一声明…...
MySQL 基础入门
写在前面 关于MySQL的下载安装和其图形化软件Navicat的下载安装,网上已经有了很多的教程,这里就不再赘述了,本文主要是介绍了关于MySQL数据库的基础知识。 MySQL数据库 MySQL数据库基础 MySQL数据库概念 MySQL 数据库: 是一个关系型数据库管理系统 。 支持SQL语…...
GPT模型搭建
GPT模型搭建 1. 章节介绍 本章节聚焦于从0搭建GPT模型,通过事先准备的基础代码,引导学习者逐步构建模型。旨在让程序员、软件架构师和工程师等掌握GPT模型搭建的核心流程,理解其关键组件与技术细节,为实际应用和面试做好准备。 …...
BUUCTF-web刷题篇(8)
17.EasyCalcS 查看源码,发现有段代码有php文件,即calc.php 经过代码审计之后应该要访问calc.php文件,打开后: <?php error_reporting(0); if(!isset($_GET[num])){show_source(__FILE__); }else{$str $_GET[num];$blackli…...
AI SEO内容优化指南:如何打造AI平台青睐的高质量内容
AI SEO内容优化指南:如何打造AI平台青睐的高质量内容 在生成式AI平台(如DeepSeek、Kimi、豆包、腾讯元宝等)主导的搜索新时代,内容优化已成为企业抢占流量入口的核心策略。本文将从内容创作、分发到效果维护全链路,解…...
无需预对齐即可消除批次效应,东京大学团队开发深度学习框架STAIG,揭示肿瘤微环境中的详细基因信息
生物组织是由多种类型细胞构成的复杂网络,这些细胞通过特定的空间配置执行重要功能。近年来,10x Visium、Slide-seq、Stereo-seq 和 STARmap 等空间转录组学 (ST) 技术的进步,使得生物学家们能够在空间结构内绘制基因数据,从而各类…...