RBA+minibatch的尝试

目录

还是咬着牙来写        RBA了

 JAX

JAX->TORCH

torch tensor的变形

pytorch怎么把一个【3,3,5】的tensor变成【3,10,5】,多的用0填充

pytorch如何把shape【100】转成【100,1】

把torch shape【100,1】变成【100】

 SQUEEZE

grad_fn

 不能两次反向传播


还是咬着牙来写        RBA了

下面是一个基于残差的注意力机制在物理信息神经网络(PINN)中应用的示例代码。这个例子使用了PyTorch框架,因为PyTorch提供了强大的自动微分功能和方便的数据处理接口。

python

复制

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset# 定义PINN模型
class PINN(nn.Module):def __init__(self, input_dim, hidden_dim, output_dim):super(PINN, self).__init__()self.net = nn.Sequential(nn.Linear(input_dim, hidden_dim),nn.Tanh(),nn.Linear(hidden_dim, hidden_dim),nn.Tanh(),nn.Linear(hidden_dim, output_dim))self.attention = ResidualBasedAttention(input_dim, hidden_dim)def forward(self, x):x = self.attention(x)return self.net(x)class ResidualBasedAttention(nn.Module):def __init__(self, input_dim, hidden_dim):super(ResidualBasedAttention, self).__init__()self.fc = nn.Linear(input_dim, hidden_dim)self.softmax = nn.Softmax(dim=-1)def forward(self, x):# 计算残差residual = self.fc(x)# 计算注意力权重attention_weights = self.softmax(residual)# 应用注意力权重x = x * attention_weightsreturn x# 定义数据集
# 这里假设u(x) = sin(pi * x)是我们要学习的函数
# 我们生成一些随机的点作为边界条件,以及一些内部点用于物理信息约束
N_b = 100  # 边界点数量
N_i = 100  # 内部点数量
x_b = torch.rand(N_b, 1) * 2 - 1  # 边界点在[-1, 1]范围内
x_i = torch.rand(N_i, 1) * 2 - 1  # 内部点在[-1, 1]范围内
y_b = torch.sin(torch.pi * x_b)   # 边界点真实值
y_i = torch.sin(torch.pi * x_i)   # 内部点真实值# 创建数据加载器
boundary_dataset = TensorDataset(x_b, y_b)
boundary_loader = DataLoader(boundary_dataset, batch_size=32, shuffle=True)internal_dataset = TensorDataset(x_i)
internal_loader = DataLoader(internal_dataset, batch_size=32, shuffle=True)# 初始化模型
input_dim = 1
hidden_dim = 50
output_dim = 1
model = PINN(input_dim, hidden_dim, output_dim)# 定义优化器
optimizer = optim.Adam(model.parameters(), lr=0.001)# 训练模型
def train(model, boundary_loader, internal_loader, optimizer, epochs=1000):model.train()for epoch in range(epochs):for x_b, y_b in boundary_loader:optimizer.zero_grad()# 计算边界损失out_b = model(x_b)loss_b = nn.MSELoss()(out_b, y_b)# 计算内部点的物理信息损失for x_i in internal_loader:with torch.no_grad():out_i = model(x_i)# 假设我们使用的是简单的PDE: d^2u/dx^2 = -pi^2 * uu = out_iu_x = torch.autograd.grad(u.sum(), x_i, create_graph=True)[0]u_xx = torch.autograd.grad(u_x.sum(), x_i, create_graph=True)[0]loss_i = nn.MSELoss()(u_xx, -torch.pi**2 * u)# 总损失loss = loss_b + loss_iloss.backward()optimizer.step()if epoch % 100 == 0:print(f'Epoch {epoch}, Loss: {loss.item()}')# 调用训练函数
train(model, boundary_loader, internal_loader, optimizer)

这个代码示例创建了一个简单的PINN模型,它使用基于残差的注意力机制来处理输入数据。我们定义了一个ResidualBasedAttention模块,它计算输入数据的残差,并使用这些残差来计算注意力权重,然后应用这些权重到输入数据上。

