Python 踩坑记录

name ‘xrange’ is not defined

在 Python2 中, xrange 和 range 的功能想不多, 不同的是 xrange 生成的是一个生成器, 而 range 生成的是一个 list 对象, 在要生成很大的数字序列时, xrange 的性能更好些

在 Python3 中, 取消了 range 函数, 而把 xrange 函数重命名为了 range 函数, 因此, 可以使用xrange = range来令python3兼容python2

plt.title: ‘str’ object is not callable

在交互式对话框中(如 jupyter notebook), 如果之前输入了 plt.title = "image", 那么 plt.title 就不再是一个函数了, 所以会报错. 解决方法是重启 kernel

no module named ‘torch.utils.data.DataLoader’

导入时, import 是针对文件而言的, 如果想要导入文件中的某个对象或类, 需要使用 from... import ... 语法, 如下所示:

1
2
3
import torch.utils.data as data # data.py

from torch.utils.data import DataLoader # class DataLoader

takes 0 positional arguments but 1 was given

在类中的函数, 会自动传递self参数, 因此在定义函数的时候不要忘了加上该参数, 否则会在调用时显示参数数量不匹配的错误.

python 的赋值运算符

python 对于基本类型的数据, 使用=不会对原来的变量造成影响, 拷贝后的变量无关联:

1
2
3
4
5
a = 10
b = a
b = 20
print(a) # 10
print(b) # 20

python 对于对象类型的数据, 使用=是浅拷贝, 拷贝后的对象指向同一个实例:

1
2
3
4
5
6
7
8
9
10
class A(object):
def __init__(self, item):
super(A, self).__init__()
self.item = item

a = A(10)
b = a
b.item = 20
print(a.item) # 20
print(b.item) # 20

TypeError: list indices must be integers or slices, not tuple

列表类型的数据无法进行超过一维以上的划分, 如下所示:

1
2
a[:5] # 正确
a[:, :5] # 报错

因此, 在因此二维以上的操作时, 应该现将其转换成numpy数组, 在进行划分, 如下所示:

1
2
a = np.array(a)
a[:, :5] # 正确

TypeError: Cannot cast ufunc subtract output from dtype(‘int64’) to dtype(‘uint8’) with casting rule ‘same_kind’

在进行强制类型转换时, 不能向上转, 只能向下转

detach() 和 data 的区别

https://blog.csdn.net/dss_dssssd/article/details/83818181

tensor.datatensor.detach()的功能都是获取和tensor相同的数据, 并且当对获取到的值进行修改时, 原来的tensor也会被修改. 它们之间的区别在于data并不会将修改记录到tensor的加入到历史中, 而.detach()会将修改记录到历史中, 这样, 当在进行反向传播时, 如果通过.detach()对原始数据进行了修改, 程序就会报错, 而data不会提示任何错误, 这样存在很大的风险, 具体看下面代码示例.

torch.data

1
2
3
4
5
6
7
8
9
10
11
12
>>> a = torch.tensor([1,2,3.], requires_grad =True)
>>> out = a.sigmoid()
>>> c = out.data
>>> c.zero_()
tensor([ 0., 0., 0.])

>>> out # out的数值被c.zero_()修改
tensor([ 0., 0., 0.])

>>> out.sum().backward() # 反向传播
>>> a.grad # 这个结果很严重的错误,因为out已经改变了, 但是程序没有报错, 存在隐患
tensor([ 0., 0., 0.])

torch.detach()

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> a = torch.tensor([1,2,3.], requires_grad =True)
>>> out = a.sigmoid()
>>> c = out.detach()
>>> c.zero_()
tensor([ 0., 0., 0.])

>>> out # out的值被c.zero_()修改 !!
tensor([ 0., 0., 0.])

# 编译错误, 避免了安全隐患
>>> out.sum().backward() # 需要原来out得值,但是已经被c.zero_()覆盖了,结果报错
RuntimeError: one of the variables needed for gradient
computation has been modified by an