最近在训练模型时出了问题,需要记录训练时各层的梯度,所以想着每次miniBatch梯度计算后,就将梯度写入csv文件中。
1、分析
首先,我们能够轻松拿到梯度,格式如:{name:value, name1:value1, …},而每次梯度更新后都能拿到,name也就是从模型头到模型尾每层的名字。所以每次梯度更新都是keys一样,但是value不一样。
获取梯度部分的代码如下:
for name, parms in model.named_parameters():
try: # 某些层没有梯度,mean计算会异常
grad_dict.update({name: float(parms.grad.mean().detach().cpu().numpy())})
except:
grad_dict.update({name: "None"})
得到的grad_dict如下图
2、写入csv
这里主要使用 to_csv() 方法将 DataFrame 存储为 csv 文件。
所以首先将dictionary转换为DataFrame:
df_data = pd.DataFrame(data=[grad_dict], index=[index])
- 因为一个dictionary在csv中就是一行,而我可以一次转换多行,所以本质上data是一个可迭代的对象(虽然dictionary也可以,但是为了方便理解,直接按可迭代类型处理)
- 而index就是为data中多行数据执行序号(如果不指定则按顺序指定)。
然后将DataFrame写入csv文件中:
df_data.to_csv(csv_path, mode='a', header=False)
- csv_path为csv文件路径,没有则会自动创建。
- mode默认为’w’,'a’表示追加模式。
- header表示是否写入head(默认为True),如果我们是追加则不希望再次写入head,所以除了第一次需要写入,后面都不需要了(可以判断csv_path是否存在来判断是否是第一次写入)。
3、总结
首先我们通过named_parameters()函数来获取每层名字和梯度值,构建成字典,然后将字典转为DataFrame,通过to_csv()函数写入csv文件。
实际上如果要记录其他比如每层的权重值,也可以通过该方法。