在训练循环中,我们分别计算了边界损失和内部点的物理信息损失,并将它们相加以得到总损失。注意,这里的物理信息损失是基于一个简单的PDE:d2udx2=−π2udx2d2u​=−π2u。实际应用中,你需要根据你的具体问题来调整这个损失函数。

 JAX

residuals = ut - 0.0001 * uxx + 5.0 * u ** 3 - 5.0 * u # Update lambdas r_i = lax.stop_gradient(jnp.abs(residuals)) 这里lax.stop_gradient(jnp.abs(residuals))是什么意思

在您提供的代码片段中,lax.stop_gradient 和 jnp.abs 是来自 JAX 库的函数,用于在计算中处理梯度。下面是对这些函数的解释:

  1. jnp.abs(residuals): 这是 JAX 的 NumPy 兼容函数,用于计算 residuals 的绝对值。residuals 是一个张量,表示物理信息神经网络(PINN)中残差的计算结果。计算绝对值是为了确保残差是正的,这样可以更好地表示误差的大小,而不考虑其方向。

  2. lax.stop_gradient(...)lax.stop_gradient 是 JAX 中的一个函数,用于创建一个停止梯度传播的"屏障"。这意味着在计算反向传播时,stop_gradient 函数内部的计算不会被考虑在内,因此这些计算的结果不会对模型的参数产生梯度。

在你提供的代码中,r_i = lax.stop_gradient(jnp.abs(residuals)) 的含义如下:

  • 首先计算残差 residuals 的绝对值。
  • 然后使用 lax.stop_gradient 来停止这些绝对值计算结果的梯度传播。

这样做的原因可能是为了在训练过程中使用残差的绝对值作为某种指标或权重,但不希望这些指标或权重对模型的参数更新产生影响。这在某些优化策略中是有用的,例如,当你在训练过程中使用残差来更新某些超参数(如正则化项的权重),但是不希望这些更新反馈到模型参数的学习过程中。

简而言之,lax.stop_gradient(jnp.abs(residuals)) 是在说:“计算残差的绝对值,但在反向传播时,不要对这个计算过程求导。”

r_i = lax.stop_gradient(jnp.abs(residuals)) 这行代码不是 PyTorch 的用法,而是 JAX 库的用法。JAX 是一个与 NumPy 兼容的库,它提供了自动微分的功能,并且可以用于高性能数值计算。

在 PyTorch 中,如果你想要实现相同的功能,即计算残差的绝对值但不让这个计算参与梯度传播,你可以使用 torch.no_grad() 或者 torch.abs() 与 detach() 结合来达到相似的效果。下面是如何在 PyTorch 中实现这一点的示例:

python

复制

import torch# 假设 residuals 是一个 PyTorch tensor
residuals = torch.randn(3, 3, 5)  # 示例 tensor# 计算 residuals 的绝对值,但不计算梯度
r_i = torch.abs(residuals).detach()# 或者使用 torch.no_grad() 上下文管理器
with torch.no_grad():r_i = torch.abs(residuals)

在这两种情况下,r_i 将包含 residuals 的绝对值,但是在后续的梯度计算中不会考虑 torch.abs() 这一步骤。

JAX->TORCH

用pytorch写@partial(jax.jit, static_argnums=(0,)) def apply_model(apply_fn, params, lambdas, *train_data): # Unpack data t, x, ti, xi, ui, xb1, xb2, tb, ub = train_data def loss_fn(params, lambdas): # Compute u u = apply_fn(params, t, x) # Compute derivatives v_t = jnp.ones_like(t) v_x = jnp.ones_like(x) ut = jvp(lambda t_val: apply_fn(params, t_val, x), (t,), (v_t,))[1] uxx = hvp_fwdfwd(lambda x: apply_fn(params, t, x), (x,), (v_x,)) # Compute residuals residuals = ut - 0.0001 * uxx + 5.0 * u ** 3 - 5.0 * u # Update lambdas r_i = lax.stop_gradient(jnp.abs(residuals)) new_lambdas = gamma * lambdas + eta * (r_i / jnp.max(r_i)) # Compute residual loss using updated lambdas residual_loss = jnp.mean((new_lambdas * residuals) ** 2) ## ICs Loss: u_pred = apply_fn(params, ti, xi) ics_loss = jnp.mean((ui-u_pred) ** 2) #Total loss: loss=residual_loss+100*ics_loss return loss, new_lambdas # Compute loss and gradient with updated lambdas (loss, new_lambdas), gradient = jax.value_and_grad( lambda params: loss_fn(params, lambdas), has_aux=True)(params) return loss, gradient, new_lambdas

