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

代码解读:Diffusion Models中的长宽桶技术(Aspect Ratio Bucketing)

Diffusion Models专栏文章汇总:入门与实战

前言:自从SDXL提出了长宽桶技术之后,彻底解决了不同长宽比的图像输入问题,现在已经成为训练扩散模型必选的方案。这篇博客从代码详细解读如何在模型训练的时候运用长宽桶技术(Aspect Ratio Bucketing)。

目录

原理解读-原有训练的问题

长宽桶技术(Aspect Ratio Bucketing)

完整代码


原理解读-原有训练的问题

纵横比分桶训练可以极大地提高输出质量,现有图像生成模型的一个常见问题是,它们非常容易生成带有非自然作物的图像。这是因为这些模型被训练成生成方形图像。然而,大多数照片和艺术品都不是方形的。然而,该模型只能同时在相同大小的图像上工作,并且在训练过程中,通常的做法是同时在多个训练样本上操作,以优化所使用gpu的效率。作为妥协,选择正方形图像,在训练过程中,只裁剪出每个图像的中心,然后作为训练样例显示给图像生成模型。

例如,人类通常是没有脚或头的,剑只有一个刀刃,剑柄和剑尖在框架外。因为我们正在创建一个图像生成模型来配合我们的故事叙述体验,所以我们的模型能够产生适当的,未裁剪的角色是很重要的,并且生成的骑士不应该持有延伸到无限的金属状直线。

对裁剪图像进行训练的另一个问题是,它可能导致文本和图像之间的不匹配。例如,带有王冠标签的图像通常在中央裁剪后不再包含王冠,因此君主已经被斩首。我们发现使用随机作物代替中心作物只能略微改善这些问题。使用具有可变图像大小的稳定扩散是可能的,尽管可以注意到,远远超过512x512的原生分辨率往往会引入重复的图像元素,并且非常低的分辨率会产生无法识别的图像。

尽管如此,这向我们表明,在可变大小的图像上训练模型应该是可能的。在单个、可变大小的样本上进行训练是微不足道的,但也非常缓慢,而且由于使用小批量提供的缺乏正则化,更容易产生训练不稳定性。

长宽桶技术(Aspect Ratio Bucketing)

由于这个问题似乎没有现有的解决方案,我们已经为我们的数据集实现了自定义批生成代码,允许创建批处理,其中批处理中的每个项目具有相同的大小,但批处理的图像大小可能不同。

我们通过一种叫做宽高比桶的方法来做到这一点。另一种方法是使用固定的图像大小,缩放每个图像以适应这个固定的大小,并应用在训练期间被掩盖的填充。由于这会导致训练期间不必要的计算,我们没有选择遵循这种替代方法。

在下面,我们描述了我们自定义的宽高比桶的批量生成方案背后的原始想法。

首先,我们必须定义要将数据集的图像排序到哪个存储桶中。为此,我们定义的最大图像尺寸为512x768,最大尺寸为1024。由于最大图像大小为512x768,比512x512大,需要更多的VRAM,因此每个gpu的批处理大小必须降低,这可以通过梯度积累来补偿。

我们通过应用以下算法生成桶:

Set the width to 256.
While the width is less than or equal to 1024:Find the largest height such that height is less than or equal to 1024 and that width multiplied by height is less than or equal to 512 * 768.Add the resolution given by height and width as a bucket.Increase the width by 64.

同样的重复,宽度和高度互换。重复的桶将从列表中删除,并添加一个大小为512x512的桶。

接下来,我们将图像分配到相应的桶中。为此,我们首先将桶分辨率存储在NumPy数组中,并计算每个分辨率的长宽比。对于数据集中的每张图像,我们检索其分辨率并计算长宽比。图像宽高比从桶宽高比数组中减去,使我们能够根据宽高比差的绝对值有效地选择最接近的桶:

image_bucket = argmin(abs(bucket_aspects — image_aspect))

图像的桶号与其数据集中的项目ID相关联。如果图像的宽高比非常极端,甚至与最适合的桶相差太大,则从数据集中修剪图像。

由于我们在多个GPU上进行训练,在每个epoch之前,我们对数据集进行了分片,以确保每个GPU在大小相等的不同子集上工作。为此,我们首先复制数据集中的项目id列表并对它们进行洗牌。如果这个复制的列表不能被gpu数量乘以批大小整除,则会对列表进行修剪,并删除最后的项以使其可整除。

