从tensorflow转Pytorch的笔记(gather的用法,待补充...)
https://blog.csdn.net/CHNguoshiwushuang/article/details/80721675
tensorflow的mnist改写成pytorch
https://blog.csdn.net/victoriaw/article/details/72354307 PyTorch之示例——MNIST
https://blog.csdn.net/caichao08/article/details/78997033
神经网络的pytorch实现-基于MNIST数据集
https://blog.csdn.net/sparta_117/article/details/66965760 使用Tensorflow和MNIST识别自己手写的数字
从tensorflow转过来学习Pytorch,对比一下二者的不同:
为什么要转Pytorch?
- 更加灵活(使用tensorflow能够找到很多别人的代码,使用Pytorch更加容易实现自己的想法),支持Python化(也就是说基本可以当numpy使用)
- 速度更快
- 代码简洁容易上手(0.4版本后没有
Variable
之类的定义,只有一个tensor的定义,参数requires_grad=True
可以自动求微分,替代Variable)
细节上一些发现
-
以下划线结束的函数是inplace操作,会修改自身的值。
tensorA.add_(tensorB) # 会改变tensorA的值
-
tensor和numpy很方便互转且内存共享。
numpyA = tensorA.numpy() # Tensor -> Numpy tensorA = torch.from_numpy(numpyA) # Numpy -> Tensor
-
只有一个元素的tensor 可以调用
tensor.item()
直接取元素值。 -
tensor.backward()
反向传播之后,tensor.grad
梯度值是累加的,在使用反向传播之前使用zero_grad()
把梯度清0。 -
view()
有两个作用,一是改变tensor的shape,二是让新tensor和原tensor共享内存,相当于深拷贝detach()
,而普通的=
赋值方法不会共享内存。 -
resize()
是另一种可用来调整size的方法,但与view()
不同,如果新维度超过了原维度,会自动分配新的内存空间。 -
增删维度,
None
类似于np.newaxis()
tensor.unsqueeze(n) # 在第n个维度上增加1个维度 tensor.squeeze(n) # 在第n个维度上压缩 tensor.squeeze(1) # 压缩所有维数为1的维度
-
contiguous()
为tensor分配整块的内存,有些tensor并不是占用一整块内存,而是由不同的数据块组成,而tensor的view()操作依赖于内存是整块的。 -
gather()
??? ??? -
非叶子节点的梯度计算完之后即被清空,可以使用
autograd.grad
或hook
方法获取非叶子节点的值
常用的库
- 神经网络
torch.nn
nn.Module
nn.functional
nn.Sequential