vscode 和jupyter notebook强大的调试功能详细分析

程序错误定位

如果报出exception,寻找输出在最下方且是自己项目内的错误位置
比如这里我们看最下面的的一个NullPointerException,标蓝文件定位说明该错误出自我们自己的项目代码,点他定位错误
![在这里插入图片描述](https://img-blog.csdnimg.cn/022d6b8b55ca47c69da8846fd9591e11.png在这里插入图片描述

他提示我自己项目内的类jdbcutils中出现了空指针异常
在这里插入图片描述
发现ips为空指针,因为没有将配置文件放在src下,导致配置找不到,所以为null,至此问题就解决了。

之所以为什么是找最下方的,因为在程序堆栈中报错都是从下向上报错,从控制台输出的越靠后,说明在程序堆栈越底部,说明越接近错误真实发生的地方

jupyter note book vscode 版提供了强大的调试功能,分为逐行调试和cell debug
本文章借鉴了https://blog.csdn.net/Nie_Quanxin/article/details/124239699,感谢这位仁兄的分享。

首先升级ipykernel,确保版本不低于6,这个基本每个环境新安装时都要先安装ipykernel,与pip更新一样为每个新建虚拟环境的必做选项。

pip install --upgrade ipykernel

逐行调试,左一,就是断点调试的简化版本,对cell中每一行进行调试
在这里插入图片描述

cell断点调试

在这里插入图片描述
cell断点调试功能非常强大,除了本cell的可以调试,还能进入其他cell的函数,或其他的py文件。
查看某个变量的值可以使用printf,或将其定义为变量

p1=np.sum(y)/m

鼠标放在变量上也能查看值,外带额外的信息
在这里插入图片描述
变量列表
在这里插入图片描述

断点调试按钮功能

在这里插入图片描述
1.继续按钮:程序快速跳转到下一个断点的位置
2.单步跳过按钮:执行一条语句,如果执行的语句是自定义的函数则直接得出结果,不进入函数(函数是自定义的函数才能进入)
3.单步调试,就是执行一条语句,相比于2不同在于如果该语句执行了函数则会进入函数,调到函数的代码进行一行行地执行。
4.单步跳出:如果在函数中就跳出当前函数,执行完在函数中当前语句后面的所有代码,如果在全局就跳出当前的cell,执行完在cell内在该语句后面的所有代码。
5.重启:重新从头进行调试
6.断开:停止调试

经常会出现的bug

1.在跨cell调试的时候会出现跳入函数时会报错
无法加载源“c:\Users\xx\AppData\Local\Temp\ipykernel_9776\3566846540.py”: source unavailable。
这是因为修改了函数的代码,但是没有重新运行该函数所在的单元导致的错误,正确的方法是要每次修改函数后都应该重新运行该函数所在的单元,这是使用jupyter的一个良好的习惯,每次修改一个cell的代码都要重新执行该cell。

2.调试小箭头消失
在这里插入图片描述
这个重启内核就好了
在这里插入图片描述

vscode编辑实用快捷键

参考vscode实用快捷键
实用快捷键

快捷键实战(可不看)
  1. 将class定义如class PartNormalDataset(Dataset):去掉
  2. ctrl + D实现批量修改,将函数引入的变量全变为全局,ctrl + F里面的局部替换查找在jupyter notebook里不起作用,相当于局部查找操作

源:

def __init__(self,root = './data/shapenetcore_partanno_segmentation_benchmark_v0_normal', npoints=2500, split='train', class_choice=None, normal_channel=False):

修改后
![在这里插入图片描述](https://img-blog.csdnimg.cn/4f550ee8f88246628f7db4734da0c39d.png
3.使用⇧ shift + ⌃ ctrl + L,将所有self.删去
这个就是cell内全局查找的操作,删除任何位置匹配的,包括注释的,函数内的

4.注:实用快捷键F2,可以修改所有引用位置相同,且名字相同的位置

a=[]
a3=a
a=a
def f():
    a=1

修改外面的a话只有函数外的且叫a的能被修改

a1=[]
a3=a1
a1=a1
def f():
    a=1

vscode自带的调试功能

1.四个额外的调试选项

可以通过右击来得到
在这里插入图片描述

1.单步执行目标:
目前没有发现和上面按钮“继续”有什么区别。
2.跳转到光标处
可以直接跳转到该地点,向前跳转则是直接跳过去,放弃执行中间的所有代码。向后跳转并不会时光回溯,已经做过的操作和得到的变量也不会因为跳到前面的代码而撤销,所有结果都会保留下来。
3.跳转到光标:加强版的断点等于是,只能向前跳,相对于2的向前跳不同的是他会做完中间的代码。
4.内联断点:仅当执行到达与内联断点关联的列时,才会命中内联断点。这在调试在一行中包含多个语句的缩小代码时特别有用。比如for循环,短路运算符等一行代码包含多个表达式时会特别有用。比如下面的例子:在这里插入图片描述

2.添加高级断点

高级断点
在这里插入图片描述
可以在某个条件达到时,或某条指令执行到一定次数引起中断,也可以在debug这条指令时输出日志,对于条件循环中非常好用

3.调试控制台

在这里插入图片描述
可以在这里在调试中查看所有的变量,也可以更改变量的值之类的,非常的万能,尤其是在封装非常好的代码中查看变量很方便,并且是根据当前debug作用域在动态变化的,不会查看到作用域之外或已被释放的变量,搜寻变量的规则与正常程序是一致的。

深度学习调试的两种方式

1.py 文件debug调试

优点:可以使用跳转到光标,ipynb文件则不行,跳转到光标可以实现代码的回退,如果使用得当
有时ipynb会报显存不足,在py则没有这个
缺点:如果修改代码,要重新执行上面所有操作,上面有比较耗时的操作就很麻烦

2.ipynb文件debug调试

优点:随时查看,随时调试
缺点:对封装性强的比如函数,类调试没有优势
麻烦,最终还要导出py文件作为模块

最后综上还是选择py 文件debug调试比较好,有耗时操作比如训练可以将其注释掉,然后执行其他代码也不影响使用

代码复现标准

**1.dataset:**最后输出的值要是符合要求的
**2.网络:**使用torchinfo要和源代码有相同的info
3.训练:
如果有源码

SEED = 0
torch.manual_seed(SEED)
torch.cuda.manual_seed(SEED)
np.random.seed(SEED)

1.可使用随机种子来使结果可以复现
2.调试看看各个参数结果正不正常
3.指标是否合理,比如某些ious为0,非常低,我要看看是否是合理的,经验证是合理的,说明程序没问题
4.直接看训练几轮看看正确率效果是否有大幅提升(最省事)
在这里插入图片描述

其他小知识

1.调试循环运行速度总是比非调试情况下的运行速度慢,所以要比较运行速度需要在非调试状态下进行比较

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值