然后,我们根据当前进程的全局排名选择1/world_size*bsz项id的不同子集。自定义批处理生成的其余部分将从这些过程中的任何一个过程中进行描述,并对数据集项id的子集进行操作。

对于当前的分片,每个bucket的列表是通过迭代打乱的数据集项目ID列表并将ID分配给分配给图像的bucket对应的列表来创建的。

处理完所有图像后,我们遍历每个bucket的列表。如果它的长度不能被批大小整除,则根据需要删除列表上的最后一个元素以使其可整除,并将它们添加到单独的捕获所有桶中。由于保证整个分片大小包含许多可被批大小整除的元素,因此保证生成一个长度可被批大小整除的所有bucket。

当请求批处理时,我们从加权分布中随机抽取一个桶。桶的权重设置为桶的大小除以所有剩余桶的大小。这确保了即使有大小差异很大的桶,自定义批生成在训练期间不会引入强烈的偏差,根据图像大小显示图像。如果在没有加权的情况下选择桶,那么小的桶将在训练过程中早期清空,只有最大的桶将在训练结束时保留。按大小对桶进行加权可以避免这种情况。

最后从所选的桶中取出一批项。取走的项目从桶中移除。如果桶现在为空,则在epoch的剩余时间内删除它。所选的项id和所选桶的分辨率现在被传递给图像加载函数。

完整代码

