最近大半个月都在进行论文3D Hand Shape and Pose from Images in the Wild的复现。因此将近日在使用Numpy, Torch, cv, 以及训练中遇到的问题小结一下。
文章目录
1. pytorch
1.1 RuntimeError: expected dtype Double but got dtype Float
首先要明确PyTorch的数据类型。
- FloatTensor的数据类型是torch.float32
- DoubleTensor的数据类型是torch.float64 (没错,double也是一种float, 但是64位)
- LongTensor 的数据类型是torch.int64
- IntTensor的数据类型是torch.int32
因此这里的问题就是:在训练网络的过程中由于类型的冲突导致这种错误,主要是模型内部参数和输入类型不一致所导致的。主要有两个部分需要注意到:1.自己定义的变量要设置为一种数据类型;2.网络内部的变量类型也要统一。
Tensor间的类型转换:
1. TensorA.type(torch.float32)
2. torch.float()
1.2 CUDA ERROR: device-side assert triggered at
解决思路:CUDA(GPU) 的报错一般位置不准确,报错信息也不详细。**将数据和网络转移到cpu中,**再次运行,就可以看到真正的错误原因。
如果使用.cpu()后仍然报错,说明真正出错的地方可能在使用.cpu()的前面,将.cpu()前移。
2. train network
3. Numpy
3.1 向量的单位向量
求向量的单位向量这一操作在生成旋转向量时会用到。通过np.linalg.norm(求范数)实现
linalg=linear(线性)+algebra(代数),norm则表示范数。
x_norm=np.linalg.norm(x, ord=None, axis=None, keepdims=False)
参数意义具体见链接:
np.linalg.norm(求范数)
3.2 维度的压缩与扩展
压缩:
numpy.squeeze(a, axis=None)
3.3 np.array索引
3.3.1 切片索引
简单,不赘述
3.3.2 数组做索引某一维
一维数组做索引,用索引到的元素代替数组的原元素。
如果索引数组是一维,那么将一维数组的每个元素替代为被索引数组的第一维。
a = np.random.randint(0,5,(3,4))
a
array([[3, 0, 2, 3],
[2, 1, 0, 1],
[3, 4, 3, 3]])
b = [0,2]
a[b]
array([[3, 0, 2, 3],
[3, 4, 3, 3]])
a[b].shape
(2, 4)
如果要对array的第n维进行数组索引,可以采用切片+数组索引的办法。
如要对第一维进行数组索引
a[:, [0,1]]
3.3.3 数组做索引多维
a[b, c] # b,c形状必须完全相同,且a的ndim大于等于2
# 加入b,c shape为2x2
# 则结果为
# [[a[b00, c00], a[b01, c01],
[a[b10, c10], a[b11, c11]]
d = [[0,1], [0,2]]
a
array([[3, 0, 2, 3],
[2, 1, 0, 1],
[3, 4, 3, 3]])
a[d, d]
array([[3, 1],
[3, 3]])
3.3.4 使用布尔值数组进行索引
使用布尔索引最自然的方式是布尔值数组与原数组有相同的形状
3.4 Numpy数据类型转换
a = a.sdtype(np.float32)
3.5 numpy与torch的相互转化
torch_arr = torch.from_numpy(np_arr)
np_arr = torch_arr.numpy()
4. cv
4.1 图片缩放
cv2.resize(dst, interpolation=cv2.INTER_LINEAR)
这里的INTER_LINEAR指的是双线性插值。
4.2 旋转向量与旋转矩阵
旋转向量:3维向量,其单位向量表示旋转轴,其模大小表示旋转角度,范围在[0, pi]. 要表示反方向旋转,只需要取单位向量维相反方向。
旋转矩阵:3x3矩阵,由线性代数可知,与3x3矩阵相乘可以表示空间中的旋转。
两者的转换:罗德里格斯旋转公式。
在cv2中的接口: cv2.Rodrigues()