知识蒸馏—原理+代码实战(Distillation CNN 和 Progressive Distillation Diffusion)

文章目录

    • 1. Distillation 基本概念
    • 2. Distillation MNIST CNN分类代码实战
    • 3. Progressive Distillation Diffusion生成代码实战
        • 3.1 Progressive Distillation原理
        • 3.2 v-parameterization
        • 3.2 渐进蒸馏 cifar 代码实战

1. Distillation 基本概念

知识蒸馏被广泛的用于模型压缩迁移学习。开山之作应该是”Distilling the Knowledge in a Neural Network“。这篇文章中,作者的motivation是找到一种方法,把多个模型的知识提炼给单个模型。通常用一个已经训练好的Teacher Model A 去教另一个 Student Model B。通常 Model A 比 Model B更强,在Model A 的引导下,Model B可以比自学 学的更好。

做法:先训练一个teacher网络,然后使用这个teacher网络的输出数据的真实标签训练student网络。知识蒸馏,可以用来将网络从大网络转化成一个小网络,并保留接近于大网络的性能;也可以将多个网络的学到的知识转移到一个网络中,使得单个网络的性能接近emsemble的结果。

如对于如下的图像分类任务:

在这里插入图片描述

  • 传统训练:当没有 Teacher 网络时候,仅仅将 data 经过 Student 网络,在softmax之后,输出概率分布值 q,将 qlabel p 求 cross_entropy loss 就是称为 Hard loss,因为这个p是真实值的one-hot向量,我们希望q和p越接近越好。

  • 知识蒸馏:当有 Teacher 的帮助下的时候,loss来自 Student 和 Teacher 网络。且Teacher 输出的 q' 要经过带温度的Softmax之后(让它更加平滑,思想类似于label smooth)得到 q'' 再与 q 求loss,总loss = Teacher q'' 和 Student q 的 loss + Student q 和 label p 的 loss
    L = α ⋅ H a r d _ L o s s + ( 1 − α ) ⋅ S o f t _ L o s s = α ⋅ C E ( p , q ) + ( 1 − α ) ⋅ C E ( q ′ ′ , q ) L=\alpha\cdot Hard\_Loss+(1-\alpha)\cdot Soft\_Loss=\alpha\cdot CE(p,q) + (1-\alpha)\cdot CE(q'',q) L=αHard_Loss+(1α)Soft_Loss=αCE(p,q)+(1α)CE(q′′,q)在这里插入图片描述

  • SoftMax问题
    普通的Cross Entropy Loss是由NLL LossLogSoftmax组成的:

F.cross_entropy(p,target)) = F.nll_loss(torch.log(torch.softmax(p)), target)

这个 cross_entropy loss 中的 softmax 其实没有那么 soft,输出的概率分布,使得对于正确类别会有一个很高的置信度,而对于其他的类别的概率几乎为0。这样的话,teacher网络学到数据的相似信息(例如数字2和3,7很类似,这种soft label信息)很难传达给student网络。 因此,文章提出了带温度系数T的Softmax:Softmax-T
在这里插入图片描述
这里 q i q_i qi 是student网络学习的对象(soft targets), z i z_i zi 是神经网络softmax前的输出logit。如果将T取1,这个公式就是softmax,根据logit输出各个类别的概率。如果T接近于0,则最大的值会越近1,其它值会接近0,近似于onehot编码。如果T越大,则输出的结果的分布越平缓,相当于平滑的一个作用,起到保留相似信息的作用。如果T等于无穷,就是一个均匀分布。

对比Softmax(上) 和 Softmax-T(下) 对模型预测结果概率分布的可视化:
在这里插入图片描述

最终的蒸馏损失,就是将原本的CE Loss中Soft LossSoftmax换成Softmax_T,得到 KD Loss:
K D _ L o s s = α ⋅ H a r d _ L o s s + ( 1 − α ) ⋅ S o f t _ L o s s = α ⋅ C E ( p , q ) + ( 1 − α ) ⋅ C E ( q ′ ′ , q ) KD\_Loss=\alpha\cdot Hard\_Loss+(1-\alpha)\cdot Soft\_Loss=\alpha\cdot CE(p,q) + (1-\alpha)\cdot CE(q'',q) KD_Loss=αHard_Loss+(1α)Soft_Loss=αCE(p,q)+(1α)CE(q′′,q)
p是真实标签label,q是Student输出,q’'是Teacher输出。