import numpy as np
import pickle
import timedef get_prng(seed):return np.random.RandomState(seed)class BucketManager:def __init__(self, bucket_file, valid_ids=None, max_size=(768,512), divisible=64, step_size=8, min_dim=256, base_res=(512,512), bsz=1, world_size=1, global_rank=0, max_ar_error=4, seed=42, dim_limit=1024, debug=False):with open(bucket_file, "rb") as fh:self.res_map = pickle.load(fh)if valid_ids is not None:new_res_map = {}valid_ids = set(valid_ids)for k, v in self.res_map.items():if k in valid_ids:new_res_map[k] = vself.res_map = new_res_mapself.max_size = max_sizeself.f = 8self.max_tokens = (max_size[0]/self.f) * (max_size[1]/self.f)self.div = divisibleself.min_dim = min_dimself.dim_limit = dim_limitself.base_res = base_resself.bsz = bszself.world_size = world_sizeself.global_rank = global_rankself.max_ar_error = max_ar_errorself.prng = get_prng(seed)epoch_seed = self.prng.tomaxint() % (2**32-1)self.epoch_prng = get_prng(epoch_seed) # separate prng for sharding use for increased thread resilienceself.epoch = Noneself.left_over = Noneself.batch_total = Noneself.batch_delivered = Noneself.debug = debugself.gen_buckets()self.assign_buckets()self.start_epoch()def gen_buckets(self):if self.debug:timer = time.perf_counter()resolutions = []aspects = []w = self.min_dimwhile (w/self.f) * (self.min_dim/self.f) <= self.max_tokens and w <= self.dim_limit:h = self.min_dimgot_base = Falsewhile (w/self.f) * ((h+self.div)/self.f) <= self.max_tokens and (h+self.div) <= self.dim_limit:if w == self.base_res[0] and h == self.base_res[1]:got_base = Trueh += self.divif (w != self.base_res[0] or h != self.base_res[1]) and got_base:resolutions.append(self.base_res)aspects.append(1)resolutions.append((w, h))aspects.append(float(w)/float(h))w += self.divh = self.min_dimwhile (h/self.f) * (self.min_dim/self.f) <= self.max_tokens and h <= self.dim_limit:w = self.min_dimgot_base = Falsewhile (h/self.f) * ((w+self.div)/self.f) <= self.max_tokens and (w+self.div) <= self.dim_limit:if w == self.base_res[0] and h == self.base_res[1]:got_base = Truew += self.divresolutions.append((w, h))aspects.append(float(w)/float(h))h += self.divres_map = {}for i, res in enumerate(resolutions):res_map[res] = aspects[i]self.resolutions = sorted(res_map.keys(), key=lambda x: x[0] * 4096 - x[1])self.aspects = np.array(list(map(lambda x: res_map[x], self.resolutions)))self.resolutions = np.array(self.resolutions)if self.debug:timer = time.perf_counter() - timerprint(f"resolutions:\n{self.resolutions}")print(f"aspects:\n{self.aspects}")print(f"gen_buckets: {timer:.5f}s")def assign_buckets(self):if self.debug:timer = time.perf_counter()self.buckets = {}self.aspect_errors = []skipped = 0skip_list = []for post_id in self.res_map.keys():w, h = self.res_map[post_id]aspect = float(w)/float(h)bucket_id = np.abs(self.aspects - aspect).argmin()if bucket_id not in self.buckets:self.buckets[bucket_id] = []error = abs(self.aspects[bucket_id] - aspect)if error < self.max_ar_error:self.buckets[bucket_id].append(post_id)if self.debug:self.aspect_errors.append(error)else:skipped += 1skip_list.append(post_id)for post_id in skip_list:del self.res_map[post_id]if self.debug:timer = time.perf_counter() - timerself.aspect_errors = np.array(self.aspect_errors)print(f"skipped images: {skipped}")print(f"aspect error: mean {self.aspect_errors.mean()}, median {np.median(self.aspect_errors)}, max {self.aspect_errors.max()}")for bucket_id in reversed(sorted(self.buckets.keys(), key=lambda b: len(self.buckets[b]))):print(f"bucket {bucket_id}: {self.resolutions[bucket_id]}, aspect {self.aspects[bucket_id]:.5f}, entries {len(self.buckets[bucket_id])}")print(f"assign_buckets: {timer:.5f}s")def start_epoch(self, world_size=None, global_rank=None):if self.debug:timer = time.perf_counter()if world_size is not None:self.world_size = world_sizeif global_rank is not None:self.global_rank = global_rank# select ids for this epoch/rankindex = np.array(sorted(list(self.res_map.keys())))index_len = index.shape[0]index = self.epoch_prng.permutation(index)index = index[:index_len - (index_len % (self.bsz * self.world_size))]#print("perm", self.global_rank, index[0:16])index = index[self.global_rank::self.world_size]self.batch_total = index.shape[0] // self.bszassert(index.shape[0] % self.bsz == 0)index = set(index)self.epoch = {}self.left_over = []self.batch_delivered = 0for bucket_id in sorted(self.buckets.keys()):if len(self.buckets[bucket_id]) > 0:self.epoch[bucket_id] = np.array([post_id for post_id in self.buckets[bucket_id] if post_id in index], dtype=np.int64)self.prng.shuffle(self.epoch[bucket_id])self.epoch[bucket_id] = list(self.epoch[bucket_id])overhang = len(self.epoch[bucket_id]) % self.bszif overhang != 0:self.left_over.extend(self.epoch[bucket_id][:overhang])self.epoch[bucket_id] = self.epoch[bucket_id][overhang:]if len(self.epoch[bucket_id]) == 0:del self.epoch[bucket_id]if self.debug:timer = time.perf_counter() - timercount = 0for bucket_id in self.epoch.keys():count += len(self.epoch[bucket_id])print(f"correct item count: {count == len(index)} ({count} of {len(index)})")print(f"start_epoch: {timer:.5f}s")def get_batch(self):if self.debug:timer = time.perf_counter()# check if no data left or no epoch initializedif self.epoch is None or self.left_over is None or (len(self.left_over) == 0 and not bool(self.epoch)) or self.batch_total == self.batch_delivered:self.start_epoch()found_batch = Falsebatch_data = Noneresolution = self.base_reswhile not found_batch:bucket_ids = list(self.epoch.keys())if len(self.left_over) >= self.bsz:bucket_probs = [len(self.left_over)] + [len(self.epoch[bucket_id]) for bucket_id in bucket_ids]bucket_ids = [-1] + bucket_idselse:bucket_probs = [len(self.epoch[bucket_id]) for bucket_id in bucket_ids]bucket_probs = np.array(bucket_probs, dtype=np.float32)bucket_lens = bucket_probsbucket_probs = bucket_probs / bucket_probs.sum()bucket_ids = np.array(bucket_ids, dtype=np.int64)if bool(self.epoch):chosen_id = int(self.prng.choice(bucket_ids, 1, p=bucket_probs)[0])else:chosen_id = -1if chosen_id == -1:# using leftover images that couldn't make it into a bucketed batch and returning them for use with basic square imageself.prng.shuffle(self.left_over)batch_data = self.left_over[:self.bsz]self.left_over = self.left_over[self.bsz:]found_batch = Trueelse:if len(self.epoch[chosen_id]) >= self.bsz:# return bucket batch and resolutionbatch_data = self.epoch[chosen_id][:self.bsz]self.epoch[chosen_id] = self.epoch[chosen_id][self.bsz:]resolution = tuple(self.resolutions[chosen_id])found_batch = Trueif len(self.epoch[chosen_id]) == 0:del self.epoch[chosen_id]else:# can't make a batch from this, not enough images. move them to leftovers and try againself.left_over.extend(self.epoch[chosen_id])del self.epoch[chosen_id]assert(found_batch or len(self.left_over) >= self.bsz or bool(self.epoch))if self.debug:timer = time.perf_counter() - timerprint(f"bucket probs: " + ", ".join(map(lambda x: f"{x:.2f}", list(bucket_probs*100))))print(f"chosen id: {chosen_id}")print(f"batch data: {batch_data}")print(f"resolution: {resolution}")print(f"get_batch: {timer:.5f}s")self.batch_delivered += 1return (batch_data, resolution)def generator(self):if self.batch_delivered >= self.batch_total:self.start_epoch()while self.batch_delivered < self.batch_total:yield self.get_batch()if __name__ == "__main__":# prepare a pickle with mapping of dataset IDs to resolutions called resolutions.pkl to use thiswith open("resolutions.pkl", "rb") as fh:ids = list(pickle.load(fh).keys())counts = np.zeros((len(ids),)).astype(np.int64)id_map = {}for i, post_id in enumerate(ids):id_map[post_id] = ibm = BucketManager("resolutions.pkl", debug=True, bsz=8, world_size=8, global_rank=3)print("got: " + str(bm.get_batch()))print("got: " + str(bm.get_batch()))print("got: " + str(bm.get_batch()))print("got: " + str(bm.get_batch()))print("got: " + str(bm.get_batch()))print("got: " + str(bm.get_batch()))print("got: " + str(bm.get_batch()))bm = BucketManager("resolutions.pkl", bsz=8, world_size=1, global_rank=0, valid_ids=ids[0:16])for _ in range(16):bm.get_batch()print("got from future epoch: " + str(bm.get_batch()))bms = []for rank in range(16):bm = BucketManager("resolutions.pkl", bsz=8, world_size=16, global_rank=rank)bms.append(bm)for epoch in range(5):print(f"epoch {epoch}")for i, bm in enumerate(bms):print(f"bm {i}")first = Truefor ids, res in bm.generator():if first and i == 0:#print(ids)first = Falsefor post_id in ids:counts[id_map[post_id]] += 1print(np.bincount(counts))

 

