>>> x.grad_fn.data
Traceback (most recent call last):File "<stdin>", line 1,in<module>
AttributeError:'NoneType'object has no attribute 'data'>>> x.grad_fn.data
Traceback (most recent call last):File "<stdin>", line 1,in<module>
AttributeError:'NoneType'object has no attribute 'data'
嘗試做反向傳播
>>> x.backward()
Traceback (most recent call last):File "<stdin>", line 1,in<module>File "C:\Users\sean\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\tensor.py", line 93,in backwardtorch.autograd.backward(self, gradient, retain_graph, create_graph)File "C:\Users\sean\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\autograd\__init__.py", line 84,in backwardgrad_tensors = _make_grads(tensors, grad_tensors)File "C:\Users\sean\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\autograd\__init__.py", line 28,in _make_gradsraise RuntimeError("grad can be implicitly created only for scalar outputs")
RuntimeError: grad can be implicitly created only for scalar outputs
意思很簡單,就是說,這里如果是做反向傳播,東西必須是標量的輸出。
對x求和
>>> y = x.sum()>>> y
tensor(4., grad_fn=<SumBackward0>)
關于y做反向傳播 有反向傳播的函數。
>>> y.backward()>>> y
tensor(4., grad_fn=<SumBackward0>)>>> y.grad
>>> y.grad_fn
<SumBackward0 object at 0x0000026BADBFF278>>>> a = y.backward()>>> a
>>> a ==NoneTrue
這時候再去檢查x
>>> x
tensor([[1.,1.],[1.,1.]], requires_grad=True)>>> x.grad
tensor([[2.,2.],[2.,2.]])>>> x.grad_fn
>>> a = Variable(torch.ones(2,2)*2, requires_grad=True)>>> a
tensor([[2.,2.],[2.,2.]], requires_grad=True)>>> y = a.sum()>>> a
tensor([[2.,2.],[2.,2.]], requires_grad=True)>>> y
tensor(8., grad_fn=<SumBackward0>)>>> y.backward()>>> a.grad
tensor([[1.,1.],[1.,1.]])
>>> a = torch.Tensor((2,3,4,5))>>> a
tensor([2.,3.,4.,5.])>>> a = torch.Tensor([2,3,4,5])>>> a
tensor([2.,3.,4.,5.])
不得不說,這其實跟numpy的array構造法類似的
>>> a = torch.Tensor(np.array([2,3,4,5]))>>> a
tensor([2.,3.,4.,5.])
直接Tensor創建(三)
用size的維度來做輸入
>>> a = torch.Tensor(1,2)>>> a
tensor([[0.0000,0.0000]])>>> a = torch.Tensor(3,2)>>> a
tensor([[0.0000,0.0000],[0.0000,0.0000],[0.0000,0.0000]])
構造全1的張量
>>> a = torch.ones(3,2)>>> a
tensor([[1.,1.],[1.,1.],[1.,1.]])>>> a = torch.ones((3,2))>>> a
tensor([[1.,1.],[1.,1.],[1.,1.]])>>> a = torch.ones([3,2])>>> a
tensor([[1.,1.],[1.,1.],[1.,1.]])>>> a = torch.ones(np.array((3,2)))
Traceback (most recent call last):File "<stdin>", line 1,in<module>
TypeError: ones(): argument 'size'(position 1) must be tuple of ints,not numpy.ndarray
>>>
除了numpy不能使用的,其他的上面提到的,都可以作為size
構造全0的張量
跟全1的一模一樣。
>>> a = torch.zeros(3,2)>>> a
tensor([[0.,0.],[0.,0.],[0.,0.]])>>> a = torch.zeros((3,2))>>> a
tensor([[0.,0.],[0.,0.],[0.,0.]])>>> a = torch.zeros([3,2])>>> a
tensor([[0.,0.],[0.,0.],[0.,0.]])>>> a = torch.zeros(np.array([3,2]))
Traceback (most recent call last):File "<stdin>", line 1,in<module>
TypeError: zeros(): argument 'size'(position 1) must be tuple of ints,not numpy.ndarray
>>> a = torch.zeros(1)>>> a
tensor([0.])>>> a = torch.zeros(2)>>> a
tensor([0.,0.])>>>
對角元全是1,其他都是0的矩陣 只能是方陣
>>> a = torch.eye(2)>>> a
tensor([[1.,0.],[0.,1.]])>>> a = torch.eye(1)>>> a
tensor([[1.]])>>> a = torch.eye(3)>>> a
tensor([[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]])>>> a = torch.eye(4)>>> a
tensor([[1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,0.,0.,1.]])>>> a = torch.eye((1,2))
Traceback (most recent call last):File "<stdin>", line 1,in<module>
TypeError: eye(): argument 'n'(position 1) must be int,nottuple
arange(s,e, step)
step:步長
>>> a = torch.arange(0,1,10)>>>1>>> a = torch.arange(0,10,1)>>> a
tensor([0,1,2,3,4,5,6,7,8,9])
linspace(s, e, steps)
steps:步數
steps:大于等于2
>>> a = torch.linspace(0,1,10)>>> a
tensor([0.0000,0.1111,0.2222,0.3333,0.4444,0.5556,0.6667,0.7778,0.8889,1.0000])>>> a = torch.linspace(0,10,1)
Traceback (most recent call last):File "<stdin>", line 1,in<module>
RuntimeError: invalid argument 3: invalid number of points at d:\build\pytorch\pytorch-0.4.1\aten\src\th\generic\thtensormath.cpp:4408>>> a = torch.linspace(0,10,2)>>> a
tensor([0.,10.])
rand(*size) 均勻分布 (類似的有randn標準正態分布)
>>> a = torch.rand(1)>>> a
tensor([0.5391])>>> a = torch.rand(1)>>> a
tensor([0.7884])>>> a = torch.rand(1,2)>>> a
tensor([[0.6491,0.8738]])>>> a = torch.rand(2,1)>>> a
tensor([[0.1860],[0.4988]])>>> a = torch.rand(2)>>> a
tensor([0.9654,0.6263])>>> a = torch.randn(1)>>> a
tensor([-1.2497])>>> a = torch.randn(1)>>> a
tensor([-2.0466])>>> a = torch.randn(1)>>> a
tensor([0.4620])>>> a = torch.randn(2)>>> a
tensor([0.3337,0.5260])>>> a = torch.randn(1,2)>>> a
tensor([[-0.0197,0.1966]])>>> a = torch.randn(2,1)>>> a
tensor([[-0.3927],[-0.4279]])
>>> a
tensor([-0.2679,0.1669,3.7573,-1.9038,-0.2729])>>> a.size()
torch.Size([5])>>> a.shape
torch.Size([5])>>> a
tensor([[-0.2679],[0.1669],[3.7573],[-1.9038],[-0.2729]])>>> a.size()
torch.Size([5,1])>>> a.shape
torch.Size([5,1])
將tensor轉成其他數據類型
轉成list
很吃驚的是,居然精度有這么高!!
>>> a
tensor([-0.2679,0.1669,3.7573,-1.9038,-0.2729])>>> a.tolist()[-0.2678675651550293,0.16691356897354126,3.757300853729248,-1.9038498401641846,-0.27292633056640625]
轉成numpy
>>> a
tensor([-0.2679,0.1669,3.7573,-1.9038,-0.2729])>>> a.numpy()
array([-0.26786757,0.16691357,3.7573009,-1.9038498,-0.27292633],dtype=float32)
改變Tensor形狀
先創建一個數據
>>> a
tensor([[-0.0752,0.0072,1.7456,1.2480,0.7506,-1.2426],[0.1641,-0.6519,-0.9540,-1.0443,-0.8130,1.0243],[1.2052,-1.0993,2.5415,0.9572,-0.9123,0.6194],[1.4059,1.1456,-0.1732,-1.0271,-0.0565,-0.6258],[0.7262,-2.5908,0.5556,0.6691,-0.0912,2.1089],[1.5669,-0.6453,0.8954,0.4817,-0.6550,0.9734]])>>> a.size()
torch.Size([6,6])
>>> a
tensor([[-0.0752,0.0072,1.7456,1.2480,0.7506,-1.2426],[0.1641,-0.6519,-0.9540,-1.0443,-0.8130,1.0243],[1.2052,-1.0993,2.5415,0.9572,-0.9123,0.6194],[1.4059,1.1456,-0.1732,-1.0271,-0.0565,-0.6258],[0.7262,-2.5908,0.5556,0.6691,-0.0912,2.1089],[1.5669,-0.6453,0.8954,0.4817,-0.6550,0.9734]])>>> a.shape
torch.Size([6,6])
>>> a.resize_(2,18)
tensor([[-0.0752,0.0072,1.7456,1.2480,0.7506,-1.2426,0.1641,-0.6519,-0.9540,-1.0443,-0.8130,1.0243,1.2052,-1.0993,2.5415,0.9572,-0.9123,0.6194],[1.4059,1.1456,-0.1732,-1.0271,-0.0565,-0.6258,0.7262,-2.5908,0.5556,0.6691,-0.0912,2.1089,1.5669,-0.6453,0.8954,0.4817,-0.6550,0.9734]])>>> a
tensor([[-0.0752,0.0072,1.7456,1.2480,0.7506,-1.2426,0.1641,-0.6519,-0.9540,-1.0443,-0.8130,1.0243,1.2052,-1.0993,2.5415,0.9572,-0.9123,0.6194],[1.4059,1.1456,-0.1732,-1.0271,-0.0565,-0.6258,0.7262,-2.5908,0.5556,0.6691,-0.0912,2.1089,1.5669,-0.6453,0.8954,0.4817,-0.6550,0.9734]])
這次就會發生改變了。 但是注意,這次不允許使用負數(來進行默認計算)
>>> a.resize_(2,-1)
Traceback (most recent call last):File "<stdin>", line 1,in<module>
RuntimeError: sizes must be non-negative
>>> a = torch.rand(10)>>> a
tensor([0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718])>>> a.unsqueeze(dim=1)
tensor([[0.5478],[0.4366],[0.2502],[0.5778],[0.7834],[0.8406],[0.3881],[0.8908],[0.0255],[0.4718]])>>> a
tensor([0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718])
但是如果維度只有1的話,我們dim=2就會出問題
>>> a.unsqueeze(dim=2)
Traceback (most recent call last):File "<stdin>", line 1,in<module>
RuntimeError: Dimension out of range(expected to be inrange of [-2,1], but got 2)
但是這個報錯很有趣,所以,我都試了下
>>> a
tensor([0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718])>>> a.unsqueeze(dim=0)
tensor([[0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718]])>>> a.unsqueeze(dim=-1)
tensor([[0.5478],[0.4366],[0.2502],[0.5778],[0.7834],[0.8406],[0.3881],[0.8908],[0.0255],[0.4718]])>>> a.unsqueeze(dim=-2)
tensor([[0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718]])
squeeze()反向操作
>>> a
tensor([0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718])>>> a.squeeze()
tensor([0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718])
把數據做一下簡單的調整
>>> a
tensor([[0.5478],[0.4366],[0.2502],[0.5778],[0.7834],[0.8406],[0.3881],[0.8908],[0.0255],[0.4718]])>>> a.squeeze()
tensor([0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718])
先壓縮一下:
>>> a = a.unsqueeze(dim=1)>>> a
tensor([[[0.5478]],[[0.4366]],[[0.2502]],[[0.5778]],[[0.7834]],[[0.8406]],[[0.3881]],[[0.8908]],[[0.0255]],[[0.4718]]])>>> a.shape
torch.Size([10,1,1])>>> a.squeeze()
tensor([0.5478,0.4366,0.2502,0.5778,0.7834,0.8406,0.3881,0.8908,0.0255,0.4718])
>>> a = torch.randn(6,6)>>> a
tensor([[-0.9391,1.4903,-1.4979,1.4666,0.1815,-0.6964],[-1.2770,-0.8761,-1.9706,0.8806,-0.9304,0.0181],[0.1157,1.3184,0.2521,-1.5565,-0.8318,1.0100],[-0.2843,0.3335,-0.1813,-1.3236,2.2849,-0.0776],[-0.6731,-0.5142,0.2758,0.4677,2.0181,-1.2722],[1.8404,0.7929,-0.8389,1.0610,-0.0790,-0.2701]])
>>> a
tensor([[-0.9391,1.4903,-1.4979,1.4666,0.1815,-0.6964],[-1.2770,-0.8761,-1.9706,0.8806,-0.9304,0.0181],[0.1157,1.3184,0.2521,-1.5565,-0.8318,1.0100],[-0.2843,0.3335,-0.1813,-1.3236,2.2849,-0.0776],[-0.6731,-0.5142,0.2758,0.4677,2.0181,-1.2722],[1.8404,0.7929,-0.8389,1.0610,-0.0790,-0.2701]])>>> a[(1,3),]
tensor([[-1.2770,-0.8761,-1.9706,0.8806,-0.9304,0.0181],[-0.2843,0.3335,-0.1813,-1.3236,2.2849,-0.0776]])
Tensor的比較
Tensor > int
>>> a
tensor([[-0.9391,1.4903,-1.4979,1.4666,0.1815,-0.6964],[-1.2770,-0.8761,-1.9706,0.8806,-0.9304,0.0181],[0.1157,1.3184,0.2521,-1.5565,-0.8318,1.0100],[-0.2843,0.3335,-0.1813,-1.3236,2.2849,-0.0776],[-0.6731,-0.5142,0.2758,0.4677,2.0181,-1.2722],[1.8404,0.7929,-0.8389,1.0610,-0.0790,-0.2701]])>>> a >0
tensor([[0,1,0,1,1,0],[0,0,0,1,0,1],[1,1,1,0,0,1],[0,1,0,0,1,0],[0,0,1,1,1,0],[1,1,0,1,0,0]], dtype=torch.uint8)
>>> a
tensor([[-0.9391,1.4903,-1.4979,1.4666,0.1815,-0.6964],[-1.2770,-0.8761,-1.9706,0.8806,-0.9304,0.0181],[0.1157,1.3184,0.2521,-1.5565,-0.8318,1.0100],[-0.2843,0.3335,-0.1813,-1.3236,2.2849,-0.0776],[-0.6731,-0.5142,0.2758,0.4677,2.0181,-1.2722],[1.8404,0.7929,-0.8389,1.0610,-0.0790,-0.2701]])>>> a ==-0.9391
tensor([[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]], dtype=torch.uint8)
>>> indices = torch.tensor([0,1])>>> torch.index_select(a,1, indices)
tensor([[-0.9391,1.4903],[-1.2770,-0.8761],[0.1157,1.3184],[-0.2843,0.3335],[-0.6731,-0.5142],[1.8404,0.7929]])>>> a
tensor([[-0.9391,1.4903,-1.4979,1.4666,0.1815,-0.6964],[-1.2770,-0.8761,-1.9706,0.8806,-0.9304,0.0181],[0.1157,1.3184,0.2521,-1.5565,-0.8318,1.0100],[-0.2843,0.3335,-0.1813,-1.3236,2.2849,-0.0776],[-0.6731,-0.5142,0.2758,0.4677,2.0181,-1.2722],[1.8404,0.7929,-0.8389,1.0610,-0.0790,-0.2701]])
記住,這里的tensor不同于Tensor
>>> indices
tensor([0,1])>>> torch.Tensor([0,1])
tensor([0.,1.])
發現了吧,必須要是正整數。 而且也必須是Tensor
>>> torch.index_select(a,1,[0,1])
Traceback (most recent call last):File "<stdin>", line 1,in<module>
TypeError: index_select(): argument 'index'(position 3) must be Tensor,notlist
>>> a
tensor([[1.,0.,0.,0.,0.],[0.,1.,0.,0.,0.],[0.,0.,1.,0.,0.],[0.,0.,0.,1.,0.],[0.,0.,0.,0.,1.]])>>> torch.nonzero(a)
tensor([[0,0],[1,1],[2,2],[3,3],[4,4]])
gather 根據index,在dim上選取數據,輸出size與index一直
其實就是一個多重映射
>>> t = torch.tensor([[1,2],[3,4]])>>> torch.gather(t,1, torch.tensor([[0,0],[1,0]]))
tensor([[1,1],[4,3]])>>> torch.gather(t,0, torch.tensor([[0,0],[1,0]]))
tensor([[1,2],[3,2]])
用下面的例子來區分dim=1和dim=0的區別
>>> t
tensor([[1,2],[3,4]])>>> torch.gather(t,0, torch.tensor([[0,1],[1,0]]))
tensor([[1,4],[3,2]])>>> torch.gather(t,1, torch.tensor([[0,1],[1,0]]))
tensor([[1,2],[4,3]])
看到有這么一段公式 3D-Tensor下的公式。(n維都是類似的)
out[i][j][k]=input[index[i][j][k]][j][k]# if dim == 0
out[i][j][k]=input[i][index[i][j][k]][k]# if dim == 1
out[i][j][k]=input[i][j][index[i][j][k]]# if dim == 2
clamp截斷
這個函數就是用來做截斷的
>>> t
tensor([[1,2],[3,4]])>>> torch.clamp(t,2,3)
tensor([[2,2],[3,3]])