PyTorch(总)---PyTorch遇到令人迷人的BUG与记录
BUG1
在使用NLLLoss()激活函数时,NLLLoss用来做n类分类的,一般最后一层网络为LogSoftmax,如果其他的则需要使用CrossEntropyLoss。其使用格式为:loss(m(input), target),其中input为2DTensor大小为(minibatch,n),target为真实分类的标签。
如果输入的input类型为torch.cuda.FloatTensor,target类型为torch.cuda.IntTensor,则会出现如下错误:
因此需要保证target类型为torch.cuda.LongTensor,需要在数据读取的迭代其中把target的类型转换为int64位的:target = target.astype(np.int64),这样,输出的target类型为torch.cuda.LongTensor。(或者在使用前使用Tensor.type(torch.LongTensor)
进行转换)。
为了说明pytorch中numpy和toch的转换关系,测试如下:
首先输入int32的numpy数组转换为torch,得到的IntTensor类型
如果输入的为int64的numpy,得到LongTensor类型:
如果把int32的数组转换为LongTensor,则会出错:
如果把int64的数组转换为LongTensor,正常:
PS: 2017/8/8(奇怪,在使用binary_cross_entropy
进行分类时又要求类型为FloatTensor
类型,简直够了)
BUG2
同样是NLLLoss()使用时的问题。网络传播都正常,但是在计算loss时出现如下错误: RuntimeError: cuda runtime error (59) : device-side assert triggered at /home/loop/pytorch-master/torch/lib/THC/generic/THCTensorMath.cu:15
断点调试发现数据类型出现如下变化:
我以为显卡除了问题,最后在pytoch#1204中发现一个人的标签中出现-1,发生了类似的错误:
而我的标签为1~10,最后把标签定义为1~9,解决这个问题。^_^!
BUG3
当使用torch.view()
时出现 RuntimeError: input is not contiguous at /home/loop/pytorch-master/torch/lib/TH/generic/THTensor.c:231
这个是由于浅拷贝出现的问题。
如下:定义初始化一个Tensor
值,并且对其进行维度交换,在进行Tensor.view()
操作时出现以上错误。
这是由于浅拷贝的原因,y
只是复制了x
的指针,x
改变,y
也要随之改变,如下:
可以使用tensor.contiguous()
解决:
BUG4
按照官网的方式编译PyTorch源码时出现:undefined reference to ... @GLIBCXX_3.4.21 (未定义的引用问题)
我的是出现在编译90%左右的broadcast_test附近出现的。问题估计是GCC的版本造成的,虽然GCC -v
显示的5.0,但是调用的库不是,需要执行:
conda install libgcc
然后python setup.py clean
重新生成即可解决问题
BUG5
使用Cross_entropy
损失函数时出现 RuntimeError: multi-target not supported at …
仔细看其参数说明:
input has to be a 2D Tensor of size batch x n. This criterion expects a class index (0 to nClasses-1) as the target for each value
of a 1D tensor of size n
其标签必须为0~n-1,而且必须为1维的,如果设置标签为[nx1]的,则也会出现以上错误。
NOTE1 共享参数问题
在tensorflow中有variable_scope
方法实现参数共享,也就是说对于2张图片,第二张训练时的权重参数与第一张图片所使用的相同,详见tf.variable_scope. 同样,在PyTorch则不存在这样的问题,因为PyTorch中使用的卷积(或者其他)层首先需要初始化,也就是需要建立一个实例,然后使用实例搭建网络,因此在多次使用这个实例时权重都是共享的。
NOTE2 torch.nn.Module.cuda 作用
之前看教程中在定义完网络后会进行:
现在才发现这个的作用,官方文档上写的是:Moves all model parameters and buffers to the GPU.
也就是在定义时并没有把weight
参数传入gpu中,在调用网络进行计算时,如果传入的数据为GPU数据,则会出现:tensors are on different GPUs 错误,因此使用torch.nn.Module.cuda
可以把定义的网络参数传入gpu中。
NOTE3 对同一网络连续两次对同一梯度求解(backward)
如果使用一个Variable
数据传入到网络,通过backward
求解其梯度值,然后在使用另一个Variable
传入网络,再次求解梯度值,其最终结果会怎么样呢?正如你所想得样,是两次梯度之和。测试代码如下:
定义一个一层的线性网络,并且其权重(weight)和偏置(bias)都初始化为0,在每次求解梯度后输出梯度值,其结果如下:
可以发现,在进行梯度求解前,没有梯度,在第一次计算后梯度为-1,第二次计算后为-2,如果在第一次求解后初始化梯度net.zero_grad()
,则来嗯次都是-1,则连续多次求解梯度为多次梯度之和。
NOTE4 pytorch自定义权重初始化
在上面的NOTE3中使用自定意的权重参数初始化,使用toch.nn.Module.apply()
对定义的网络参数进行初始化,首先定义一个权重初始化的函数,如果传入的类是所定义的网络,则对其权重进行in_place赋值。
如果对weight_init(m)
中的classname输出,可以发现有多个类:(因此需要判断是否为所定义的网络)
NOTE5 pytorch权重的更新
关于网络传递中网络的定义、loss计算、backpropogate的计算,update weight在Neural Networks有简单介绍,这里测试下。只要定义一个优化器(optimizer),实现了常见的优化算法(optimization algorithms),然后使用优化器和计算的梯度进行权重的更新。
在NOTE3中的代码后面增加如下(更新权重参数):
其运行结果为:
可见使用optimizer.step()
实现了网络权重的更新。(而且可以选择不同的更新方式,如:Adam、SGD等)
NOTE6 torch.autograd.backward()使用技巧
当计算多个梯度相加(相减)时,使用backward(torch.FloatTensor([-1]))
可以简单实现。
NOTE7 监控内存使用,防止内存泄漏memory leak
代码如下:
原文链接:http://blog.csdn.net/u011276025/article/details/73826562
- vsftpd搭建自己的ftp服务器
- Linux一键安装Transmission电影下载到服务器
- centos安装ab工具给网站进行压力测试
- ubuntu16.04安装mongodb教程
- linux压缩解压命令使用
- linux使用wc命令查看文件行数、字母、字节数命令
- 程序员偷偷深爱的 9 个不良编程习惯
- 低级程序员和高级程序员的区别
- Silverlight学习(二)
- Silverlight学习(三)
- ArcGIS for Android学习(一)
- Arcgis for Silverlight学习(一)
- ImageButton与Button
- RadioButton、CheckBox与ToggleButton
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- leetcode链表之删除链表的节点
- Windows 技术篇-通过注册表查找vc运行库所在位置实战演示,通过ProductCode查看vc++运行库安装位置
- Python 库安装问题-whl is not a supported wheel on this platform.原因及解决办法
- 安装Go运行环境
- Python 语法问题-module 'pip' has no attribute 'pep425tags',告诉你如何正确查看pip支持,32位、64位查看pip支持万能方法
- 使用matplotlib绘制3D图表
- 微服务的用户认证与授权杂谈(下)
- Python 库安装问题-用pip安装pyHook3报错,原因及解决办法
- 微服务的用户认证与授权杂谈(上)
- Python 技术篇-win32、amd64结尾的whl库该选哪个,如何查看python平台支持
- Python 基础篇-pip卸载python库方法,pip命令大全
- Python 技术篇-pip安装的python库缓存位置查看方法,如何查看python库源码
- Redis持久化 - RDB和AOF
- Python 技术篇-pip只下载python库不安装方法,pip命令大全
- Python 技术篇-将项目打包成whl文件,whl包的制作方法