相关文章:

代码解读:Diffusion Models中的长宽桶技术(Aspect Ratio Bucketing)

Diffusion Models专栏文章汇总&#xff1a;入门与实战 前言&#xff1a;自从SDXL提出了长宽桶技术之后&#xff0c;彻底解决了不同长宽比的图像输入问题&#xff0c;现在已经成为训练扩散模型必选的方案。这篇博客从代码详细解读如何在模型训练的时候运用长宽桶技术(Aspect Rat…...

Linux下如何使用GitLab进行团队协作

在Linux系统中&#xff0c;使用GitLab进行团队协作是非常常见的做法。GitLab是一个基于Git的代码托管和项目管理平台&#xff0c;可以帮助团队成员共享、追踪和管理代码的开发过程。本文将介绍如何在Linux系统中安装和配置GitLab&#xff0c;以及一些常用的团队协作功能。 安装…...

无法连接到internet怎么办?已连接但无internet访问,其实并不难

有时我们会遇到无法连接到Internet的问题&#xff0c;由多种原因引起&#xff0c;包括硬件故障、软件设置问题、网络供应商故障等。本文将介绍无法连接到Internet时可以采取的步骤。 简述 当你无法连接到Internet时&#xff0c;可以按照以下步骤进行检查和解决&#xff1a; 1…...

建投数据人力资源系列产品获得欧拉操作系统及华为鲲鹏技术认证书

