PyTorch Tensor Ops
Tensor
- 直接赋值其实两个变量是指向同一个内存地址的
- 需要两个一样值的,用 Variable(x.data.clone())
- clone是深拷贝,而一般的赋值传的是引用
- 而copy和”=”的区别其实在Python中
- 前者是建立新对象,后者是传一个引用
尺度变化
- 想要使用尺度变化,首先要清楚计算的Broadcast原理
- 本质,想象为一个先拓展到和另外一个一样大,再做逐点乘
- 成立条件: 每个对应维度大小要么相同,要么其中有一个是1,要么其中有一个不存在
- 如果x,y的维度不同,会优先给空着的维度补0
[3,2,4,4]*[2,4,1]
- 注意在这里,最低维y为1,x为4,可以,但是如果y的最低维为2就不行
- 对于每个维度.计算结果是xy中较大的那个
- 尽量避免使用Permute操作,比较费时间,如果是为了做broadcast还是使用更加直接的方式
- 一个比较好的例子: BN的mean是[c]但是输入参数是[N,c,w,h]我们需要将mean broadcast过去
- 将mean reshape为[1,c,1,1],再做加减法
mean.reshape([1,-1,1,1])
- 另外一种方式是将其拓展为 [c,1,1] ,然后再做
mean[:,None,None]
- 这种做法必须向后对齐,很神奇
- 将mean reshape为[1,c,1,1],再做加减法
- 一个比较好的例子: BN的mean是[c]但是输入参数是[N,c,w,h]我们需要将mean broadcast过去
- 当我想制作一个fake data的时候
[Batch, Channel, W, H]
- 拓展数据,使用
tensor.expand([1,1,3,3])
- 或者是使用
torch.stack([x,x,x], dim = 0)
- stack会直接新建一个维度,而cat则不会
- 比如
[1,2,2]
做一个torch.stack([x,x], dim = 2)
- stack
[1,2,2,2]
- cat
[1,2,4]
- stack
- 拓展数据,使用
- 对于一个正常的Tensor,需要做转置的时候用
x.T
,但是如果这个tensor只有1维度,比如torch.tensor([1.,2.,3.])
,对其做T得到的shape和原来一样- 这时候就可以用
x[:,None]
- 这时候就可以用
- 对于想要在For-loop中将一些Tensor给concat起来
- 可以先利用一个List将需要concat的存放,然后用
torch.stack(list, dim=0)
进行拼接 - 生成这个list可以用list comprehension来做
- 可以先利用一个List将需要concat的存放,然后用
- 在我的代码里使用inplace的方法
tensor.mul_()
和使用赋值的方法差距很大,原因不是那么知道!- inplace 和
x = ...
- ! Inplace的替换和赋值有区别,比如说都是对bn.weight赋值,用第二种方式相当于将bn层的weight指向了一个新的tensor,但是我们一开始加到optimizer中的还是原来那个Tensor,导致了新的参数没有被更新
- 注意inplace修改和替代的区别!这个坑经常会遇到!
- inplace 和
- 对于一个(300,)的tenso,其实本质上是一维的,第二维度可以是任意值,和(300,1)有本质的区别
Numpy Ops
- Cheat Sheet
- np中的topk,np中的argpartition(x,k)找到第k大的,并且将它按这个数分成两部分
random.randn()
返回的不是0到1,要0到1用np.random.uniform(0,1)
- 排序
pred_inds = np.argsort(predict_scores)[::-1]
- 转化为int(For indexing)
x.astype(int)
- 为了控制random,使用
random.seed(NUM)
注意每次执行这个,只能够对一次random操作生效,下一次就不生效 np.argwhere(arr == x)
来获得ind- 或者用这种方式: ``````
- 可以用
[:,None]
来代替转置 np.tile
创建多个副本