def distillation_loss(y,labels,teacher_scores,temp,alpha):soft_loss = nn.KLDivLoss()(F.log_softmax(y/temp, dim=1), F.softmax(teacher_scores/temp,dim=1))hard_loss = F.cross_entropy(y,labels)return soft_loss *(temp*temp*2.0*alpha) + hard_loss *(1. - alpha)

2. Distillation MNIST CNN分类代码实战

  1. Import libs:
import torch
from torch import nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from tqdm import tqdm
import torchvision
from torchvision import transforms
  1. Define Teacher CNN Model(big) and Student CNN Model(small):
class TeacherModel(nn.Module):def __init__(self, in_channels=1, num_classes=10):super(TeacherModel, self).__init__()self.relu = nn.ReLU()self.fc1 = nn.Linear(784, 1200)self.fc2 = nn.Linear(1200, 1200)self.fc3 = nn.Linear(1200, num_classes)self.dropout = nn.Dropout(p=0.5)def forward(self, x):x = x.view(-1, 784)x = self.relu(self.dropout(self.fc1(x)))x = self.relu(self.dropout(self.fc2(x)))x = self.fc3(x)return xclass StudentModel(nn.Module):def __init__(self, in_channels=1, num_classes=10):super(StudentModel, self).__init__()self.relu = nn.ReLU()self.fc1 = nn.Linear(784, 20)self.fc2 = nn.Linear(20, 20)self.fc3 = nn.Linear(20, num_classes)self.dropout = nn.Dropout(p=0.5)def forward(self, x):x = x.view(-1, 784)x = self.relu(self.dropout(self.fc1(x)))x = self.relu(self.dropout(self.fc2(x)))x = self.fc3(x)return x
  1. Function of Train Teacher Model:
def teacher(device, train_loader, test_loader):print('--------------teachermodel start--------------')model = TeacherModel()model = model.to(device)criterion = nn.CrossEntropyLoss()optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)epochs = 6for epoch in range(epochs):model.train()for data, target in tqdm(train_loader):data = data.to(device)target = target.to(device)preds = model(data)loss = criterion(preds, target)optimizer.zero_grad()loss.backward()optimizer.step()model.eval()num_correct = 0num_samples = 0with torch.no_grad():for x, y in test_loader:x = x.to(device)y = y.to(device)preds = model(x)predictions = preds.max(1).indicesnum_correct += (predictions.eq(y)).sum().item()num_samples += predictions.size(0)acc = num_correct / num_samplesmodel.train()print('Epoch:{}\t Acc:{:.4f}'.format(epoch + 1, acc))torch.save(model, 'teacher.pkl')print('--------------teachermodel end--------------')
  1. Function of Train Stuent Model independently
def student(device, train_loader, test_loader):print('--------------studentmodel start--------------')model = StudentModel()model = model.to(device)criterion = nn.CrossEntropyLoss()optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)epochs = 3for epoch in range(epochs):model.train()for data, target in tqdm(train_loader):data = data.to(device)target = target.to(device)preds = model(data)loss = criterion(preds, target)optimizer.zero_grad()loss.backward()optimizer.step()model.eval()num_correct = 0num_samples = 0with torch.no_grad():for x, y in test_loader:x = x.to(device)y = y.to(device)# print(y)preds = model(x)#             print(preds)predictions = preds.max(1).indices# print(predictions)num_correct += (predictions.eq(y)).sum().item()num_samples += predictions.size(0)acc = num_correct / num_samplesmodel.train()print('Epoch:{}\t Acc:{:.4f}'.format(epoch + 1, acc))print('--------------studentmodel prediction end--------------')
  1. Function of Distilling Teacher Model to Student Model:(核心)