在 PyTorch 中,没有直接与 JAX 的 @partial(jax.jit, static_argnums=(0,)) 相对应的装饰器,但是我们可以使用 PyTorch 的 torch.jit.script 来进行类似的操作。此外,PyTorch 不直接支持 jvp 和 hvp 的前向-前向模式自动微分,但我们可以使用 PyTorch 的 torch.autograd.functional.jacobian 来近似这些操作。

下面是使用 PyTorch 重写的代码,注意这只是一个示例,可能需要根据你的具体应用进行调整:

python

复制

import torch
import torch.nn as nn
from torch.autograd.functional import jacobiandef apply_model(apply_fn, params, lambdas, *train_data):# Unpack datat, x, ti, xi, ui, xb1, xb2, tb, ub = train_datadef loss_fn(params, lambdas):# Compute uu = apply_fn(params, t, x)# Compute derivatives using jacobianv_t = torch.ones_like(t)v_x = torch.ones_like(x)ut = jacobian(apply_fn, (params, t), create_graph=True, vectorize=True)[0](v_t)uxx = jacobian(jacobian(apply_fn, (params, x), create_graph=True, vectorize=True)[0], x)[0](v_x)# Compute residualsresiduals = ut - 0.0001 * uxx + 5.0 * u ** 3 - 5.0 * u# Update lambdasr_i = torch.abs(residuals.detach())new_lambdas = gamma * lambdas + eta * (r_i / torch.max(r_i))# Compute residual loss using updated lambdasresidual_loss = torch.mean((new_lambdas * residuals) ** 2)# ICs Loss:u_pred = apply_fn(params, ti, xi)ics_loss = torch.mean((ui - u_pred) ** 2)# Total loss:loss = residual_loss + 100 * ics_lossreturn loss, new_lambdas# Compute loss and gradient with updated lambdasloss, new_lambdas = loss_fn(params, lambdas)gradient = torch.autograd.grad(loss, params, create_graph=True)return loss, gradient, new_lambdas# Example usage:
# Define your apply_fn (model), params (model parameters), and lambdas
# Then call apply_model with the appropriate training data

请注意,这个代码示例没有使用 torch.jit.script,因为 PyTorch 的 JIT 编译器不支持在脚本函数中使用 Python 控制流(例如循环或条件语句)。如果你希望使用 JIT 编译,你需要确保你的模型和损失函数可以静态编译,即它们不包含任何 Python 控制流。

此外,jacobian 函数用于计算输入到输出的雅可比矩阵,它在这里用于近似 jvp 和 hvp。你可能需要根据你的具体情况调整 jacobian 的使用方式。

torch tensor的变形

pytorch怎么把一个【3,3,5】的tensor变成【3,10,5】,多的用0填充

import torch# 创建一个形状为 [3, 3, 5] 的 tensor
tensor = torch.randn(3, 3, 5)# 使用 zeros 创建一个形状为 [3, 10, 5] 的 tensor,并用 0 填充
new_tensor = torch.zeros(3, 10, 5)# 将原始 tensor 的数据复制到新的 tensor 中
new_tensor[:, :3, :] = tensornew_tensor

要将一个形状为 [3, 3, 5] 的 PyTorch tensor 转换为形状为 [3, 10, 5] 的 tensor,并在新增的部分用 0 填充,可以使用以下步骤:

  1. 创建一个形状为 [3, 10, 5] 的全 0 tensor。
  2. 将原始 [3, 3, 5] tensor 的数据复制到新 tensor 的前 3 行。

