pytorch pyro 贝叶斯神经网络 bnn beyesean neure network svi 定制SVI目标和培训循环,变更推理
定制SVI目标和培训循环¶
Pyro支持各种基于优化的贝叶斯推理方法,包括Trace_ELBO
作为SVI(随机变分推理)的基本实现。参见文件(documents的简写)有关各种SVI实现和SVI教程的更多信息I, 二,以及罗马数字3了解SVI的背景。
在本教程中,我们将展示高级用户如何修改和/或增加变分目标(或者:损失函数)以及由Pyro提供的训练步骤实现,以支持特殊的用例。
-
基本SVI用法
-
较低层次的模式
-
-
示例:自定义正则化
-
示例:调整损失
-
例如:贝塔VAE
-
示例:混合优化器
-
示例:自定义ELBO
-
示例:KL退火
基本SVI用法¶
我们首先回顾一下SVI
烟火中的物体。我们假设用户已经定义了一个model
和一个guide
。然后,用户创建一个优化器和一个SVI
对象:
optimizer = pyro.optim.Adam({"lr": 0.001, "betas": (0.90, 0.999)}) svi = pyro.infer.SVI(model, guide, optimizer, loss=pyro.infer.Trace_ELBO())
然后可以通过调用svi.step(...)
。对…的争论step()
然后被传递给model
和guide
.
较低层次的模式¶
上述模式的好处在于,它允许Pyro为我们处理各种细节,例如:
-
pyro.optim.Adam
动态创建一个新的torch.optim.Adam
每当遇到新参数时优化器 -
SVI.step()
渐变步骤之间的零渐变
如果我们想要更多的控制,我们可以直接操纵各种可微损失方法ELBO
班级。例如,这个优化循环:
svi = pyro.infer.SVI(model, guide, optimizer, loss=pyro.infer.Trace_ELBO()) for i in range(n_iter):loss = svi.step(X_train, y_train)
相当于这个低级模式:
loss_fn = lambda model, guide: pyro.infer.Trace_ELBO().differentiable_loss(model, guide, X_train, y_train) with pyro.poutine.trace(param_only=True) as param_capture:loss = loss_fn(model, guide) params = set(site["value"].unconstrained()for site in param_capture.trace.nodes.values()) optimizer = torch.optim.Adam(params, lr=0.001, betas=(0.90, 0.999)) for i in range(n_iter):# compute lossloss = loss_fn(model, guide)loss.backward()# take a step and zero the parameter gradientsoptimizer.step()optimizer.zero_grad()
示例:自定义正则化¶
假设我们想在SVI损失中加入一个定制的正则项。使用上面的使用模式,这很容易做到。首先我们定义正则项:
def my_custom_L2_regularizer(my_parameters):reg_loss = 0.0for param in my_parameters:reg_loss = reg_loss + param.pow(2.0).sum()return reg_loss
那么我们唯一需要做的改变就是:
- loss = loss_fn(model, guide) + loss = loss_fn(model, guide) + my_custom_L2_regularizer(my_parameters)
示例:剪裁渐变¶
对于一些模型,损耗梯度可能在训练期间爆炸,导致溢出和NaN
价值观。防止这种情况的一种方法是使用渐变剪辑。中的优化器pyro.optim
拿一本可选的字典clip_args
这允许将梯度范数或梯度值剪切到给定的界限内。
要更改上面的基本示例:
- optimizer = pyro.optim.Adam({"lr": 0.001, "betas": (0.90, 0.999)}) + optimizer = pyro.optim.Adam({"lr": 0.001, "betas": (0.90, 0.999)}, {"clip_norm": 10.0})
还可以通过修改上述低级模式来手动实现梯度裁剪的其他变体。
示例:调整损失¶
根据优化算法,损失的规模可能重要,也可能无关紧要。假设我们想在对损失函数进行微分之前,根据数据点的数量对其进行缩放。这很容易做到:
- loss = loss_fn(model, guide) + loss = loss_fn(model, guide) / N_data
请注意,在SVI的情况下,损失函数中的每一项都是来自模型或指南的对数概率,同样的效果可以通过使用poutine.scale。例如,我们可以使用poutine.scale
装饰器缩放模型和指南:
@poutine.scale(scale=1.0/N_data) def model(...):pass@poutine.scale(scale=1.0/N_data) def guide(...):pass
例如:贝塔VAE¶
我们也可以使用poutine.scale以构建非标准的ELBO变分目标,其中,例如,KL散度相对于期望的对数似然性被不同地缩放。特别是对于βVAE,KL散度用一个因子来缩放beta
:
def model(data, beta=0.5):z_loc, z_scale = ...with pyro.poutine.scale(scale=beta)z = pyro.sample("z", dist.Normal(z_loc, z_scale))pyro.sample("obs", dist.Bernoulli(...), obs=data)def guide(data, beta=0.5):with pyro.poutine.scale(scale=beta)z_loc, z_scale = ...z = pyro.sample("z", dist.Normal(z_loc, z_scale))
有了这种模型的选择,并引导对应于潜在变量的测井密度z
来构建变分目标
svi = pyro.infer.SVI(model, guide, optimizer, loss=pyro.infer.Trace_ELBO())
将被缩放一倍beta
,导致KL发散,其同样由beta
.
示例:混合优化器¶
中的各种优化器pyro.optim
允许用户在每个参数的基础上指定优化设置(如学习率)。但是如果我们要对不同的参数使用不同的优化算法呢?我们可以使用Pyro的MultiOptimizer
(见下文),但我们也可以实现同样的事情,如果我们直接操纵differentiable_loss
:
adam = torch.optim.Adam(adam_parameters, {"lr": 0.001, "betas": (0.90, 0.999)}) sgd = torch.optim.SGD(sgd_parameters, {"lr": 0.0001}) loss_fn = pyro.infer.Trace_ELBO().differentiable_loss # compute loss loss = loss_fn(model, guide) loss.backward() # take a step and zero the parameter gradients adam.step() sgd.step() adam.zero_grad() sgd.zero_grad()
为了完整起见,我们还展示了如何使用多重优化器,这使我们能够结合多个烟火优化。请注意,由于MultiOptimizer
使用torch.autograd.grad
引擎盖下(而不是torch.Tensor.backward()
),它的界面略有不同;特别是step()
方法也将参数作为输入。
def model():pyro.param('a', ...)pyro.param('b', ...)...adam = pyro.optim.Adam({'lr': 0.1}) sgd = pyro.optim.SGD({'lr': 0.01}) optim = MixedMultiOptimizer([(['a'], adam), (['b'], sgd)]) with pyro.poutine.trace(param_only=True) as param_capture:loss = elbo.differentiable_loss(model, guide) params = {'a': pyro.param('a'), 'b': pyro.param('b')} optim.step(loss, params)
示例:自定义ELBO¶
在前三个例子中,我们绕过了创建SVI
对象提供的可微分损失函数ELBO
实施。我们可以做的另一件事是创造定制ELBO
实现,并将它们传递到SVI
机械。例如,简化版本的Trace_ELBO
损失函数可能如下所示:
# note that simple_elbo takes a model, a guide, and their respective arguments as inputs def simple_elbo(model, guide, *args, **kwargs):# run the guide and trace its executionguide_trace = poutine.trace(guide).get_trace(*args, **kwargs)# run the model and replay it against the samples from the guidemodel_trace = poutine.trace(poutine.replay(model, trace=guide_trace)).get_trace(*args, **kwargs)# construct the elbo loss functionreturn -1*(model_trace.log_prob_sum() - guide_trace.log_prob_sum())svi = SVI(model, guide, optim, loss=simple_elbo)
请注意,这基本上就是elbo
实施于“迷你烟火”看起来像。
示例:KL退火¶
在深度学习中,KL退火是一种在训练过程中逐渐减少KL散度损失权重的技术,这有助于模型更好地学习数据分布。这种方法在处理深度马尔可夫模型时尤其有用,因为它允许模型在训练初期不过分关注潜在变量的细节,而是更多地关注数据的整体结构。随着训练的进行,逐渐增加KL散度的权重,使得模型能够细化其对潜在变量的推断。
在实现KL退火时,可以通过定义一个定制的损失函数来实现,或者使用像
poutine.scale
这样的工具来动态调整损失函数中的KL散度项的权重。例如,在Pyro这个概率编程库中,可以使用poutine.scale
装饰器来按比例缩小KL散度项,从而实现退火效果。这种方法提供了一种灵活的方式来控制模型在训练过程中对潜在变量分布的推断强度。在实际应用中,KL退火可以帮助模型避免过早地陷入局部最优解,并且有助于提高模型对数据的泛化能力。通过逐渐调整损失函数中各项的权重,模型可以在训练的不同阶段关注不同的学习目标,最终达到更好的学习效果。
此外,KL退火也可以视为一种正则化技术,它通过控制模型复杂度来防止过拟合。在训练初期,较小的KL散度权重允许模型在不完全匹配潜在变量分布的情况下进行学习,这有助于模型探索更广泛的参数空间。随着训练的进行,逐渐增大的KL散度权重则迫使模型更加精确地学习数据分布,从而提高模型的预测准确性。
总的来说,KL退火是一种有效的技术,可以在深度学习模型的训练中发挥作用,特别是在处理复杂的数据分布和结构时。通过合理地设计退火策略,可以显著提高模型的性能和泛化能力。
爬山法是完完全全的贪心法,每次都鼠目寸光的选择一个当前最优解,因此只能搜索到局部的最优值。模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。模拟退火算法以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。以图1为例,模拟退火算法在搜索到局部最优解A后,会以一定的概率接受到E的移动。也许经过几次这样的不是局部最优的移动后会到达D点,于是就跳出了局部最大值A。
模拟退火算法描述:
若J( Y(i+1) )>= J( Y(i) ) (即移动后得到更优解),则总是接受该移动
若J( Y(i+1) )< J( Y(i) ) (即移动后的解比当前解要差),则以一定的概率接受移动,而且这个概率随着时间推移逐渐降低(逐渐降低才能趋向稳定)
这里的“一定的概率”的计算参考了金属冶炼的退火过程,这也是模拟退火算法名称的由来。
根据热力学的原理,在温度为T时,出现能量差为dE的降温的概率为P(dE),表示为:
P(dE) = exp( dE/(kT) )
其中k是一个常数,exp表示自然指数,且dE<0。这条公式说白了就是:温度越高,出现一次能量差为dE的降温的概率就越大;温度越低,则出现降温的概率就越小。又由于dE总是小于0(否则就不叫退火了),因此dE/kT < 0 ,所以P(dE)的函数取值范围是(0,1) 。
随着温度T的降低,P(dE)会逐渐降低。
我们将一次向较差解的移动看做一次温度跳变过程,我们以概率P(dE)来接受这样的移动。
关于爬山算法与模拟退火,有一个有趣的比喻:
爬山算法:兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是爬山算法,它不能保证局部最优值就是全局最优值。
模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,它渐渐清醒了并朝最高方向跳去。这就是模拟退火
(http://www.cnblogs.com/heaad/ 转载请注明)
在……里深度马尔可夫模型教程ELBO变分目标在训练期间被修改。特别地,潜在随机变量之间的各种KL-散度项相对于观察数据的对数概率按比例缩小(即退火)。在本教程中,这是通过使用poutine.scale
。我们可以通过定义一个定制的损失函数来完成同样的事情。后一种选择并不是一种非常优雅的模式,但是我们还是包含了它,以显示我们所拥有的灵活性。
def simple_elbo_kl_annealing(model, guide, *args, **kwargs):# get the annealing factor and latents to anneal from the keyword# arguments passed to the model and guideannealing_factor = kwargs.pop('annealing_factor', 1.0)latents_to_anneal = kwargs.pop('latents_to_anneal', [])# run the guide and replay the model against the guideguide_trace = poutine.trace(guide).get_trace(*args, **kwargs)model_trace = poutine.trace(poutine.replay(model, trace=guide_trace)).get_trace(*args, **kwargs)elbo = 0.0# loop through all the sample sites in the model and guide trace and# construct the loss; note that we scale all the log probabilities of# samples sites in `latents_to_anneal` by the factor `annealing_factor`for site in model_trace.values():if site["type"] == "sample":factor = annealing_factor if site["name"] in latents_to_anneal else 1.0elbo = elbo + factor * site["fn"].log_prob(site["value"]).sum()for site in guide_trace.values():if site["type"] == "sample":factor = annealing_factor if site["name"] in latents_to_anneal else 1.0elbo = elbo - factor * site["fn"].log_prob(site["value"]).sum()return -elbosvi = SVI(model, guide, optim, loss=simple_elbo_kl_annealing) svi.step(other_args, annealing_factor=0.2, latents_to_anneal=["my_latent"])
以前的然后
Customizing SVI objectives and training loops¶
Pyro provides support for various optimization-based approaches to Bayesian inference, with Trace_ELBO
serving as the basic implementation of SVI (stochastic variational inference). See the docs for more information on the various SVI implementations and SVI tutorials I, II, and III for background on SVI.
In this tutorial we show how advanced users can modify and/or augment the variational objectives (alternatively: loss functions) and the training step implementation provided by Pyro to support special use cases.
-
Basic SVI Usage
-
A Lower Level Pattern
-
-
Example: Custom Regularizer
-
Example: Scaling the Loss
-
Example: Beta VAE
-
Example: Mixing Optimizers
-
Example: Custom ELBO
-
Example: KL Annealing
Basic SVI Usage¶
We first review the basic usage pattern of SVI
objects in Pyro. We assume that the user has defined a model
and a guide
. The user then creates an optimizer and an SVI
object:
optimizer = pyro.optim.Adam({"lr": 0.001, "betas": (0.90, 0.999)}) svi = pyro.infer.SVI(model, guide, optimizer, loss=pyro.infer.Trace_ELBO())
Gradient steps can then be taken with a call to svi.step(...)
. The arguments to step()
are then passed to model
and guide
.
A Lower-Level Pattern¶
The nice thing about the above pattern is that it allows Pyro to take care of various details for us, for example:
-
pyro.optim.Adam
dynamically creates a newtorch.optim.Adam
optimizer whenever a new parameter is encountered -
SVI.step()
zeros gradients between gradient steps
If we want more control, we can directly manipulate the differentiable loss method of the various ELBO
classes. For example, this optimization loop:
svi = pyro.infer.SVI(model, guide, optimizer, loss=pyro.infer.Trace_ELBO()) for i in range(n_iter):loss = svi.step(X_train, y_train)
is equivalent to this low-level pattern:
loss_fn = lambda model, guide: pyro.infer.Trace_ELBO().differentiable_loss(model, guide, X_train, y_train) with pyro.poutine.trace(param_only=True) as param_capture:loss = loss_fn(model, guide) params = set(site["value"].unconstrained()for site in param_capture.trace.nodes.values()) optimizer = torch.optim.Adam(params, lr=0.001, betas=(0.90, 0.999)) for i in range(n_iter):# compute lossloss = loss_fn(model, guide)loss.backward()# take a step and zero the parameter gradientsoptimizer.step()optimizer.zero_grad()
Example: Custom Regularizer¶
Suppose we want to add a custom regularization term to the SVI loss. Using the above usage pattern, this is easy to do. First we define our regularizer:
def my_custom_L2_regularizer(my_parameters):reg_loss = 0.0for param in my_parameters:reg_loss = reg_loss + param.pow(2.0).sum()return reg_loss
Then the only change we need to make is:
- loss = loss_fn(model, guide) + loss = loss_fn(model, guide) + my_custom_L2_regularizer(my_parameters)
Example: Clipping Gradients¶
For some models the loss gradient can explode during training, leading to overflow and NaN
values. One way to protect against this is with gradient clipping. The optimizers in pyro.optim
take an optional dictionary of clip_args
which allows clipping either the gradient norm or the gradient value to fall within the given limit.
To change the basic example above:
- optimizer = pyro.optim.Adam({"lr": 0.001, "betas": (0.90, 0.999)}) + optimizer = pyro.optim.Adam({"lr": 0.001, "betas": (0.90, 0.999)}, {"clip_norm": 10.0})
Further variants of gradient clipping can also be implemented manually by modifying the low-level pattern described above.
Example: Scaling the Loss¶
Depending on the optimization algorithm, the scale of the loss may or not matter. Suppose we want to scale our loss function by the number of datapoints before we differentiate it. This is easily done:
- loss = loss_fn(model, guide) + loss = loss_fn(model, guide) / N_data
Note that in the case of SVI, where each term in the loss function is a log probability from the model or guide, this same effect can be achieved using poutine.scale. For example we can use the poutine.scale
decorator to scale both the model and guide:
@poutine.scale(scale=1.0/N_data) def model(...):pass@poutine.scale(scale=1.0/N_data) def guide(...):pass
Example: Beta VAE¶
We can also use poutine.scale to construct non-standard ELBO variational objectives in which, for example, the KL divergence is scaled differently relative to the expected log likelihood. In particular for the Beta VAE the KL divergence is scaled by a factor beta
:
def model(data, beta=0.5):z_loc, z_scale = ...with pyro.poutine.scale(scale=beta)z = pyro.sample("z", dist.Normal(z_loc, z_scale))pyro.sample("obs", dist.Bernoulli(...), obs=data)def guide(data, beta=0.5):with pyro.poutine.scale(scale=beta)z_loc, z_scale = ...z = pyro.sample("z", dist.Normal(z_loc, z_scale))
With this choice of model and guide the log densities corresponding to the latent variable z
that enter into constructing the variational objective via
svi = pyro.infer.SVI(model, guide, optimizer, loss=pyro.infer.Trace_ELBO())
will be scaled by a factor of beta
, resulting in a KL divergence that is likewise scaled by beta
.
Example: Mixing Optimizers¶
The various optimizers in pyro.optim
allow the user to specify optimization settings (e.g. learning rates) on a per-parameter basis. But what if we want to use different optimization algorithms for different parameters? We can do this using Pyro’s MultiOptimizer
(see below), but we can also achieve the same thing if we directly manipulate differentiable_loss
:
adam = torch.optim.Adam(adam_parameters, {"lr": 0.001, "betas": (0.90, 0.999)}) sgd = torch.optim.SGD(sgd_parameters, {"lr": 0.0001}) loss_fn = pyro.infer.Trace_ELBO().differentiable_loss # compute loss loss = loss_fn(model, guide) loss.backward() # take a step and zero the parameter gradients adam.step() sgd.step() adam.zero_grad() sgd.zero_grad()
For completeness, we also show how we can do the same thing using MultiOptimizer, which allows us to combine multiple Pyro optimizers. Note that since MultiOptimizer
uses torch.autograd.grad
under the hood (instead of torch.Tensor.backward()
), it has a slightly different interface; in particular the step()
method also takes parameters as inputs.
def model():pyro.param('a', ...)pyro.param('b', ...)...adam = pyro.optim.Adam({'lr': 0.1}) sgd = pyro.optim.SGD({'lr': 0.01}) optim = MixedMultiOptimizer([(['a'], adam), (['b'], sgd)]) with pyro.poutine.trace(param_only=True) as param_capture:loss = elbo.differentiable_loss(model, guide) params = {'a': pyro.param('a'), 'b': pyro.param('b')} optim.step(loss, params)
Example: Custom ELBO¶
In the previous three examples we bypassed creating a SVI
object and directly manipulated the differentiable loss function provided by an ELBO
implementation. Another thing we can do is create custom ELBO
implementations and pass those into the SVI
machinery. For example, a simplified version of a Trace_ELBO
loss function might look as follows:
# note that simple_elbo takes a model, a guide, and their respective arguments as inputs def simple_elbo(model, guide, *args, **kwargs):# run the guide and trace its executionguide_trace = poutine.trace(guide).get_trace(*args, **kwargs)# run the model and replay it against the samples from the guidemodel_trace = poutine.trace(poutine.replay(model, trace=guide_trace)).get_trace(*args, **kwargs)# construct the elbo loss functionreturn -1*(model_trace.log_prob_sum() - guide_trace.log_prob_sum())svi = SVI(model, guide, optim, loss=simple_elbo)
Note that this is basically what the elbo
implementation in “mini-pyro” looks like.
Example: KL Annealing¶
In the Deep Markov Model Tutorial the ELBO variational objective is modified during training. In particular the various KL-divergence terms between latent random variables are scaled downward (i.e. annealed) relative to the log probabilities of the observed data. In the tutorial this is accomplished using poutine.scale
. We can accomplish the same thing by defining a custom loss function. This latter option is not a very elegant pattern but we include it anyway to show the flexibility we have at our disposal.
def simple_elbo_kl_annealing(model, guide, *args, **kwargs):# get the annealing factor and latents to anneal from the keyword# arguments passed to the model and guideannealing_factor = kwargs.pop('annealing_factor', 1.0)latents_to_anneal = kwargs.pop('latents_to_anneal', [])# run the guide and replay the model against the guideguide_trace = poutine.trace(guide).get_trace(*args, **kwargs)model_trace = poutine.trace(poutine.replay(model, trace=guide_trace)).get_trace(*args, **kwargs)elbo = 0.0# loop through all the sample sites in the model and guide trace and# construct the loss; note that we scale all the log probabilities of# samples sites in `latents_to_anneal` by the factor `annealing_factor`for site in model_trace.values():if site["type"] == "sample":factor = annealing_factor if site["name"] in latents_to_anneal else 1.0elbo = elbo + factor * site["fn"].log_prob(site["value"]).sum()for site in guide_trace.values():if site["type"] == "sample":factor = annealing_factor if site["name"] in latents_to_anneal else 1.0elbo = elbo - factor * site["fn"].log_prob(site["value"]).sum()return -elbosvi = SVI(model, guide, optim, loss=simple_elbo_kl_annealing) svi.step(other_args, annealing_factor=0.2, latents_to_anneal=["my_latent"])
相关文章:
pytorch pyro 贝叶斯神经网络 bnn beyesean neure network svi 定制SVI目标和培训循环,变更推理
定制SVI目标和培训循环 Pyro支持各种基于优化的贝叶斯推理方法,包括Trace_ELBO作为SVI(随机变分推理)的基本实现。参见文件(documents的简写)有关各种SVI实现和SVI教程的更多信息I, 二,以及罗马数字3了解SVI的背景。 在本教程中…...

Openeuler22 部署 RackTables0.22.0
目录 0、前言 一、部署lamp环境,lamp环境测试 1、部署Apache,apache环境测试 2、部署php、mysql,php环境测试 二、放文件 三、配置mysql 四、安装racktables 第一步、点击proceed继续 第二步、点击proceed 第三步、根据提示进行操作…...

从传统到智能:高标准农田灌区信息化助力农业现代化
从传统农业的粗放式管理,到如今智能化、精准化的现代农业转型,高标准农田灌区信息化建设无疑是推动这一历史进程的关键力量。它不仅标志着农业生产方式的根本性变革,还深刻影响着农业资源的高效利用与可持续发展策略,为实现农业现…...

堆排序-建堆,增删替换
我们 之前写过根据 堆排序的优先级队列,但是如果我们想要建立一个堆怎么办呢? 如何实现上浮 下潜 具体看这篇文章 堆排序-优先级队列-CSDN博客 建堆 我们有两种方法建立一个堆 1.我们基于add方法建立一个堆,一次次的add,然后对…...

使用AI写WebSocket知识是一种怎么样的体验?
一、WebSocket基础知识 1. WebSocket概念 1.1 为什么会出现WebSocket 一般的Http请求我们只有主动去请求接口,才能获取到服务器的数据。例如前后端分离的开发场景,自嘲为切图仔的前端大佬找你要一个配置信息的接口,我们后端开发三下两下开…...

若依系统(Security)增加微信小程序登录(自定义登录)
若依系统(分离版后端)自带的账号验证是基于 UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(username, password); 验证,然后在系统中controller或service类中 SecurityUtils 工具类中直接可获取用户或用户…...
道可云人工智能元宇宙每日资讯|2024互联网岳麓峰会在长沙召开
道可云元宇宙每日简报(2024年9月10日)讯,今日元宇宙新鲜事有: 2024互联网岳麓峰会在长沙召开 9月9日,2024互联网岳麓峰会在长沙召开,湖南省副省长曹志强在峰会表示,今年上半年湖南省人工智能产…...
MySQL JDBC URL各参数详解
jdbc:mysql://localhost:3306/test?userroot&password123456&useUnicodetrue&characterEncodinggbk &autoReconnecttrue&failOverReadOnlyfalse&serverTimezoneUTC&drivercom.mysql.cj.jdbc.Driver 参数名称参数说明缺省值user指定用于连接数据库…...
celery control.shutdown
Celery 提供了 control 模块,允许你发送控制命令给正在运行的 worker。其中 shutdown 命令可以用来关闭一个或多个 worker。下面是如何使用 control.shutdown 来关闭 worker 的详细说明。 使用 control.shutdown 1. 导入必要的模块 首先,你需要导入 C…...
数据库设计与软件工程阶段的对应关系
数据库设计的很多阶段确实可以与软件工程的各阶段对应起来,这体现了数据库设计作为软件工程中一个核心组成部分的紧密关联性。 1. 需求分析阶段 数据库设计:需求分析是数据库设计的初始阶段,主要任务是收集和分析用户的需求,包括…...

基于ASP+ACCESS的教师信息管理系统
摘要 随着我国社会主义市场经济的发展和改革开放的不断深入,计算机的应用已遍及国民经济的各个领域,计算机来到我们的工作和生活中,改变着我们和周围的一切。在以前,学校用手工处理教师档案以及工资发放等繁多的工作和数据时&…...

【智能体】浅谈大模型之AI Agent
随着ChatGPT推出插件和函数调用功能,构建以LLM(大语言模型)为核心控制器的AI Agent愈发成为一个拥有无限可能的概念。 AI Agent是一种超越简单文本生成的人工智能系统。它使用大型语言模型(LLM)作为其核心计算引擎&am…...
大疆 嵌入式 笔记 面试题目汇总大全[嵌入式找工作必看] 比较有难度适合进阶收藏学习
24届大疆车载嵌入式系统安全面试经验 投递岗位:(大疆车载)嵌入式系统安全 投递时间:大疆大概在7月-8月月初开秋招岗位。8月月中开始笔试,8月月末开始面试。(理论上9月,10月开奖。)…...
线程池以及详解使用@Async注解异步处理方法
目录 一.什么是线程池: 二.使用线程池的好处: 三.线程池的使用场景: 四.使用线程池来提高Springboot项目的并发处理能力: 1.在application.yml配置文件中配置: 2.定义配置类来接受配置文件内的属性值:…...
css鼠标移动过去变成手的图标
在css中定义 cursor:pointer;直接在html中指定 <div class"mt-2 mt-md-2 mt-lg-1 fs-md-1 fs-lg-2 " style"cursor:pointer;"></div>...

uniapp 懒加载、预加载、缓存机制深度解析
uniapp 懒加载、预加载、缓存机制深度解析 文章目录 uniapp 懒加载、预加载、缓存机制深度解析一、为什么要使用uniapp的懒加载、预加载和缓存机制二、如何使用uniapp的懒加载、预加载和缓存机制1. 懒加载2. 预加载3. 缓存机制 四、扩展与高级技巧1. 结合懒加载和预加载优化页面…...

《OpenCV计算机视觉》—— 图像形态学(腐蚀、膨胀等)
文章目录 一、图像形态学基本概念二、基本运算1.简单介绍2.代码实现 三、高级运算1.简单介绍2.代码实现 一、图像形态学基本概念 图像形态学是图像处理科学的一个独立分支,它基于集合论和数学形态学的理论,专门用于分析和处理图像中的形状和结构。图像形…...
【Rust光年纪】海洋学研究的利器:Rust语言海洋学计算库详解
探索Rust语言下的海洋学计算库:功能对比与选择指南 前言 随着科学技术的不断发展,海洋学领域对于计算和数据处理的需求也日益增长。在Rust语言中,出现了一系列专注于海洋学计算和数据处理的库,它们为海洋学工作者提供了强大的工…...

Word文档的读入【2】
现在,乔老师已经了解了Word文档的基本结构。 下面,我们通过观察一份答题卡来思考一下每条信息的具体位置。这样,在后面几天的学习和操作中,我们就能更快、更准确地读取到答题卡中的信息。 这份答题卡是由一个表格和一些段落组成。…...

报名开启 | 游戏开发缺队友?首期繁星招聘会来袭!
**点击蓝链领取游戏开发教程 ** EE GAMES 创作者社区是专注于链接每一位游戏创作者,提供社区交流、团队匹配、经验共享、成果展示、知识整合、最新活动资讯等全方位服务的游戏领域垂类社区。 这里不仅仅是一个游戏创作的互助平台,更是每一位游戏创作者…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...