def kd(teachermodel, device, train_loader, test_loader):print('--------------kdmodel start--------------')teachermodel.eval()studentmodel = StudentModel()studentmodel = studentmodel.to(device)studentmodel.train()temp = 7    #蒸馏温度alpha = 0.3hard_loss = nn.CrossEntropyLoss()soft_loss = nn.KLDivLoss(reduction='batchmean')optimizer = torch.optim.Adam(studentmodel.parameters(), lr=1e-4)epochs = 20for epoch in range(epochs):for data, target in tqdm(train_loader):data = data.to(device)target = target.to(device)with torch.no_grad():teacher_preds = teachermodel(data)student_preds = studentmodel(data)student_loss = hard_loss(student_preds, target) #hard_lossdistillation_loss = soft_loss(F.log_softmax(student_preds / temp, dim=1),F.softmax(teacher_preds / temp, dim=1))   #soft_lossloss = alpha * student_loss + (1 - alpha) * distillation_lossoptimizer.zero_grad()loss.backward()optimizer.step()studentmodel.eval()num_correct = 0num_samples = 0with torch.no_grad():for x, y in test_loader:x = x.to(device)y = y.to(device)preds = studentmodel(x)predictions = preds.max(1).indicesnum_correct += (predictions.eq(y)).sum().item()num_samples += predictions.size(0)acc = num_correct / num_samplesstudentmodel.train()print('Epoch:{}\t Acc:{:.4f}'.format(epoch + 1, acc))print('--------------kdmodel end--------------')
  1. Main function (load data, implement train function):
if __name__ == '__main__':torch.manual_seed(0)device = torch.device("cuda" if torch.cuda.is_available else "cpu")torch.backends.cudnn.benchmark = True#加载数据集X_train = torchvision.datasets.MNIST(root="dataset/",train=True,transform=transforms.ToTensor(),download=True)X_test = torchvision.datasets.MNIST(root="dataset/",train=False,transform=transforms.ToTensor(),download=True)train_loader = DataLoader(dataset=X_train, batch_size=32, shuffle=True)test_loader = DataLoader(dataset=X_test, batch_size=32, shuffle=False)#从头训练教师模型,并预测teacher(device, train_loader, test_loader)#从头训练学生模型,并预测student(device, train_loader, test_loader)#知识蒸馏训练学生模型model = torch.load('teacher.pkl')kd(model, device, train_loader, test_loader)

最终训练结果,对比Teacher MdeolStuent Model without DistillationStuent Model with Distillation的Accuracy:可以看出,①使用Teacher蒸馏训练出的Student,比独立训练的Student更强。②实际场景中,大部分情况下,student本身都是显著弱于teacher的,因此很难超越teacher的表现。

  • Teacher Mdeol:Epoch:3 Acc:0.9689,Epoch:6 Acc:0.9764
  • Stuent Model without Distillation:Epoch:3 Acc:0.8173
  • Stuent Model with Distillation:Epoch:3 Acc:0.8387,Epoch:20 Acc:0.9015

3. Progressive Distillation Diffusion生成代码实战

通过跨步蒸馏减少扩散模型采样步数的方法,主要内容包括:progressive distillationguided diffusion distillationstep distillationData-free DistillationLatent Consistency Models

本节主要讲解渐进式蒸馏 Progressive Distillation: 因为本文提出的 v-parameterization 在后续的Diffusion工作中被广泛的应用,来加快推理速度,如Imagen video, Imagen, Stable Diffusion, Dall E等。

3.1 Progressive Distillation原理

渐进式蒸馏的目标:是将一个步骤很多的Teacher Diffusion蒸馏为一个步骤较少的Student Diffusion,一般通过反复迭代的方式进行。每次迭代,Student企图1步学习Teacher模型2步的结果。每次迭代蒸馏后,Student需要的Sample步数都会比原来少一半,而当前的Student将会变成下一次的Teacher。

在这里插入图片描述
如上图所示,Teacher Diffusion f ( z , η ) f(z,\eta) f(z,η) 通过 4 个确定性步骤将随机噪声 ε 映射到样本 x,Student Diffusion f ( z , θ ) f(z,\theta) f(z,θ) 只需1步即可学习到这种映射关系。