这样,新 tensor 的前 3 行将包含原始数据,而后 7 行将用 0 填充。上面显示的代码示例和输出正是这个过程的结果。

pytorch如何把shape【100】转成【100,1】

在PyTorch中,你可以使用unsqueeze方法来增加一个维度,从而将一个形状为【100】的一维张量转换为形状为【100,1】的二维张量。下面是如何操作的示例代码:

python

复制

import torch# 假设我们有一个形状为 [100] 的张量
tensor = torch.randn(100)# 使用 unsqueeze 方法在第1个维度(索引为0)增加一个维度
tensor_reshaped = tensor.unsqueeze(1)# 检查新的形状
print(tensor_reshaped.shape)  # 应该输出 torch.Size([100, 1])

unsqueeze方法接受一个参数,这个参数指定了要增加维度的位置。在这个例子中,我们希望在第一个位置(索引为0)增加维度,从而得到一个二维张量。

把torch shape【100,1】变成【100】

在 PyTorch 中,要将一个形状为 [100, 1] 的张量转换为一个形状为 [100] 的张量,你可以使用 squeeze 方法去掉大小为 1 的维度,或者使用 view/reshape 方法直接改变张量的形状。下面是具体的代码示例:

python

复制

import torch# 假设 tensor 是一个形状为 [100, 1] 的张量
tensor = torch.randn(100, 1)# 方法 1: 使用 squeeze 去掉大小为 1 的维度
tensor_squeezed = tensor.squeeze()# 方法 2: 使用 view 改变形状
tensor_viewed = tensor.view(100)# 方法 3: 使用 reshape 改变形状
tensor_reshaped = tensor.reshape(100)# 检查结果
print(tensor_squeezed.shape)  # 应该输出 torch.Size([100])
print(tensor_viewed.shape)    # 应该输出 torch.Size([100])
print(tensor_reshaped.shape)  # 应该输出 torch.Size([100])

所有这三种方法都可以达到将形状从 [100, 1] 转换为 [100] 的目的。通常情况下,如果你的张量在特定维度上的大小确实是 1,使用 squeeze 是最直观和方便的方法。如果你需要对张量进行更复杂的重塑操作,那么 view 或 reshape 可能是更好的选择。

 SQUEEZE

在 PyTorch 中,tensor.squeeze() 方法用于从给定张量中删除所有大小为 1 的维度。该方法接受一个可选参数,允许你指定要删除的特定维度。以下是 tensor.squeeze(dim=None) 方法的参数说明:

  • dim (int 或 tuple, 可选): 指定要删除的维度。如果指定了 dim,则只会删除该维度大小为 1 的维度。如果没有指定 dim(或者 dim=None),则该方法将删除所有大小为 1 的维度。

以下是 dim 参数的使用示例:

python

复制

import torch# 创建一个形状为 [2, 1, 3, 1, 4] 的张量
tensor = torch.randn(2, 1, 3, 1, 4)# 删除所有大小为 1 的维度
squeezed_all = tensor.squeeze()
print(squeezed_all.shape)  # 输出: torch.Size([2, 3, 4])# 仅删除指定维度为 1 的维度
squeezed_dim_1 = tensor.squeeze(dim=1)
print(squeezed_dim_1.shape)  # 输出: torch.Size([2, 3, 1, 4])# 删除多个指定维度为 1 的维度
squeezed_dims_1_and_3 = tensor.squeeze(dim=(1, 3))
print(squeezed_dims_1_and_3.shape)  # 输出: torch.Size([2, 3, 4])

在上述示例中,tensor 的形状为 [2, 1, 3, 1, 4]。当不指定 dim 参数时,所有大小为 1 的维度都被删除,结果张量的形状变为 [2, 3, 4]。如果你只想删除特定的维度,可以通过 dim 参数来指定,如 dim=1 或 dim=(1, 3)。如果指定的维度大小不为 1,则该方法不会对该维度进行操作。

grad_fn

