chaos
#Python
#深度学习
引言 在模型训练时,每个Batch反向传播完成后我们需要手动清除计算图上本次迭代的所有梯度 在阅读不同的代码时,总能看到不同的清空代码: model.zero_grad() optimizer.zero_grad() 正文 上述两种梯度清空的方式均有效,区别在于起作用的范围不同 model.zero_grad() 此时mdoel包含的所有参数上的梯度均被清空 optimizer.zero_grad() 此时该优化器中负责更新的模型参数上的梯度被清空,即不一定是全部的梯度被清空 若模型训练过程中只有一个优化器,即优化器构造时使用 optimizer = optim.Optimiers(model.parameters(), lr=args.lr) 此时上述两种梯度清空方式完全等价 总结 两种不同的梯度清零方式在多数场景下基本等价,其区别在于作用范围不同 对于多任务训练、多优化器的训练中,需要根据具体训练策略的不同对参数梯度进行不同作用范围的清空
chaos
#Python
#深度学习
需求 对基于pytorch的深度学习模型进行多卡训练以加速训练过程 由于显卡版本过于老旧,安装配置NCCL工程量过于庞大,希望使用简单的pytorch代码实现单机多卡训练,不考虑多机多卡的显卡通信 训练完成后保存的checkpoint需要能够在任何设备上进行加载、推理 实现 训练 pytorch提供了简单的单机多卡训练api,只需要在初始化模型之后执行下列语句将模型复制到多卡上 # initiate multi-gpu training model = nn.DataParallel(model, device_ids=<ids of the gpus you want to use>) 其他操作与单卡训练完全一致 加载checkpoint 上述操作后保存的checkpoint如果按照常规方法直接进行加载会报错 RuntimeError: Error(s) in loading state_dict for <ModelName>: Missing key(s) in state_dict:... debug遍历后发现其实其状态字典是完全一致的,只是因为我们在训练过程中将模型定义为了多卡并行模型。这里只需要按照训练过程中转换为多卡模型的代码初始化当前模型结构即可,即执行: # initiate multi-gpu training model = nn.DataParallel(model, device_ids=<ids of the gpus you want to use>) 其他操作与征程推理完全一致,若不想使用多卡/只想使用cpu,只需要按照常规将device = torch.device("<cpu/cuda:id>")即可 Note:查阅资料过程中发现有解答建议使用参数强行忽略模型加载的错误torch.load(<checkpoint>, strict=False),经测试,这样加载的模型啥也不是…不知道为什么pytorch官方要提供这个接口
chaos
#Python
#深度学习
背景 之前介绍过Pytoch的单机多卡训练,当时采用的是内置的nn.DataParallel()方法 经过单机多卡训练的模型保存checkpoint之后再次加载需要同样使用DP()对模型进行封装之后才能正常加载,否则会报错状态词典的键值对不上 原因 经过DP()封装之后的模型,其状态词典分别添加了module.的前缀,例如原参数为hr_branch.conv_hr.1.layers.0.weight,封装之后变成了module.hr_branch.conv_hr.1.layers.0.weight。 解决方案 在加载状态词典之前将该前缀进行替换,得到纯净的状态词典,则不再需要重新对模型进行DP()封装 ckp_state_dict = torch.load(args.ckp, map_location=torch.device("cpu"))["model"] ckp_state = {} for k, v in ckp_state_dict.items(): k = k.replace("module.", "") ckp_state[k] = v 参考 文章
chaos
#深度学习
#System
#Linux
背景 NVIDIA-container-runtime是在docker容器中映射本机显卡必备的运行时 NVIDIA推出该工具之后搭配新版本的docker就不需要使用单独版本的docker启动支持显卡的容器 开始动手 添加安装源 官网比较难进,酌情查看
Debian-based distributions Debian/Ubuntu/…
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \ sudo apt-key add - distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \ sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list sudo apt-get update RHEL-based distributions CentOS/Fedora/Oracle/…
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.repo | \ sudo tee /etc/yum.repos.d/nvidia-container-runtime.repo 更新密钥 安装源来自于nvidia官网,可能会有些慢
Debian-based distributions curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \ sudo apt-key add - RHEL-based distributions DIST=$(sed -n 's/releasever=//p' /etc/yum.conf) DIST=${DIST:-$(. /etc/os-release; echo $VERSION_ID)} sudo rpm -e gpg-pubkey-f796ecb0 sudo gpg --homedir /var/lib/yum/repos/$(uname -m)/$DIST/nvidia-container-runtime/gpgdir --delete-key f796ecb0 安装 安装源来自于nvidia官网,可能会有些慢
chaos
#Python
#深度学习
几个概念 预训练 自训练 自监督学习 半监督学习 监督学习 无监督学习 区分 预训练 广义上讲:是对一个模型进行“预先训练”,以完成后续的下游任务 狭义上讲(更常用):在大规模无标注语料上,用自监督的方式训练模型 自训练 常应用于CV领域 有一个Teacher模型$M_{teacher}$和一个Student模型$M_{student}$,首先在标注数据上训练$M_{teacher}$,然后用它对大规模无标注数据进行标注,把得到的结果(与少量有标签数据混合)当做伪标注数据去训练$M_{student}$ 使用少量的标记数据和大量的未标记数据对模型进行联合训练 预训练与自训练是同级概念,其中分别可以与“监督/半监督/无监督/自监督”进行组合 监督与无监督 无监督的典型任务是聚类算法 半监督 没有太多意义的一个概念 其中的代表即自训练,甚至基本等同 自监督 是狭义上“预训练”的实现方法 与完全不受监督的设置相比,自监督学习使用数据集本身的信息来构造伪标签 是一种具有监督形式的特殊形式的非监督学习方法