深度学习实验二

Posted zc.9495

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习实验二相关的知识,希望对你有一定的参考价值。

NNDL 实验二 pytorch入门

一. 概念:张量、算子
1.张量:在深度学习框架中,数据经常用张量(Tensor)的形式来存储。张量是矩阵的扩展与延伸,可以认为是高阶的矩阵,是标量,向量,矩阵的高维拓展。
2.算子:算子是构建复杂机器学习模型的基础组件,包含一个函数f(x)的前向函数和反向函数。

二. 使用pytorch实现张量运算
1.2 张量
1.2.1 创建张量

创建一个张量可以有多种方式,如:指定数据创建、指定形状创建、指定区间创建等。
1.2.1.1 指定数据创建张量
通过给定Python列表数据,可以创建任意维度的张量。

(1)通过指定的Python列表数据[2.0, 3.0, 4.0],创建一个一维张量。

#导入torch
import torch
ndim_1_Tensor = torch.tensor([2.0, 3.0, 4.0])
print(ndim_1_Tensor)

运行结果:

tensor([2., 3., 4.])

(2)通过指定的Python列表数据来创建类似矩阵(matrix)的二维张量。

ndim_2_Tensor = torch.tensor([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0]])
print(ndim_2_Tensor)

运行结果:

tensor([[1., 2., 3.],
        [4., 5., 6.]])

(3)同样地,还可以创建维度为3、4…N等更复杂的多维张量。

ndim_3_Tensor = torch.tensor([[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]], [[11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]])
print(ndim_3_Tensor)

运行结果:

tensor([[[ 1,  2,  3,  4,  5],
         [ 6,  7,  8,  9, 10]],
        [[11, 12, 13, 14, 15],
         [16, 17, 18, 19, 20]]])

需要注意的是,张量在任何一个维度上的元素数量必须相等。下面尝试定义一个在同一维度上元素数量不等的张量。

ndim_2_Tensor = torch.tensor([[1.0, 2.0],[4.0, 5.0, 6.0]])

运行结果:

    ndim_2_Tensor = torch.tensor([[1.0, 2.0],[4.0, 5.0, 6.0]])
ValueError: expected sequence of length 2 at dim 1 (got 3)

从输出结果看,这种定义情况会抛出异常,提示在任何维度上的元素数量必须相等。
1.2.1.2 指定形状创建

m=2
n=3
# 使用paddle.zeros创建数据全为0,形状为[m, n]的Tensor
zeros_Tensor = torch.zeros([m, n])
# 使用paddle.ones创建数据全为1,形状为[m, n]的Tensor
ones_Tensor = torch.ones([m, n])
# 使用paddle.full创建数据全为指定值,形状为[m, n]的Tensor,这里我们指定数据为10
full_Tensor = torch.full([m, n], 10)
print('zeros Tensor: ', zeros_Tensor)
print('ones Tensor: ', ones_Tensor)
print('full Tensor: ', full_Tensor)

运行结果:

zeros Tensor:  tensor([[0., 0., 0.],
        [0., 0., 0.]])
ones Tensor:  tensor([[1., 1., 1.],
        [1., 1., 1.]])
full Tensor:  tensor([[10., 10., 10.],
        [10., 10., 10.]])

1.2.1.3 指定区间创建

arange_Tensor = torch.arange(start=1, end=5, step=1)
print('arange_Tensor:', arange_Tensor)
linspace_Tensor = torch.linspace(start=1, end=5, steps=5)
print('linspace_Tensor:', linspace_Tensor)

运行结果:

arange_Tensor: tensor([1, 2, 3, 4])
linspace_Tensor: tensor([1., 2., 3., 4., 5.])

1.2.2 张量的属性

1.2.2.1 张量的形状
创建一个四维张量,并打印出shape、ndim、shape[n]、size属性。

ndim_4_Tensor = torch.ones([2, 3, 4, 5])
print("Number of dimensions:", ndim_4_Tensor.ndim)
print("Shape of Tensor:", ndim_4_Tensor.shape)
print("Elements number along axis 0 of Tensor:", ndim_4_Tensor.shape[0])
print("Elements number along the last axis of Tensor:", ndim_4_Tensor.shape[-1])
print('Number of elements in Tensor: ', ndim_4_Tensor.size)

运行结果:

Number of dimensions: 4
Shape of Tensor: torch.Size([2, 3, 4, 5])
Elements number along axis 0 of Tensor: 2
Elements number along the last axis of Tensor: 5
Number of elements in Tensor:  <built-in method size of Tensor object at 0x000001E83F173840>

1.2.2.2 形状的改变

# 定义一个shape为[3,2,5]的三维Tensor
ndim_3_Tensor = torch.tensor([[[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]]])
print("the shape of ndim_3_Tensor:", ndim_3_Tensor.shape)
reshape_Tensor = torch.reshape(ndim_3_Tensor, [2, 5, 3])
print("After reshape:", reshape_Tensor)

运行结果:

the shape of ndim_3_Tensor: torch.Size([3, 2, 5])
After reshape: tensor([[[ 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]]])

从输出结果看,将张量从[3, 2, 5]的形状reshape为[2, 5, 3]的形状时,张量内的数据不会发生改变,元素顺序也没有发生改变,只有数据形状发生了改变。

笔记
使用reshape时存在一些技巧,比如:
-1表示这个维度的值是从张量的元素总数和剩余维度推断出来的。因此,有且只有一个维度可以被设置为-1。
0表示实际的维数是从张量的对应维数中复制出来的,因此shape中0所对应的索引值不能超过张量的总维度。
分别对上文定义的ndim_3_Tensor进行reshape为[-1]和reshape为[0, 5, 2]两种操作,观察新张量的形状。

new_Tensor1 = ndim_3_Tensor.reshape([-1])
print('new Tensor 1 shape: ', new_Tensor1.shape)
new_Tensor2 = ndim_3_Tensor.reshape([0, 5, 2])
print('new Tensor 2 shape: ', new_Tensor2.shape)

运行结果:

new Tensor 1 shape:  [30]
new Tensor 2 shape:  [3, 5, 2]

1.2.2.3 张量的数据类型

print("Tensor dtype from Python integers:", torch.tensor(1).dtype)
print("Tensor dtype from Python floating point:", torch.tensor(1.0).dtype)

运行结果:

Tensor dtype from Python integers: torch.int64
Tensor dtype from Python floating point: torch.float32

如果想改变张量的数据类型,可以通过调用torch.castAPI来实现。

# 定义dtype为float32的Tensor
float32_Tensor = torch.tensor(1.0)
# torch.cast可以将输入数据的数据类型转换为指定的dtype并输出。支持输出和输入数据类型相同。
int64_Tensor = float32_Tensor.to(torch.int64)
print('Tensor after cast to int64:', int64_Tensor.dtype)

运行结果:

Tensor after cast to int64: torch.int64

1.2.2.4 张量的设备位置
初始化张量时可以通过place来指定其分配的设备位置,可支持的设备位置有三种:CPU、GPU和固定内存。

# 创建CPU上的Tensor
cpu_Tensor = torch.tensor(1, device=torch.device('cpu'))
print('cpu_Tensor:', cpu_Tensor.device)
# 创建GPU上的Tensor
gpu_Tensor = torch.tensor(1, device=torch.device('gpu'))
print('gpu_Tensor:', gpu_Tensor.device)
# 创建固定内存上的Tensor
pin_memory_Tensor = torch.tensor(1, device=torch.device('cudaPinned'))
print('pin memory Tensor:', pin_memory_Tensor.device)

运行结果:

cpu Tensor:  CPUPlace
gpu Tensor:  CUDAPlace(0)
pin memory Tensor:  CUDAPinnedPlace

1.2.3 张量与Numpy数组转换

ndim_1_Tensor =torch.tensor([1., 2.])
# 将当前 Tensor 转化为 numpy.ndarray
print('Tensor to convert: ', ndim_1_Tensor.numpy())

运行结果:

Tensor to convert:  [1. 2.]

1.2.4 张量的访问

1.2.4.1 索引和切片
我们可以通过索引或切片方便地访问或修改张量。飞桨使用标准的Python索引规则与Numpy索引规则,具有以下特点:
基于0−n的下标进行索引,如果下标为负数,则从尾部开始计算。
通过冒号“:”分隔切片参数start:stop:step来进行切片操作,也就是访问start到stop范围内的部分元素并生成一个新的序列。其中start为切片的起始位置,stop为切片的截止位置,step是切片的步长,这三个参数均可缺省。
1.2.4.2 访问张量
针对一维张量,对单个轴进行索引和切片。