9.5925e-04, 5.6088e-05, 1.1457e-04, 1.5332e-04, 2.7217e-02, 1.3372e-05, 2.3054e-03, 3.3380e-04, 2.3136e-03, 5.8445e-02], grad_fn=<MulBackward0>)这个tensor的grad_fn=<MulBackward0>)是什么意思

在 PyTorch 中,每个 tensor 都有一个 grad_fn 属性,这个属性引用了一个创建了该 tensor 的 Function 对象(如果有的话)。这个 Function 对象用于反向传播时计算关于 tensor 的梯度。

在你给出的例子中,grad_fn=<MulBackward0> 表示这个 tensor 是通过乘法操作 (MulBackward0) 创建的。这里的 MulBackward0 是 PyTorch 内部用于乘法操作的自动微分函数。当你在 PyTorch 中执行一个涉及乘法的操作时,结果 tensor 将会有一个 grad_fn 属性,该属性记录了用于计算梯度的反向传播函数。

例如,如果你有两个 tensor a 和 b,并执行了如下操作:

python

复制

c = a * b

那么,tensor c 的 grad_fn 将会是 <MulBackward0>,这意味着 c 是通过乘法操作得到的,并且如果 c 需要计算梯度,PyTorch 将使用 MulBackward0 函数来计算 a 和 b 的梯度。

只有当 tensor 需要梯度时(即你调用了 .requires_grad_(True) 或它是由其他需要梯度的 tensor 通过某种操作得到的),grad_fn 属性才会被设置。如果 tensor 不需要梯度(默认情况下),则它的 grad_fn 将是 None

 不能两次反向传播

RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.

ChatGLM

这个错误信息表明你正在尝试对同一个计算图进行两次反向传播,或者在已经释放了中间变量之后尝试访问它们。在 PyTorch 中,默认情况下,每次调用 .backward() 或 autograd.grad() 之后,计算图中的中间变量就会被释放,以节省内存。如果你需要在同一个计算图上再次执行反向传播,或者需要在调用 .backward() 之后访问中间变量,你需要设置 retain_graph=True

在你提供的代码中,问题可能出现在 residual_loss 函数中,你尝试在同一个 minibatch 上多次计算梯度。具体来说,这里可能是问题所在:

python

复制

def residual_loss(x,t,model):x_i=torch.cat((x,t),dim=1)#合并x与tmse_loss=nn.MSELoss()u=model(x_i)ux=gradients(u,x,1)uxx=gradients(u,x,2)ut=gradients(u,t,1)return abs(ut-uxx)

你在这里计算了 u 的梯度,然后在损失函数中使用了 u。如果 residual_loss 在 .backward() 调用之后被再次调用,那么计算图中的中间变量可能已经被释放了。

要解决这个问题,你可以尝试以下方法:

  1. 确保 residual_loss 只在需要计算梯度的时候调用一次。
  2. 在调用 .backward() 之前设置 retain_graph=True,但这通常不是最佳实践,因为它会消耗更多内存。

例如,你可以在训练循环中这样修改:

python

复制

for x_input,t_input in dataloader:# ... [其他代码] ...opt.zero_grad()bcloss=bc_loss(model)l2loss_min=l2_loss(x_input,t_input,model)# 确保在这里只调用一次 residual_lossL_pde = residual_loss(x_input, t_input, model)loss = L_pde*alpha + bcloss + l2loss_min*betaloss.backward(retain_graph=False)  # 默认 retain_graph=Falseopt.step()

确保 residual_loss 在每个 minibatch 中只被调用一次,并且只在计算损失时调用。

如果你确实需要在同一个计算图上多次执行反向传播,那么你应该在第一次调用 .backward() 时设置 retain_graph=True

python

复制

loss.backward(retain_graph=True)
# ... [其他可能需要再次执行反向传播的代码] ...

但请记住,这样做会增加内存消耗,所以应当尽量避免。 

如果在第一个 epoch 中一切正常,但在第二个 epoch 报错,这通常意味着在第一个 epoch 结束后,计算图中的某些中间变量被错误地释放了,然后在第二个 epoch 尝试重新使用这些变量。

