动手学深度学习PyTorch版笔记

torchvision包,它是服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。torchvision主要由以下几部分构成:

  1. torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
  2. torchvision.models: 包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;
  3. torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;
  4. torchvision.utils: 其他的一些有用的方法。

tensor.view(): 从numpy和pytorch之间的相似性来看,view类似于numpy的reshape函数

import torch

x = torch.randn(4, 4)

x.size()
torch.Size([4, 4])
y = x.view(16)
y.size()
torch.Size([16])

-1 的意思是从其他维度来推断size

z = x.view(-1, 8)
z.size()
torch.Size([2, 8])

从后向中排除子图

每个变量都有两个标志:requires_gradvolatile。它们都允许从梯度计算中精细地排除子图,并可以提高效率。
requires_grad
如果有一个单一的输入操作需要梯度,它的输出也需要梯度。相反,只有所有输入都不需要梯度,输出才不需要。如果其中所有的变量都不需要梯度进行,后向计算不会在子图中执行。

from torch.autograd import Variable
x = Variable(torch.randn(5, 5))
y = Variable(torch.randn(5, 5))
z = Variable(torch.randn(5, 5), requires_grad=True)
a = x + y
a.requires_grad
False
b = a + z
b.requires_grad
True

这个标志特别有用,当您想要冻结部分模型时,或者您事先知道不会使用某些参数的梯度。例如,如果要对预先训练的CNN进行优化,只要切换冻结模型中的requires_grad标志就足够了,直到计算到最后一层才会保存中间缓冲区,其中的仿射变换将使用需要梯度的权重并且网络的输出也将需要它们。

对多维Tensor按维度操作

X = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(X.sum(dim=0, keepdim=True))  # dim为0,按照相同的列求和,并在结果中保留列特征
print(X.sum(dim=1, keepdim=True))  # dim为1,按照相同的行求和,并在结果中保留行特征
print(X.sum(dim=0, keepdim=False)) # dim为0,按照相同的列求和,不在结果中保留列特征
print(X.sum(dim=1, keepdim=False)) # dim为1,按照相同的行求和,不在结果中保留行特征
tensor([[5, 7, 9]])
tensor([[ 6],
        [15]])
tensor([5, 7, 9])
tensor([ 6, 15])

torch.gather(input, dim, index, out=None, sparse_grad=False) → Tensor:沿dim指定的轴收集值

对于一个三维张量,输出由:

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

t = torch.tensor([[1, 2], [3, 4]])
t
tensor([[1, 2],
        [3, 4]])
torch.gather(t, 1, torch.tensor([[0,0],[1,0]]))
tensor([[1, 1],
        [4, 3]])
0 1
0 1 2
1 3 4

相当于下面坐标取的点,dim=1,是以y为轴
[(0,0),(0,1)] --> [(0,0),(0,0)]
[(1,0),(1,1)] --> [(1,1),(1,0)]

b = torch.Tensor([[1,2,3],[4,5,6]])
print(b)
index_1 = torch.LongTensor([[0,1],[2,0]])
index_2 = torch.LongTensor([[0,1,1],[0,0,0]])
print(torch.gather(b, dim=1, index=index_1))
print(torch.gather(b, dim=0, index=index_2))
tensor([[1., 2., 3.],
        [4., 5., 6.]])
tensor([[1., 2.],
        [6., 4.]])
tensor([[1., 5., 6.],
        [1., 2., 3.]])

[(0,0),(0,1),(0,2)] --> [(0,0),(1,1),(1,2)]
[(1,0),(1,1),(1,2)] --> [(0,0),(0,1),(0,2)]

错误的课后练习

1.假如你正在实现一个全连接层,全连接层的输入形状是7×8,输出形状是7×1,其中7是批量大小,则权重参数w和偏置参数b的形状分别是____和____

8×1,7×1
8×1,1×1

答案解释:设输入批量为 X ∈ R 7 ∗ 8 X \in \mathbb{R}^{7*8} XR78, 对应的输出为 Y ∈ R 8 ∗ 1 Y \in \mathbb{R}^{8*1} YR81,则 X w ∈ R 7 ∗ 1 Xw \in \mathbb{R}^{7*1} XwR71,然后我们给 X w Xw Xw中的每个元素加上的偏置是一样的,所以偏置参数 b ∈ R 1 ∗ 1 b \in \mathbb{R}^{1*1} bR11,基于加法的广播机制,可以完成得到输出 Y = X w + b Y=Xw+b Y=Xw+b参数的形状与批量大小没有关系,也正是因为如此,对同一个模型,我们可以选择不同的批量大小。

你可能感兴趣的:(动手学深度学习PyTorch版)