近日&#xff0c;经欧拉生态创新中心和华为技术有限公司测评&#xff0c;建投数据自主研发的人力资源管理系统、招聘管理系统、绩效管理系统、培训管理系统&#xff0c;完成了基于欧拉操作系统openEuler 22.03、华为鲲鹏Kunpeng 920&#xff08;Taisha 200&#xff09;的兼容性…...

【iOS】——属性关键字的底层原理

strong&#xff0c;retain&#xff0c;copy&#xff0c;atomic&#xff0c;nonatomic c源码 interface propertyTest : NSObject property (nonatomic, strong) NSString *nsstring___StrongTest; property (nonatomic, retain) NSString *nsstring___RetainTest; property (n…...

电影类平台如何选择服务器

电影类平台如何选择服务器 1、数据存储 电影网站对服务器的要求是比较高的&#xff0c;对存储空间的需求特别大&#xff0c;所以在服务器选择上首先要确保足够大的存储空间。另外&#xff0c;当你的网站内容特别多时&#xff0c;内存不够用&#xff0c;可以选择增加内存&#x…...

递归神经网络(RNN)及其预测和分类的Python和MATLAB实现

递归神经网络&#xff08;Recurrent Neural Networks&#xff0c;RNN&#xff09;是一种广泛应用于序列数据建模的深度学习模型。相比于传统的前馈神经网络&#xff0c;RNN具有记忆和上下文依赖性的能力&#xff0c;适用于处理具有时序关联性的数据&#xff0c;如文本、语音、时…...

以flask为后端的博客项目——星云小窝

以flask为后端的博客项目——星云小窝 文章目录 以flask为后端的博客项目——星云小窝前言一、星云小窝项目——项目介绍&#xff08;一&#xff09;二、星云小窝项目——项目启动&#xff08;二&#xff09;三、星云小窝项目——项目结构&#xff08;三&#xff09;四、谈论一…...

CUDA编程02 - 数据并行介绍

一:概述 数据并行是指在数据集的不同部分上执行计算工作,这些计算工作彼此相互独立且可以并行执行。许多应用程序都具有丰富的数据并行性,使其能够改造成可并行执行的程序。因此,对于程序员来说,熟悉数据并行的概念以及使用并行编程语言来编写数据并行的代码是非常重要的。…...

Android 视频音量图标

attrs.xml <?xml version"1.0" encoding"utf-8"?> <resources><!--图标颜色--><attr name"ijkSolid" format"color|reference" /><!--喇叭底座宽度--><attr name"ijkCornerWidth" form…...

VScode 修改 Markdown Preview Enhanced 字体以及大纲编号

修改字体和背景颜色 按快捷键 Ctrl , 打开设置&#xff0c;搜索 markdown-preview-enhanced.previewTheme&#xff0c;选择一个黑色主题的css&#xff0c;如 github-dark.css. 修改自动编号和背景颜色 背景颜色 按 F1 或者 Ctrl Shift P&#xff0c;输入 Customize CSS…...

TCP的FIN报文可否携带数据

问题发现&#xff1a; 发现FTP-DATA数据传输完&#xff0c;TCP的挥手似乎只有两次 实际发现FTP-DATA报文中&#xff0c;TCP层flags中携带了FIN标志 piggyback FIN 问题转化为 TCP packet中如果有FIN flag&#xff0c;该报文还能携带data数据么&#xff1f; 答案是肯定的 RFC7…...

【GoF23种设计模式+简单工厂模式】

一、设计模式概述与类型 1.1、设计模式的一般定义&#xff1a; 设计模式&#xff08;Design Pattern&#xff09;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结&#xff0c;使用设计模式是为了可重用代码&#xff0c;让代码更容易被他人理解并且保证代…...

北醒单点激光雷达更改id和波特率以及Ubuntu20.04下CAN驱动

序言&#xff1a; 需要的硬件以及软件 1、USB-CAN分析仪使用顶配pro版本&#xff0c;带有支持ubuntu下的驱动包的&#xff0c;可以读取数据。 2、电源自备24V电源 3、单点激光雷达接线使用can线可以组网。 一、更改北醒单点激光雷达的id号和波特率 安装并运行USB-CAN分析仪自带…...

【线性代数】矩阵变换

一些特殊的矩阵 一&#xff0c;对角矩阵 1&#xff0c;什么是对角矩阵 表示将矩阵进行伸缩&#xff08;反射&#xff09;变换&#xff0c;仅沿坐标轴方向伸缩&#xff08;反射&#xff09;变换。 2&#xff0c;对角矩阵可分解为多个F1矩阵&#xff0c;如下&#xff1a; 二&a…...