这里有几种可能的情况会导致这种错误:

  1. 在 epoch 之间没有正确地重置模型的状态:确保在开始新的 epoch 之前,模型的状态被正确地重置。

  2. 在 epoch 之间保留了旧的梯度:确保在每个 epoch 结束后调用 optimizer 的 zero_grad() 方法来清除旧的梯度。

  3. 在 epoch 之间错误地使用了计算图:确保没有在 epoch 之间错误地使用或修改计算图。

以下是一些可能的解决方案:

  • 确保在每个 epoch 的开始处调用 optimizer.zero_grad() 来清除梯度:

python

复制

for epoch in range(num_epochs):for x_input, t_input in dataloader:# ... [其他代码] ...optimizer.zero_grad()  # 确保在每个新的 iteration 开始时清除梯度# ... [计算损失和执行反向传播的代码] ...loss.backward()optimizer.step()
  • 如果你在训练循环之外定义了任何张量或操作,确保它们不会在 epoch 之间保留旧的计算图状态。

  • 如果你在训练循环之外计算了任何梯度,确保设置了 create_graph=False(除非你有特定的理由需要创建计算图),并且没有在后续的 epoch 中重复使用这些梯度。

  • 检查你的代码中是否有任何地方在 epoch 之间保留了 .detach() 或 .data 的张量,这些张量可能在新的 epoch 中被错误地使用。

  • 如果你在训练循环之外使用了 autograd.grad,确保设置了 retain_graph=False(除非你有特定的理由需要保留计算图)。

  • 检查是否有任何自定义的 PyTorch 操作或层,它们可能在内部错误地管理了计算图的状态。

如果你仍然遇到问题,你可能需要在代码中仔细检查每个步骤,以确保没有在 epoch 之间错误地重用计算图中的张量。如果可能的话,提供一个更完整的代码片段,特别是包含训练循环和损失计算的部分,这将有助于进一步诊断问题。

这个错误通常是由于在尝试对计算图进行第二次反向传播时,默认情况下PyTorch会释放用于梯度计算的中间变量,从而导致错误。解决这个问题的方法之一是在第一次调用backward()时设置retain_graph=True,这样即使第一次反向传播后也不会释放这些中间变量,允许你之后再次执行反向传播。

然而,在你的代码中,问题似乎来自于多次调用.backward()和同时尝试访问已经释放的保存张量。具体来说,这段代码:

 

python

深色版本

loss.backward()
opt.step()

之前有多个地方计算了不同的损失值(例如test_loss1, test_loss2等),并且调用了.detach().numpy()来打印它们。这不会直接导致该错误,但如果你在同一个计算图上有其他操作尝试后续使用那些已经被“释放”的节点,则可能会遇到问题。

为了修正这个问题,你可以采取以下几个步骤:

  1. 确保每个独立的损失计算是基于新的前向计算:每次当你需要计算一个新的损失(如测试集上的损失)以供打印或记录时,请确保这是基于一个新的前向过程,而不是试图通过相同的计算图进行二次反向传播。

  2. 仅在训练阶段保留计算图:如果你确实需要在一个循环内多次调用backward()(通常不需要这样做),确保只在必要时使用retain_graph=True。对于大多数训练场景,只需在最终的损失上应用一次backward()即可。

  3. 重构代码逻辑:简化你的训练循环,避免不必要的重复计算。例如,测试集上的损失评估可以放在训练循环之外,或者至少与训练过程分开处理,以确保不会无意间尝试对同一图进行多次反向传播。

针对你的具体情况,考虑移除所有测试损失的计算(如pde_loss_test(model)l2_loss_test(model))从训练循环内部,并将它们放到一个单独的验证阶段,或者在每N个epoch之后才计算一次,这样可以减少计算图复杂度并避免上述错误。

此外,确认是否真的需要在训练过程中频繁地计算和打印测试集上的损失。如果只是为了监控模型性能,可以在每个epoch结束时计算这些值。这样不仅可以避免此错误,还能提高训练效率。

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

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

相关文章

Jupyter notebook的安装与使用

