0%

Pytorch学习

Pytorch学习

Tensor张量

  • tensor是pytorch里面的数据类型

  • 标量,向量和矩阵三个其实都是张量,标量是零维的张量,向量是一维的张量,矩阵是二维的张量

tensor的成员

  • ==tensor.data==:张量的数据值是什么
  • ==tensor.grad==:该张量的梯度(如果没有就显示NONE)
  • ==tensor.grad_fn==:指向该张量处的函数计算(计算图中的计算节点),进行梯度反向传播的时候会用到。如果是由用户创建的tensor,则该值 为 NONE
  • ==tensor.grad_fn.next_function==: 上一级节点的grad_fn
  • ==tensor.requires_grad==: 是否需要梯度,如果需要pytorch会在图中跟踪该张量然后在反向传播的时候计算梯度

创建tensor

  • ==torch.eye(n)==, ==torch.ones((n,m))==,== torch.zeros((n,m))==和numpy建立矩阵的方法差不多

  • ==torch.t(x)== 对x进行转置

  • 直接==torch.tensor(x)==

常用操作

  • 把numpy数组装成tensor:==torch.from_numpy(array)==

  • 展开为特定的大小:==tensor.view(x,y)==

    • 若x,y中任意一个的维度为-1,则另外一个自动计算(就是可以少打一个,改成-1)
    • tensor.view(-1)则直接展开为1*n的张量
  • ==tensor,squeeze(n)==表示若tensor的n维度是1,则去掉该维度(例如(3,1,3)的squeeze(1)就会变成(3,3))

  • ==tensor.unsqueeze(n)==: squeeze的逆向操作,参数含义相同

  • ==torch.max(tensor, axis)==和numpy的max差不多

  • ==torch.randn(x,y)==生成随机的二维tensor

  • ==x.mm(y)==:x与y矩阵乘法

自动求导Autograd

  • 设置一个张量的==requires_grad=True==,只要调用tensor.backward()即可方向计算所有点的梯度,但是注意,图里面的tensor要是一个浮点数

  • 还要注意的是,在直接==tensor.backward()==的时候,这个tensor要是一个标量

  • 但是我们可以也可以对任意张量求导,==tensor.backward(torch.tensor([[1.0,1.0]])==,设置张量每个值的权重,在backward的时候,每一步得到的关于这个向量的梯度,然后按照这个权重加起来

计算图会自动销毁

  • 一个计算图在进行反向求导之后,为了节省内存,这个计算图就销毁了,如果这时候还想求导就会报错。

不想追踪张量

  • ==tensor.detach()==,把该张量从计算图中分离
  • 使用==with torch.no_grad():==包装可以直接分离多个点

torch.nn

containers—>torch.nn.Module

1
2
3
4
5
6
7
8
9
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5)# submodule: Conv2d
self.conv2 = nn.Conv2d(20, 20, 5)

def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))

你的类可以继承这个类

  • 注意,在所有的子类中都要重写forward函数,定义了每次执行的计算步骤

卷积层

  • 传给==nn.Conv2d()==的张量size应当为

$$
batchSizechannelsheight*width
$$

    • ==nn.Conv2d==的输入输出的图像尺寸关系为:

    $$
    output=\frac{input-kernerSize+2*paddings}{stride}+1
    $$

    • 以上为CNN中的参数
    • in_channels(int) – 输入信号的通道
    • out_channels(int) – 卷积产生的通道
    • kerner_size(int or tuple) - 卷积核的尺寸
    • stride(int or tuple, optional) - 卷积步长
    • padding(int or tuple, optional) - 输入的每一条边补充0的层数
    • dilation(int or tuple, optional) – 卷积核元素之间的间距
    • groups(int, optional) – 从输入通道到输出通道的阻塞连接数
    • bias(bool, optional) - 如果bias=True,添加偏置

网络层

  • ==nn.Linear(m,n)== 线性全连接层。接受一个张量,输出一个张量,输入的size必须为(,m),输出的size必须为(,n),即只对最后一个维度进行全连接计算,再将各个维度拼接起来。这是为了保证在网络中进行随机梯度下降的时候(假设batchSize=b),最后传到全连接层的张量size为(b,m),这样设计可以保证全连接层的输出size为(b,n),即只对每个样本进行计算,而不会把不同样本的数据放在一起计算。

Sequentail与add_module

  • Sequential是一个时序容器

  • model = nn.Sequential(OrderedDict([
                      ('conv1', nn.Conv2d(1,20,5)),
                      ('relu1', nn.ReLU()),
                      ('conv2', nn.Conv2d(20,64,5)),
                      ('relu2', nn.ReLU())
                    ]))
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53

    如上,就相当于model是一个模型,可以像内置模型那样出结果,如`model(x)`

    再加上`add_module(name, layer)`可以自己重构一个模型,name是一个字符串表示名字,layer是一个模型的内容像conv,relu之类的

    ### MSELoss

    有两个参数,模型预测输出x和目标y。能计算这之间的均方误差。

    ## cuda加速运算

    - cuda可以使用显卡的gpu计算tensor的运算(前提是要有一个支持cuda的显卡)
    - 1、==torch.cuda.is_available==来判断cuda是否可用
    - 2、把tensor或模型放到gpu中计算:==x=x.cuda()==
    - 3、然后计算的时候就能快速运算了
    - ==torch.device("设备名")==可以定义计算时所用的设备,例如例如==torch.device("cuda")==表示使用cuda,==torch.device("cpu"==)表示使用cpu。使用==x.to(torch.device("设备名"))==可以将模型/张量放到相应的设备上。

    ## 数据加载

    ### dataset

    - 重写torch.utils.data.dataset类
    - `__init__():`初始化数据集,一般传入数据存放位置,储存标签信息文件路径等
    - `__getitem__():`定义给定一个索引,加载相应样本的方法。传入参的索引i,返回数据集中第i个样本文件(tensor、PIL.image等)
    - `__len__():`返回数据集中样本的个数

    ### dataloader

    - 将dataset加载为dataloader:==torch.utils.data.dataloader.Dataloader(dataset,batch_size=n,shuufle=True,drop_last=True,num_worker)==
    - batch_size表示每个batch的大小
    - shuffle表示是否在训练时打乱数据
    - drop_last表示当前最后剩下的数据不足一个batch时,是否丢弃
    - num_worker表示加载数据所用的线程数

    ## 图像操作

    ### torchvision.transforms

    - Resize(h,w)将图片缩放为指定尺寸。只传入一个参数x的时候,将图像缩放使得其中一条边大小为x
    - Centercrop(h,w)从图片的中心裁剪下(h,w)的大小,当只有一个参数x的时候为正方形
    - Randomcrop(h,w)从图片随机裁剪下(h,w)的大小,当只有一个参数x的时候,裁剪正方形
    - ToTesor()把PIL_Image或numpy数组变为tensor,同时进行归一化操作
    - Normaliuze()进行归一化操作
    - ToPILImage(tensor)把tensor变为PIL格式
    - tensor.numpy()变为numpy数组
    - 使用matplotlib显示图片:plt.imshow(np.transpose(img,(1,2,0))),img是由tensor转化来的数组,之所以要转置,是因为torch和numpy中表示图片的格式不同
    - torchvision.utils.save_image(img, path)

    ## models

    ```python
    import torchvision.models as models
    VGG = models.vgg16(pretrained=True)
  • pretrained为True表示要训练模型,为False表示只保留网络结构