聚焦智慧出行,TDengine 与路特斯科技再度携手

在全球汽车行业向电动化和智能化转型的过程中&#xff0c;智能驾驶技术正迅速成为行业的焦点。随着消费者对出行效率、安全性和便利性的需求不断提升&#xff0c;汽车制造商们需要在全球范围内实现低延迟、高质量的数据传输和处理&#xff0c;以提升用户体验。在此背景下&#…...

虚拟机迁移报错:虚拟机版本与主机“x.x.x.x”的版本不兼容

1.虚拟机在VCenter上从一个ESXi迁移到另一个ESXi上时报错&#xff1a;虚拟机版本与主机“x.x.x.x”的版本不兼容。 2.例如从10.0.128.13的ESXi上迁移到10.0.128.11的ESXi上。点击10.0.128.10上的任意一台虚拟机&#xff0c;查看虚拟机版本。 3.确认要迁移的虚拟机磁盘所在位…...

【教程】vscode添加powershell7终端

win10自带的 powershell 是1.0版本的&#xff0c;太老了&#xff0c;更换为powershell7后&#xff0c;在 vscode 的集成终端中没有显示本篇教程记录在vscode添加powershell7终端的过程 打开vscode终端配置 然后来到这个页面进行设置 查看 powershell7 的安装位置&#xff…...

如何乘上第四次工业革命的大船

如何乘上第四次工业革命的大船 第四次工业革命通常被认为是信息技术和数字化时代的到来,但具体影响哪些产业,以及它将如何演变和展开,仍然是一个广泛讨论的话题。 然而,已经可以看到一些领域可能受到第四次工业革命的深远影响,例如人工智能、物联网、大数据、生物技术、可…...

RKNN执行bash ./build-linux_RK3566_RK3568.sh 报错