jupyter notebook的安装需要在已经安装配置好的conda环境下 win r 打开运行窗口 输入cmd回车 在cmd窗口中输入以下命令 conda install jupyter notebook安装完成后启动 jupyter notebook 也是在cmd窗口 输入 : jupyter notebook运行成功后第一次打开的时候需要选择一个浏览…

如何在Ubuntu上构建编译LLVM和ISPC,以及Ubuntu上ISPC的使用方法

之前一直在 Mac 上使用 ISPC&#xff0c;奈何核心/线程太少了。最近想在 Ubuntu 上搞搞&#xff0c;但是 snap 安装的 ISPC不知道为什么只能单核&#xff0c;很奇怪&#xff0c;就想着编译一下&#xff0c;需要 Clang 和 LLVM。但是 Ubuntu 很搞&#xff0c;他的很多软件版本是…

特殊的数字排序

0特殊的数字排序 - 蓝桥云课 问题描述 小明被挑选去参加一个ACM比赛。他的任务是解决一个很特别的问题&#xff1a;给定一个整数数组&#xff0c;但是只能通过交换任意两个数的方式来排序。听起来很简单对吗&#xff1f;但是这个问题的难点在于&#xff0c;只有某些数字是可以…

汽车感性负载-智能高边钳位能量计算

随着汽车电子技术的发展&#xff0c;新的电子电气架构下&#xff0c;越来越多的执行部件在车身出现&#xff0c;比如电磁阀、风机、水泵、油泵、雨刮继电器等常用的执行器&#xff0c; 它们一般都表现为感性特点。驱动这些负载的最简单和最常见的方法是将它们连接到高边侧开关(…

量化交易学习笔记02:双均线策略

双均线策略示例 个股&#xff1a;中国平安 回测日期&#xff1a;2022-5-1至2023-5-1 短均线&#xff1a;5天 长无线&#xff1a;10天 代码&#xff1a; def initialize(context):# 初始化此策略# 设置我们要操作的股票池, 这里我们只操作一支股票# """标的&qu…

利用余弦相似度在大量文章中找出抄袭的文章

我前面的2篇文章分别讲了如果利用余弦相似度来判断2篇文章的相似度&#xff0c;来确定文章是否存在抄袭&#xff0c;和余弦相似度的原理&#xff0c;即余弦相似度到底是怎么来判断文章的相似性高低的等等。这一篇再说下&#xff0c;对于文章字数多和大量文章时&#xff0c;如果…

在 Kaggle 中绘制中文乱码解决

在 Kaggle 中绘制中文时&#xff0c;需要设置 Matplotlib 的字体&#xff0c;否则中文会显示为乱码。可以使用 SimHei&#xff08;黑体&#xff09;或 Microsoft YaHei&#xff08;微软雅黑&#xff09;。 解决方案 使用 matplotlib 设置中文字体在 Kaggle 安装 SimHei 字体 …

在 Ubuntu 服务器上使用宝塔面板搭建博客

&#x1f4cc; 介绍 在本教程中&#xff0c;我们将介绍如何在 Ubuntu 服务器 上安装 宝塔面板&#xff0c;并使用 Nginx PHP MySQL 搭建一个博客&#xff08;如 WordPress&#xff09;。 主要步骤包括&#xff1a; 安装宝塔面板配置 Nginx PHP MySQL绑定域名与 SSL 证书…

Linux线程

1.线程概念 在一个程序里的一个执行路线就叫做线程(thread)&#xff0c;更准确定义&#xff1a;线程是一个进程内部的控制序列 进程至少有一个执行路线&#xff0c;线程在进程内部运行&#xff0c;本质是在进程地址空间内运行&#xff0c;在Linux系统中&#xff0c;CPU眼中&a…

【TI MSPM0】GPIO学习

一、文件样例查找 以GPIO软件轮询为例 下面的四个文件夹分别为不同开发环境提供支持 二、工程导入 1.点击file-点击import project 2.点击browse 3.找到对应的文件打开&#xff0c;选择 推荐使用ticlang,能够提供更加优化的效率 点击finish 三、工程学习 1.readme 文件 &a…

二叉树的基本操作与实现:C语言深度剖析

