零基础深度学习Pytorch教程,一个小时快速入门(一)

Pytorch官网有非常优秀的教程,其中有几篇小短文属于名为DEEP LEARNING WITH PYTORCH: A 60 MINUTE BLITZ这个小专栏的内容,考虑到大家阅读英文文献有点困难,笔者打算花两天时间做一下翻译,同时结合自己的理解做一些内容调整,原文链接贴在这里点此跳转。话不多说直接进入正题。

第一部分是认识tensor。

Tensors

tensor直译就是张量,可以理解为向量vector的延申。tensors是一种特殊的数据结构与数组和矩阵十分相似。在Pytorch中我们使用tensors去编码一个模型的输入输出,模型的参数也是这样操作的。

tensors和Numpy的多维数组ndarray很相似,除了tensors可以运行在GPU上,或者其他的可以用来加速计算速度的特殊硬件。如果你熟悉ndarray的话,你可以正确的使用Tensors的API接口。不过如果你不熟悉的话,那请提前快速地阅读一下对应的API。

下面是加载库的头文件

import torch
import numpy as np

Tensor的初始化 

tensor可以使用多种方式初始化,下面是一些例子。

1.直接来源于数据

tensor可以直接使用数据创建,数据类型可以自动的识别出来。 

data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)

2.从numpy数组中来

tensor可以使用numpy数组来创建(numpy数组就类似于常用数值型的多维数组),反之亦然。 

np_array = np.array(data)
x_np = torch.from_numpy(np_array)

3.来源于tensor

新的tensor保留了原来tensor的参数属性包括(形状,数据类型),这里的形状可以理解为tensor的维度 。

x_ones = torch.ones_like(x_data) # 保留了x_data的属性
print(f"Ones Tensor: \n {x_ones} \n")

x_rand = torch.rand_like(x_data, dtype=torch.float) # 覆盖了x_data的数据类型
print(f"Random Tensor: \n {x_rand} \n")

对应的输出如下图”

Ones Tensor:
 tensor([[1, 1],
        [1, 1]])

Random Tensor:
 tensor([[0.5715, 0.8526],
        [0.2244, 0.4860]])

4.使用随机值或者常数值构建

shape是一个tensor的维度,在下图的函数中,它决定了输出tensor的维度。

shape = (2,3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)

print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")

输出结果如下:

Random Tensor:
 tensor([[0.5585, 0.0448, 0.1216],
        [0.7801, 0.0683, 0.2854]])

Ones Tensor:
 tensor([[1., 1., 1.],
        [1., 1., 1.]])

Zeros Tensor:
 tensor([[0., 0., 0.],
        [0., 0., 0.]])

以上就是tensor的四种创建方式了。

tensor的属性 

tensor的属性主要包括shape(形状表示维度)、数据类型和它们存储在哪一个设备上。

tensor = torch.rand(3,4)

print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")

输出如下:

Shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu

对Tensor的操作方式 

总共大约100种对tensor的操作,包括转置,索引,切片,数学运算,线性代数,随机抽样,更多的操作描述可以点击这个链接。

这些操作中的每一个都可以运行在GPU上,简单来说就是可以获得一些硬件加速。如果你财力雄厚的话可以考虑搞一块牛x的GPU帮助你干活。

# 如果财力雄厚的话,我们可以将tensor移到GPU上
if torch.cuda.is_available():
  tensor = tensor.to('cuda')

可以从操作清单中找出一些试试看,如果熟悉Numpy API,你会发现tensor 的API很容易学会。(PS:我要是熟悉Numpy我还看你这个教程吗≧ ﹏ ≦) 

1.标准的Numpy结构式的索引和切片:

tensor = torch.ones(4, 4)
tensor[:,1] = 0
print(tensor)

输出如下:

tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

2.连接tensor

你可以使用tensor.cat指定给定的维度去连接一系列的tensor。

t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)

输出如下:

tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])

3.tensor的乘积

# 计算tensor的乘积
print(f"tensor.mul(tensor) \n {tensor.mul(tensor)} \n")
# 另一种表述形式:
print(f"tensor * tensor \n {tensor * tensor}")

输出如下:

tensor.mul(tensor)
 tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

tensor * tensor
 tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

计算在两个tensor之间矩阵的乘积。

print(f"tensor.matmul(tensor.T) \n {tensor.matmul(tensor.T)} \n")
# 另一种表述形式:
print(f"tensor @ tensor.T \n {tensor @ tensor.T}")

结果如下:

tensor.matmul(tensor.T)
 tensor([[3., 3., 3., 3.],
        [3., 3., 3., 3.],
        [3., 3., 3., 3.],
        [3., 3., 3., 3.]])

tensor @ tensor.T
 tensor([[3., 3., 3., 3.],
        [3., 3., 3., 3.],
        [3., 3., 3., 3.],
        [3., 3., 3., 3.]])

4.原地操作

在这些操作中有一个_后缀是原地操作,比如:x_copy_(y),x.t_(),这些操作会改变x的数值

print(tensor, "\n")
tensor.add_(5)
print(tensor)

结果如下:

tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

tensor([[6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.]])

值得注意的是原地操作不会保留某些中间变量,这就导致在某些需要中间量的操作中,由于中间量没有被保存会出现很多问题,因此这种写法要谨慎使用。

使用Numpy过渡  

tensor在cpu上以及numpy数组可以共享它们潜在的内存位置,改变一个就可以改变另一个。

Tensor转为numpy数组

t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")

结果如下:

t: tensor([1., 1., 1., 1., 1.])
n: [1. 1. 1. 1. 1.]

tensor中的改变反映在了numpy数组之中

t.add_(1)
print(f"t: {t}")
print(f"n: {n}")

输出如下:

t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]

numpy数组转化为Tensor 

n = np.ones(5)
t = torch.from_numpy(n)

numpy数组的改变体现在了tensor中

np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")

输出如下:

t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]

我们的第一篇就到这里了,后面还会对内容进行完善,接下来会陆续更新下面几篇。

你可能感兴趣的:(深度学习,pytorch,深度学习,python)