python :invalid value encountered in true_divide。(除法遇到无效值)

博客围绕根据历年预算费用求增长率的需求展开,采用matrix矩阵实现计算时会报错。针对此问题给出两种解决方法,一是忽略警告,二是结合预算实际情况,即过去为0表示无此项,现在为0表示无需此项进行具体分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设有这样一个需求(不是假设,是真的):
给出历年的预算费用,求增长率。
为方便后续计算,用matrix矩阵实现。

# 历史数据
his=matrix([[30000., 20000., 10000.,  1000.],
        [    0.,     0.,     0.,  9000.],
        [    0.,     0., 10000.,     0.],
        [    0., 10000., 10000.,  1000.],
        [    0.,     0.,     0.,  9000.]])
# 假装是现在的数据
cur=his*1.24
rate = (cur-his)/his*100

不出意外,这个代码会报:
RuntimeWarning: invalid value encountered in true_divide
“”"Entry point for launching an IPython kernel.

遇到问题解决问题,解决方法有很多。
法1:
忽略warn

np.seterr(divide='ignore',invalid='ignore')

法2:
具体问题具体分析,这里是预算。没有倒贴钱的情况,过去为0的意思是过去没有这项,现在为0是现在不需要了。

cur[cur==0]=nan

结果:

(cur-his)/his*100
matrix([[24., 24., 24., 24.],
        [nan, nan, nan, 24.],
        [nan, nan, 24., nan],
        [nan, 24., 24., 24.],
        [nan, nan, nan, 24.]])

``` class GradCAMpp: def __init__(self, model, target_layer): self.model = model self.target_layer = target_layer self.activations = None self.gradients = None # 注册前向传播和反向传播钩子 target_layer.register_forward_hook(self.save_activation) target_layer.register_backward_hook(self.save_gradient) def save_activation(self, module, input, output): self.activations = output.detach() def save_gradient(self, module, grad_input, grad_output): self.gradients = grad_output[0].detach() def __call__(self, input_tensor, class_idx=None): # 前向传播 self.model.eval() output = self.model(input_tensor) if class_idx is None: class_idx = output.argmax(dim=1) # 反向传播 self.model.zero_grad() one_hot = torch.zeros_like(output) one_hot[0][class_idx] = 1.0 output.backward(gradient=one_hot) # 计算权重 grad = self.gradients[0].numpy() act = self.activations[0].numpy() # Grad-CAM++核心计算 grad_power = grad ** 2 grad_power_times_act = grad_power * act weights = grad_power_times_act / (2 * grad_power_times_act + np.sum(act * grad_power_times_act, axis=(1,2), keepdims=True)) weights = np.sum(weights, axis=(1,2)) # 生成热力图 cam = np.zeros(act.shape[1:], dtype=np.float32) for i, w in enumerate(weights): cam += w * act[i] cam = np.maximum(cam, 0) cam = cv2.resize(cam, (224, 224)) cam = cam - np.min(cam) cam = cam / np.max(cam) return cam # 获取目标层(使用最后一个卷积层) target_layer = model.conv2 # 创建Grad-CAM++实例 gradcam_pp = GradCAMpp(model, target_layer) # 反标准化函数 def denormalize(tensor): mean = torch.tensor([0.5, 0.5, 0.5]) std = torch.tensor([0.5, 0.5, 0.5]) return tensor * std.view(3, 1, 1) + mean.view(3, 1, 1) # 可视化示例 num_samples = 3 # 可视化样本数量 fig, axes = plt.subplots(num_samples, 3, figsize=(15, 10)) for idx in range(num_samples): # 获取测试样本 img, label = test_dataset[idx] input_tensor = img.unsqueeze(0) # 获取预测结果 with torch.no_grad(): output = model(input_tensor) pred_class = output.argmax().item() # 生成热力图 cam = gradcam_pp(input_tensor, pred_class) # 处理原始图像 img_denorm = denormalize(img).permute(1, 2, 0).numpy() # 绘制结果 axes[idx, 0].imshow(img_denorm) axes[idx, 0].axis('off') axes[idx, 0].set_title(f'Original (True: {full_dataset.classes[label]})') axes[idx, 1].imshow(cam, cmap='jet') axes[idx, 1].axis('off') axes[idx, 1].set_title(f'Grad-CAM++ Heatmap (Pred: {full_dataset.classes[pred_class]})') axes[idx, 2].imshow(img_denorm) axes[idx, 2].imshow(cam, cmap='jet', alpha=0.5) axes[idx, 2].axis('off') axes[idx, 2].set_title('Overlay') plt.tight_layout() plt.show()```Warning (from warnings module): File "C:\Users\29930\AppData\Local\Programs\Python\Python311\Lib\site-packages\torch\nn\modules\module.py", line 1830 self._maybe_warn_non_full_backward_hook(args, result, grad_fn) FutureWarning: Using a non-full backward hook when the forward contains multiple autograd Nodes is deprecated and will be removed in future versions. This hook will be missing some grad_input. Please use register_full_backward_hook to get the documented behavior. Warning (from warnings module): File "D:/正式建模/CNN+++.py", line 150 weights = grad_power_times_act / (2 * grad_power_times_act + RuntimeWarning: invalid value encountered in divide
最新发布
03-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值