目录 代码整体框架 1. #define _CRT_SECURE_NO_WARNINGS 2. 头文件引入 3. typedef int BTtype; 4. 二叉树节点结构体定义 二叉树的创建 1. BuyNode 函数 2. CreatNode 函数 二叉树的遍历 前序遍历 中序遍历 后序遍历 二叉树属性的计算 节点个…

深入解析 Latent Diffusion Model(潜在扩散模型,LDMs)(代码实现)

深入解析 Latent Diffusion Model&#xff1a;从传统 Diffusion Model 到高效图像生成的进化 近年来&#xff0c;生成模型在图像合成领域取得了显著进展&#xff0c;其中 Diffusion Model&#xff08;扩散模型&#xff0c;DMs&#xff09;以其出色的生成质量和理论上的稳健性逐…

线性回归原理推导与应用(五):波士顿房价预测实战

波士顿房价是一个非常经典的多元线性回归入门案例数据集。波士顿房价预测数据集包含了可能会影响房价的十三个因素&#xff0c;并给出了实际的房价&#xff08;单位为万美元&#xff09; 波士顿房价数据集数据集下载地址&#xff1a;https://www.kaggle.com/datasets/altavish…

基于CATIA二次开发的低音炮腔体容积精准计算技术详解

一、功能概述 本工具通过PySide6与CATIA V5深度集成&#xff0c;实现了低音炮上下腔体内体积的自动化测量系统。系统采用三维实体建模法进行容积计算&#xff0c;相较于传统手工计算方式&#xff0c;精度提升可达0.5%。主要功能模块包括&#xff1a; 壳体特征自动识别动态草图…

向量数据库原理及选型

向量数据库 什么是向量什么是向量数据库原理应用场景 向量数据库的选型主流向量数据库介绍向量数据库对比主流向量数据库对比表 选型建议 什么是向量 向量是一组有序的数值&#xff0c;表示在多维空间中的位置或方向。向量通常用一个列或行的数字集合来表示&#xff0c;这些数…

IE代理切换器v1.2免费版

虽然IE浏览器已经过时了&#xff0c;但很多其他浏览器&#xff0c;比如谷歌浏览器的代理服务器设置&#xff0c;都还是基于IE浏览器来进行设置的&#xff0c;如果你的工作场景需要切换不同的代理服务器来访问网络&#xff0c;那这款工具适合你&#xff0c;目前该工具可以实现IE…

模运算的艺术:从基础到高阶的算法竞赛应用

在算法竞赛中&#xff0c;模运算&#xff08;取模运算&#xff09;是一个非常重要的概念&#xff0c;尤其在处理大数、防止溢出、以及解决与周期性相关的问题时。C 中的模运算使用 % 运算符&#xff0c;但它的行为和使用场景需要特别注意。 1. 模运算的基本概念 模运算是指求一…

SpringBoot前后端不分离,前端如何解析后端返回html所携带的参数

有一个SpringBoot实现的前后端不分离项目&#xff0c;当前端跳转某个界面时&#xff0c;比如下面的菜单树按钮&#xff0c;后端在返回页面menuTree.html时&#xff0c;还携带了一个参数角色roleId&#xff0c;以便打开菜单树&#xff0c;还要根据这个角色查询对应的分配授权的菜…

操作系统八股文整理(一)

操作系统八股文整理 一、进程和线程的区别二、进程与线程的切换过程一、进程切换进程切换的步骤&#xff1a; 二、线程切换线程切换的步骤&#xff1a; 三、进程切换与线程切换的对比四、上下文切换的优化 三、系统调用一、系统调用的触发二、从用户空间切换到内核空间三、执行…

卷积神经网络(CNN)之 EfficientNet

在深度学习领域&#xff0c;模型的计算效率与性能之间的平衡一直是一个核心挑战。随着卷积神经网络&#xff08;CNN&#xff09;在图像分类、目标检测等任务中取得显著成果&#xff0c;模型的复杂度和计算需求也急剧增加。2019年&#xff0c;Google Research 提出的 EfficientN…