目录 报错信息: 原因分析: 解决办法: 报错信息: CMake Error at /usr/share/cmake-3.22/Modules/CMakeDetermineCCompiler.cmake:49 (message): Could not find compiler set in environment variable CC: aarch64-linux-gnu-gcc. Call Stack (most recent call fir…...

Linux常用命令整理

本文将分享一些常用的Linux命令。根据功能的不同&#xff0c;大概分为以下几个方面&#xff0c;一是文件相关命令&#xff0c;二是进程相关命令&#xff0c;三是网络相关命令&#xff0c;四是磁盘相关命令&#xff0c;五是用户管理相关命令&#xff0c;六是系统命令。 1. 文件…...

python 闭包、装饰器

一、闭包&#xff1a; 1. 外部函数嵌套内部函数 2. 外部函数返回内部函数 3.内部函数可以访问外部函数局部变量 闭包&#xff08;Closure&#xff09;是指在一个函数内部定义的函数&#xff0c;并且内部函数可以访问外部函数的局部变量&#xff0c;即使外部函数已经执行…...

[pycharm]解决pycharm运行程序出现卡住scanning files to index索引的问题

有时候会出现索引问题&#xff0c;显示scanning files to index 解决方法&#xff1a; in pycharm, go to the "File" on the left top, then select "invalidate caches/restart...", and press "invalidate and restart". 然后等它自己重启…...

python每日学习11:numpy库的用法(下)

python每日学习11&#xff1a;numpy库的用法(下) 数组的拼接 名方法称说明concatenate连接沿现有轴的数组序列hstack水平堆叠序列中的数组&#xff08;列方向&#xff09;vstack竖直堆叠序列中的数组&#xff08;行方向&#xff09;concatenate函数用于沿指定轴连接相同形状的两…...

【Emacs有什么优点,用Emacs写程序真的比IDE更方便吗?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…...

6、基于Fabirc 2.X 通用电子存证系统部署

evidence 将GOPATH设置为/root/go,拉取项目&#xff1a; cd $GOPATH/src && git clone https://gitee.com/henan-minghua_0/evidence.git 在/etc/hosts中添加&#xff1a; 127.0.0.1 orderer.example.com 127.0.0.1 peer0.org1.example.com 127.0.0.1 peer1.org…...

Linux Vim 由浅入深的教程

引言 原文链接 Vim是Linux系统中非常强大的文本编辑器&#xff0c;因其强大的功能和灵活的操作而受到广泛使用。尤其是在服务器管理和开发环境中&#xff0c;Vim几乎是必备工具。本教程将以CentOS 7为例&#xff0c;详细讲解Vim的安装、基本操作以及一些高级技巧&#xff0c;…...

MIT6.824(6.5840) Lab1笔记+源码

文章目录 其他人的内容&#xff0c;笔记写的更好&#xff0c;思路可以去看他们的MapReduceworkermapreduce coordinatorrpc纠错 源码worker.gocoordinator.gorpc.go 原本有可借鉴的部分 mrsequential.go&#xff0c;多看几遍源码 其他人的内容&#xff0c;笔记写的更好&#xf…...

【目录】8051汇编与C语言系列教程

8051汇编与C语言系列教程 作者将狼才鲸创建日期2024-07-23 CSDN文章地址&#xff1a;【目录】8051汇编与C语言系列教程本Gitee仓库原始地址&#xff1a;才鲸嵌入式/8051_c51_单片机从汇编到C_从Boot到应用实践教程 一、本教程目录 序号教程名称简述教程链接1点亮LCD灯通过IO…...

群管机器人官网源码

一款非常好看的群管机器人html官网源码 搭建教程&#xff1a; 域名解析绑定 源码文件上传解压 访问域名即可 演示图片&#xff1a; 群管机器人官网源码下载&#xff1a;客户端下载 - 红客网络编程与渗透技术 原文链接&#xff1a; 群管机器人官网源码...

整合EasyExcel实现灵活的导入导出java

引入pom依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId></dependency>实现功能 结合Vue前端&#xff0c;实现浏览器页面直接导出日志文件实现文件的灵活导入文件导出 3. 实体类 实体类里有自定义转…...

springSecurity学习之springSecurity web如何取得用户信息

web如何取得用户信息 之前说过SecurityContextHolder默认使用的是ThreadLocal来进行存储的&#xff0c;而且每次都会清除&#xff0c;但是web每次请求都会验证用户权限&#xff0c;这是如何做到的呢&#xff1f; 这是通过SecurityContextPersistenceFilter来实现的&#xff0…...

eclipse中的classbean导入外部class文件,clean项目后删除问题

最近被eclipse搞得头疼&#xff0c;下午终于解决 eclipse创建的java项目中&#xff0c;类的输出目录是classbean。由于项目需要&#xff0c;classbean目录下已经导入了外部的类&#xff0c;但每次clean项目时&#xff0c;会把class删掉。 广泛查询&#xff0c;eclipse不清空c…...

OBD诊断(ISO15031) 0A服务

文章目录 功能简介ISO 15765-4的诊断服务定义1、请求具有永久状态的排放相关故障诊断码2、请求具有永久状态的排放相关故障诊断码3、示例报文 功能简介 0A服务&#xff0c;即 Request emission-related diagnostic trouble code with permanent status&#xff08;请求排放相关…...

ForCloud全栈安全体验,一站式云安全托管试用 开启全能高效攻防

对于正处于业务快速发展阶段的企业&#xff0c;特别是大型央国企而言&#xff0c;日常的安全部署和运营管理往往横跨多家子公司&#xff0c;所面临的挑战不言而喻。尤其是在面对当前常态化的大型攻防演练任务时&#xff0c;难度更是呈“几何级数”上升&#xff1a; 合规难 众…...

Java——————接口(interface) <详解>

1.1 接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本电脑上的USB接口&#xff0c;电源插座等。 电脑的USB口上&#xff0c;可以插&#xff1a;U盘、鼠标、键盘...所有符合USB协议的设备 电源插座插孔上&#xff0c;可以插&#xff…...

【C++】【继承】【子对象】【构造函数】含子对象的派生类的构造函数写法

&#xff08;1&#xff09;子对象的概念&#xff1a;若派生类A1的数据成员中包含基类A的对象a&#xff0c;则a为派生类A1的子对象 &#xff08;2&#xff09;含子对象的派生类的构造函数的执行顺序是&#xff1a; ①调用基类构造函数&#xff0c;对基类数据成员初始化 ②调用子…...

golang语言 .go文件版本条件编译,xxx.go文件指定go的编译版本必须大于等于xxx才生效的方法, 同一个项目多个go版本文件共存方法

在go语言中&#xff0c;我们不关是可以在编译时指定版本&#xff0c; 在我们的xxx.go文件中也可以指定go的运行版本&#xff0c;即 忽略go.mod中的版本&#xff0c;而是当当前的go运行版本达到指定条件后才生效的xxx.go文件。 方法如下&#xff1a; 我们通过在xxx.go文件的头部…...

深入浅出mediasoup—通信框架

libuv 是一个跨平台的异步事件驱动库&#xff0c;用于构建高性能和可扩展的网络应用程序。mediasoup 基于 libuv 构建了包括管道、信号和 socket 在内的一整套通信框架&#xff0c;具有单线程、事件驱动和异步的典型特征&#xff0c;是构建高性能 WebRTC 流媒体服务器的重要基础…...

每日一题 LeetCode03 无重复字符的最长字串

1.题目描述 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的最长字串的长度。 2 思路 可以用两个指针, 滑动窗口的思想来做这道题,即定义两个指针.一个left和一个right 并且用一个set容器,一个length , 一个maxlength来记录, 让right往右走,并且用一个set容器来…...

栈和队列(C语言)

栈的定义 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#xff1a;…...

swagger-ui.html报错404

问题1&#xff1a;权限受限无法访问 由于采用的Shiro安全框架&#xff0c;需要在配置类ShiroConfig下的Shiro 的过滤器链放行该页面&#xff1a;【添加&#xff1a;filterChainDefinitionMap.put("/swagger-ui.html", "anon");】 public ShiroFilterFact…...

Milvus 核心组件(3)--- MinIO详解

目录 背景 MinIO 安装 docker desktop 安装 Ubuntu UI 在 docker 中的安装 Minio 下载及安装 启动minio docker image 保存 启动 minio web 网页 下一次启动 MinIO基本概念 基本概述 主要特性 应用场景 MinIO 使用 连接server 创建bucket 查询bucket 上传文件…...

[数据集][目标检测]婴儿车检测数据集VOC+YOLO格式1073张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1073 标注数量(xml文件个数)&#xff1a;1073 标注数量(txt文件个数)&#xff1a;1073 标注…...

JAVASE进阶day14(网络编程续TCP,日志)

TCP 三次握手 四次挥手 package com.lu.day14.tcp;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket;public class Client {public static void main(String[] args) {try(Socket socket new Socket("192.…...

机器学习(五) -- 无监督学习(1) --聚类1

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;7&#xff09; --SVM2 下篇&#xff1a;机器学习&#xff08;五&#xff09; -- 无监督学习&#xff08;1&#xff09; --聚类2 前言 tips&#xff1a;标题前有“***”的内容…...

leetcode 116. 填充每个节点的下一个右侧节点指针

leetcode 116. 填充每个节点的下一个右侧节点指针 题目 给定一个 完美二叉树 &#xff0c;其所有叶子节点都在同一层&#xff0c;每个父节点都有两个子节点。二叉树定义如下&#xff1a; struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next …...

[C++]优先级队列

1 .了解优先级队列 优先级队列是一种容器适配器&#xff0c;根据一些严格的弱排序标准&#xff0c;专门设计使其第一个元素始终是它所包含的元素中最大的元素。 此上下文类似于堆&#xff0c;其中可以随时插入元素&#xff0c;并且只能检索最大堆元素&#xff08;优先级队列中顶…...

学习大数据DAY22 Linux 基 本 指 令 3与 在 Linux 系 统 中 配 置MySQL 和 Oracle

目录 网络配置类 ps 显示系统执行的进程 kill systemctl 服务管理 配置静态 ip 常见错误---虚拟机重启网卡失败或者网卡丢失 mysql 操作 上机练习 6---安装 mysql---参考《mysql 安装》文档 解锁 scott 重启后的步骤 上机练习 7---安装 oracle---参考《oracle 安装》…...

scp 服务器复制命令

步骤如下&#xff1a; 终端执行如下命令 #ssh-keygen -t rsa 2. 密钥生成后会在 /root/.ssh/ 文件夹下产生两个文件 id_rsa id_rsa.pub 将 id_rsa.pub 文件复制到 152.136.121.24 执行如下命令 scp /root/.ssh/id_rsa.pub root152.136.121.24:/root/.ssh/authorized_keys…...