渐进蒸馏方法

  1. 训练Teacher Diffusion:Teacher模型的训练使用标准Diffusion模型训练方法,它的训练Loss函数定义为Noise的 ε 空间中的均方误差
    在这里插入图片描述
    相关变量定义:
    在这里插入图片描述
    注意:除了通过直接预测 x 进行训练(x-parameterization),还可以通过分别预测 x 和 ε(ε-parameterization),再合并为:
    在这里插入图片描述
    ,或者通过预测 v(v-parameterization),再计算 :
    在这里插入图片描述

  2. 渐进蒸馏Student Diffusion:蒸馏前,用Teacher Diffusion的权重初始化Student Diffusion,且模型结构一样。渐进蒸馏Diffusion方法标准Diffusion模型训练方法 的主要区别在于如何确定去噪模型的 Label 值

    • 标准Diffusion训练中:Diffusion去噪的 Label 是DDIM每个step的预定义好的Noise
    • 渐进式蒸馏Diffusion中:Student Diffusion去噪模型需要预测的 Label 是Teacher模型预测的Noise。且Student Diffusion企图用1步的预测Noise 匹配 Teacher Diffusion 2步的预测Noise,即Student Diffusion在 ε 空间的Label是Teacher Diffusion 2步的预测Noise z t ′ ′ z_t^{''} zt′′(ε-parameterization)。再利用 z ˉ t ′ ′ = z t ′ ′ \bar z_t^{''} = z_t^{''} zˉt′′=zt′′还可以变换到 x 空间(x-parameterization):
      在这里插入图片描述
      在这里插入图片描述

总结:传统Diffusion训练渐进蒸馏Diffusion
在这里插入图片描述

3.2 v-parameterization

我们都知道常规的扩散模型都是通过噪声预测来进行去噪的,即 ε-parameterization-prediction,那么什么是速度预测 v-parameterization-prediction,为什么要用速度预测?

与常规的基于噪声预测的扩散模型不同,基于速度预测的扩散模型的输出是速度 v ^ θ \hat v_{\theta} v^θ ,相应的优化目标函数为:
在这里插入图片描述
其中 v 是速度真值,可以从真实样本 x 和噪声 ε 根据噪声级别计算得到:
在这里插入图片描述

由于在扩散模型蒸馏中,v-parameterization 模型往往比 ε-parameterization表现更好,一般将 ε-parameterization 微调为 v-parameterization

在这里插入图片描述

下面将介绍 x, v, z, ε 的关系(结合上图):
在这里插入图片描述
在这里插入图片描述
总结三种 parameterization:
在这里插入图片描述

3.2 渐进蒸馏 cifar 代码实战

参考Colab:diffusion_distillation.ipynb

  1. Download codes and libs, and import libs:
!apt-get -qq install subversion
!svn checkout https://github.com/google-research/google-research/trunk/diffusion_distillation
!pip install -r diffusion_distillation/diffusion_distillation/requirements.txt --quietimport os
import time
import requests
import functools
import jax
from jax import config
import jax.numpy as jnp
import flax
from matplotlib import pyplot as plt
import numpy as onp
import tensorflow.compat.v2 as tf
tf.enable_v2_behavior()
from diffusion_distillation import diffusion_distillation
  1. configure JAX to use the TPU: JAX是谷歌开源的、可以在CPU、GPU和TPU上运行的numpy,是针对机器学习研究的高性能自微分计算加速框架。
if 'TPU_DRIVER_MODE' not in globals():url = 'http://' + os.environ['COLAB_TPU_ADDR'].split(':')[0] + ':8475/requestversion/tpu_driver_nightly'resp = requests.post(url)time.sleep(5)TPU_DRIVER_MODE = 1
config.FLAGS.jax_xla_backend = "tpu_driver"
config.FLAGS.jax_backend_target = "grpc://" + os.environ['COLAB_TPU_ADDR']
print(config.FLAGS.jax_backend_target)
  1. Train a new diffusion model:
# create model
config = diffusion_distillation.config.cifar_base.get_config()
model = diffusion_distillation.model.Model(config)# init params
state = jax.device_get(model.make_init_state())
state = flax.jax_utils.replicate(state)# JIT compile training step
train_step = functools.partial(model.step_fn, jax.random.PRNGKey(0), True)
train_step = functools.partial(jax.lax.scan, train_step)  # for substeps
train_step = jax.pmap(train_step, axis_name='batch', donate_argnums=(0,))# build input pipeline
total_bs = config.train.batch_size
device_bs = total_bs // jax.device_count()
train_ds = model.dataset.get_shuffled_repeated_dataset(split='train',batch_shape=(jax.local_device_count(),  # for pmapconfig.train.substeps,  # for lax.scan over multiple substepsdevice_bs,  # batch size per device),local_rng=jax.random.PRNGKey(0),augment=True)
train_iter = diffusion_distillation.utils.numpy_iter(train_ds)# run training
for step in range(10):batch = next(train_iter)state, metrics = train_step(state, batch)metrics = jax.device_get(flax.jax_utils.unreplicate(metrics))metrics = jax.tree_map(lambda x: float(x.mean(axis=0)), metrics)print(metrics)
  1. Distill a trained diffusion model:(核心)
# create model
config = diffusion_distillation.config.cifar_distill.get_config()
model = diffusion_distillation.model.Model(config)# load the teacher params
model.load_teacher_state(config.distillation.teacher_checkpoint_path)# init student state
init_params = diffusion_distillation.utils.copy_pytree(model.teacher_state.ema_params)
optim = model.make_optimizer_def().create(init_params)
state = diffusion_distillation.model.TrainState(step=model.teacher_state.step,optimizer=optim,ema_params=diffusion_distillation.utils.copy_pytree(init_params),num_sample_steps=model.teacher_state.num_sample_steps//2)
# build input pipeline
total_bs = config.train.batch_size
device_bs = total_bs // jax.device_count()
train_ds = model.dataset.get_shuffled_repeated_dataset(split='train',batch_shape=(jax.local_device_count(),  # for pmapconfig.train.substeps,  # for lax.scan over multiple substepsdevice_bs,  # batch size per device),local_rng=jax.random.PRNGKey(0),augment=True)
train_iter = diffusion_distillation.utils.numpy_iter(train_ds)steps_per_distill_iter = 10  # number of distillation steps per iteration of progressive distillation
end_num_steps = 4  # eventual number of sampling steps we want to use
while state.num_sample_steps >= end_num_steps:# compile training steptrain_step = functools.partial(model.step_fn, jax.random.PRNGKey(0), True)train_step = functools.partial(jax.lax.scan, train_step)  # for substepstrain_step = jax.pmap(train_step, axis_name='batch', donate_argnums=(0,))# train the student against the teacher modelprint('distilling teacher using %d sampling steps into student using %d steps'% (model.teacher_state.num_sample_steps, state.num_sample_steps))state = flax.jax_utils.replicate(state)for step in range(steps_per_distill_iter):batch = next(train_iter)state, metrics = train_step(state, batch)metrics = jax.device_get(flax.jax_utils.unreplicate(metrics))metrics = jax.tree_map(lambda x: float(x.mean(axis=0)), metrics)print(metrics)# student becomes new teacher for next distillation iterationmodel.teacher_state = jax.device_get(flax.jax_utils.unreplicate(state).replace(optimizer=None))# reset student optimizer for next distillation iterationinit_params = diffusion_distillation.utils.copy_pytree(model.teacher_state.ema_params)optim = model.make_optimizer_def().create(init_params)state = diffusion_distillation.model.TrainState(step=model.teacher_state.step,optimizer=optim,ema_params=diffusion_distillation.utils.copy_pytree(init_params),num_sample_steps=model.teacher_state.num_sample_steps//2)
  1. Load a distilled model checkpoint and sample from it:
# list all available distilled checkpoints
!gsutil ls gs://gresearch/diffusion-distillation# create imagenet model
config = diffusion_distillation.config.imagenet64_base.get_config()
model = diffusion_distillation.model.Model(config)# load distilled checkpoint for 8 sampling steps
loaded_params = diffusion_distillation.checkpoints.restore_from_path('gs://gresearch/diffusion-distillation/imagenet_8', target=None)['ema_params']# fix possible flax version errors
ema_params = jax.device_get(model.make_init_state()).ema_params
loaded_params = flax.core.unfreeze(loaded_params)
loaded_params = jax.tree_map(lambda x, y: onp.reshape(x, y.shape) if hasattr(y, 'shape') else x,loaded_params,flax.core.unfreeze(ema_params))
loaded_params = flax.core.freeze(loaded_params)
del ema_params# sample from the model
imagenet_classes = {'malamute': 249, 'siamese': 284, 'great_white': 2,'speedboat': 814, 'reef': 973, 'sports_car': 817,'race_car': 751, 'model_t': 661, 'truck': 867}
labels = imagenet_classes['truck'] * jnp.ones((4,), dtype=jnp.int32)
samples = model.samples_fn(rng=jax.random.PRNGKey(0), labels=labels, params=loaded_params, num_steps=8)
samples = jax.device_get(samples).astype(onp.uint8)# visualize samples
padded_samples = onp.pad(samples, ((0,0), (1,1), (1,1), (0,0)), mode='constant', constant_values=255)
nrows = int(onp.sqrt(padded_samples.shape[0]))
ncols = padded_samples.shape[0]//nrows
_, height, width, channels = padded_samples.shape
img_grid = padded_samples.reshape(nrows, ncols, height, width, channels).swapaxes(1,2).reshape(height*nrows, width*ncols, channels)
img = plt.imshow(img_grid)
plt.axis('off')

(-0.5, 131.5, 131.5, -0.5)
在这里插入图片描述

可以看出蒸馏过的Diffusion相较于原始的Diffusion,可以在更少的step下得到不错的生成质量FID。(DDIM 采样器 vs 优化的stochastic随机采样器 vs 蒸馏
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/179299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文带你了解如何在Java中操作Redis

文章目录 前言一、 Redis客户端简介1. Redis客户端分类2. Spring 整合 Redis 的两种方式 二、 使用 Jedis 操作 Redis1. Jedis的maven坐标2. 使用Jedis操作Redis的步骤3. Jedis 操作 Redis 示例 三、 使用 Spring Data Redis 操作 Redis1. Spring Data Redis 的 maven 坐标2. s…

Open3D点云数据处理(一):VSCode配置python,并安装open3d教程

文章目录 1 python下载与安装1.1 python下载1.2 python安装1.3 验证python是否安装成功 2 VSCode下载与安装2.1 下载2.2 安装2.3 安装汉化插件2.4 vscode安装python扩展2.5 编写一个简单的python程序并运行2.6 在外部终端中打印运行结果(不是必选的,不修…

丽晶酒店及度假村打造绮丽之境“美食实验室”中国市场首秀

于重庆丽晶酒店以艺术与美食的碰撞演绎“对比之美”,感官之华 2023年11月28日,中国上海 ——基于对当下消费趋势的敏锐洞察,洲际酒店集团旗下奢华品牌丽晶酒店及度假村近年来不断焕新,以崭新形象缔造现代奢华的旅居体验。作为丽晶…

TDL CDL信道模型

文章目录 一 TDL二 CDL三 CDL TDL区别 TDL:(Tapped Delay Line,抽头延迟线) CDL:(Clustered Delay Line,集群延迟线) 一 TDL 定义:由一组不同衰落系数和不同时延的抽头组成。全频率范围为:0.5GHz~100GHz&am…

第七节HarmonyOS UIAbility生命周期以及启动模式

一、UIAbility生命周期 为了实现多设备形态上的裁剪和多窗口的可扩展性,系统对组件管理和窗口管理进行了解耦。UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,WindowStageCreate和WindowStageDestroy为窗口管理器&#xff08…

【软件测试面试】项目经验回答+面试技巧和方法汇总...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、测试面试时问你…

井盖倾斜怎么办?智能井盖传感器监测方法

井盖倾斜是一个紧迫的问题,如果不及时处理可能会导致道路安全性下降,进而增加车辆和行人发生意外的风险。为应对这一问题现已开发出智能井盖传感器,它可以持续监测井盖的状态,一旦发现倾斜等异常情况会立即发出警报。 在智慧城市的…

【unity实战】如何更加规范的创建各种Rogue-Lite(肉鸽)风格的物品和BUFF效果(附项目源码)

文章目录 前言定义基类实现不同的BUFF效果一、回血BUFF1. 简单的回血效果实现2. BUFF层数控制回血量 二、攻击附带火焰伤害三、治疗领域1. 简单的治疗领域实现2. 添加技能冷却时间 通过拾取物品获取对应的BUFF参考源码完结 前言 当创建各种Rogue-Lite(肉鸽&#xf…

Linux基础项目开发1:量产工具——显示系统(二)

前言: 前面我们已经对这个项目的基本框架有了一个初步的了解与认识,要实现显示管理器与输入管理器,有输入有输出基本就实现这个项目的大部分功能了,首先我们先来做显示系统,对于上层系统为了让程序更好扩展&#xff0c…

策略模式实践

目录 前言 五个部分 名词解释 代码 controller层 HelloService接口 实现类 自定义注解 上下文 策略工厂 Java SPI配置 验证 前言 五个部分 接口、实现类、自定义注解、上下文、策略工厂 名词解释 自定义注解(方便后期增加实现类后灵活控制策略) 上下文(初始化…

【RESTful API】RESTful接口设计练习

参考: BV1Ps4y1J7Ve ---------------------------------------------------------------------------------------------------------- 一、RESTful框架 常见的有SpringMVC,jersey,play 二、API测试工具 Postman,Insomnia 三、RESTful接口设计练习 3.1 项目准备 构…

【项目实战】SpringBoot连接openGauss

一:Docker安装openGauss 1.下载openGauss 安装好Docker好以后,执行如下命令下载openGauss3.0镜像。docker pull enmotech/opengauss:3.0.0 2.运行openGauss 执行如下命令docker run -itd --name opengauss \ --restartalways \ --privilegedtrue \ …

eNSP防火墙USG6000V使用Web界面登入教程

文章目录 登入流程1、下载USG6000V的镜像包2、导入USG6000V的镜像包3、配置防火墙web页面4、修改本机vmnet1网卡的ipv4地址5、在eNSP上添加云6、配置防火墙管理地址,开启http服务7、关闭电脑防火墙8、访问web页面 登入流程 1、下载USG6000V的镜像包 链接&#xff…

MySQL表连接

文章目录 MySQL内外连接1.内连接2.外连接(1)左外连接(2)右外连接 3.简单案例 MySQL内外连接 1.内连接 内连接的SQL如下: SELECT ... FROM t1 INNER JOIN t2 ON 连接条件 [INNER JOIN t3 ON 连接条件] ... AND 其他条件;说明一下…

pytest-pytest-html测试报告这样做,学完能涨薪3k

在 pytest 中提供了生成html格式测试报告的插件 pytest-html 安装 安装命令如下: pip install pytest-html使用 我们已经知道执行用例的两种方式,pytest.main()执行和命令行执行,而要使用pytest-html生成报告,只需要在执行时加…

分布式运用之ELK企业级日志分析系统

1.1 ELK的概念与组件 ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。 ElasticSearch: 是基于Lucene(一个全文检索引…

2023-简单点-机器学习中常用的特殊函数,激活函数[sigmoid tanh ]

机器学习中的特殊函数 Sigmoidsoftplus函数tanhReLu(x)Leaky-ReluELUSiLu/ SwishMish伽玛函数beta函数Ref Sigmoid 值域: 【0,1】 定义域:【负无穷,正无穷】 特殊点记忆: 经过 [0 , 0.5] 关键点[0,0.5]处的导数是 0.025 相关导数: softplu…

『VUE3 の 要点摘录』

✅v-model 用法 v-model 原生方法: v-model computed : 更改名字: 多个 v-model 绑定 处理 v-model 修饰符 ✅TS项目报错 1、TypeScript 错误 “Module ‘…index’ has no default export” // tsconfig.json {...."compilerOpt…

大金仓数据库:kingbase学习

kingbase学习 1.简介2. 安装3. 基础使用3.1 客户端连接3.2 表数据测试3.2.1 建表创建字段备注 3.2.2 数据写入测试3.2.2 json测试3.2.2.1 json查询测试3.2.2.2 json修改测试3.2.2.3 json数据迁移测试 4.springboot实战4.1 maven依赖4.2 连接配置4.3 mybatis-plus测试4.4 liquib…

【AI认证笔记】NO.2人工智能的发展

目录 一、人工智能的发展里程碑 二、当前人工智能的发展特点 1.人工智能进入高速发展阶段 2.人工智能元年 三、人工智能高速发展的三大引擎 1.算法突破 2.算力飞跃 3.数据井喷 四、AI的机遇 五、AI人才的缺口 六、行业AI 人工智能算法,万物互联&#xff…