# 定义1个一维Tensor
ndim_1_Tensor = torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8])
print("Origin Tensor:", ndim_1_Tensor)
print("First element:", ndim_1_Tensor[0])
print("Last element:", ndim_1_Tensor[-1])
print("All element:", ndim_1_Tensor[:])
print("Before 3:", ndim_1_Tensor[:3])
print("Interval of 3:", ndim_1_Tensor[::3])
print("Reverse:", ndim_1_Tensor.flip(-1))

运行结果:

Origin Tensor: tensor([0, 1, 2, 3, 4, 5, 6, 7, 8])
First element: tensor(0)
Last element: tensor(8)
All element: tensor([0, 1, 2, 3, 4, 5, 6, 7, 8])
Before 3: tensor([0, 1, 2])
Interval of 3: tensor([0, 3, 6])
Reverse: tensor([8, 7, 6, 5, 4, 3, 2, 1, 0])

1.2.4.3 修改张量
与访问张量类似,可以在单个或多个轴上通过索引或切片操作来修改张量。

ndim_2_Tensor = torch.ones([2, 3])
ndim_2_Tensor = ndim_2_Tensor.to(torch.float32)
print('Origin Tensor: ', ndim_2_Tensor)
# 修改第1维为0
ndim_2_Tensor[0] = 0
print('change Tensor: ', ndim_2_Tensor)
# 修改第1维为2.1
ndim_2_Tensor[0:1] = 2.1
print('change Tensor: ', ndim_2_Tensor)
# 修改全部Tensor
ndim_2_Tensor[...] = 3
print('change Tensor: ', ndim_2_Tensor)

运行结果:

Origin Tensor:  tensor([[1., 1., 1.],
        [1., 1., 1.]])
change Tensor:  tensor([[0., 0., 0.],
        [1., 1., 1.]])
change Tensor:  tensor([[2.1000, 2.1000, 2.1000],
        [1.0000, 1.0000, 1.0000]])
change Tensor:  tensor([[3., 3., 3.],
        [3., 3., 3.]])

1.2.5 张量的运算
张量支持包括基础数学运算、逻辑运算、矩阵运算等100余种运算操作,以加法为例,有如下两种实现方式:
1)使用飞桨API torch.add(x,y)。
2)使用张量类成员函数x.add(y)。

# 定义两个Tensor
x = torch.tensor([[1.1, 2.2], [3.3, 4.4]])
x = x.to(torch.float64)
y = torch.tensor([[5.5, 6.6], [7.7, 8.8]])
y = y.to(torch.float64)
# 第一种调用方法,torch.add逐元素相加算子,并将各个位置的输出元素保存到返回结果中
print('Method 1: ', torch.add(x, y))
# 第二种调用方法
print('Method 2: ', x.add(y))

运行结果:

Method 1:  tensor([[ 6.6000,  8.8000],
        [11.0000, 13.2000]], dtype=torch.float64)
Method 2:  tensor([[ 6.6000,  8.8000],
        [11.0000, 13.2000]], dtype=torch.float64)

1.2.5.1 数学运算
张量类的基础数学函数如下:

x.abs()                       # 逐元素取绝对值
x.ceil()                      # 逐元素向上取整
x.floor()                     # 逐元素向下取整
x.round()                     # 逐元素四舍五入
x.exp()                       # 逐元素计算自然常数为底的指数
x.log()                       # 逐元素计算x的自然对数
x.reciprocal()                # 逐元素求倒数
x.square()                    # 逐元素计算平方
x.sqrt()                      # 逐元素计算平方根
x.sin()                       # 逐元素计算正弦
x.cos()                       # 逐元素计算余弦
x.add(y)                      # 

以上是关于深度学习实验二的主要内容,如果未能解决你的问题,请参考以下文章

深度学习猫狗识别TensorFlow2实验报告

深度学习实战——不同方式的模型部署(CNNYolo)

深度学习手写数字识别Tensorflow2实验报告

深度学习手写数字识别Tensorflow2实验报告

深度学习实验第四次:Python波士顿房价之构建回归预测模型

深度学习实战——卷积神经网络实践(LeNetResnet)