本系列博客的目标是用pytorch 搭建一个网络。先简单后复杂吧~
博客大部分内容参考官方文档,又按照自己更习惯的思路重新整理了下!
好记性不如烂笔头,当写博客的时候,速度会慢下来,就有更多的时间思考自己曾经忽视的细节!
参考: 知乎 梁泽浪 Pytorch 官方文档
本系列博客的主要介绍:
1、pytorch中采用的基本数据结构 Tensor
2、数据集的加载
3、网络模型的构建
4、网络模型的训练和优化
5、网络模型的保存和加载
6、网络模型的可视化及调试 --TensorBoard
在用pytorch 搭建神经网络时,无论是网路的输入还是输出,都需要用到Tensor 。因此Tensor是什么?有哪些性质?非Tensor 数据转为Tensor格式数据如何实施? Tensor 数据可以进行那些方式的计算,加减乘除等?这些问题都需要解决。
一个一阶张量可以理解为一个向量,二阶张量可以理解为矩阵,三阶张量可以理解成立方体,四阶张量可以理解成立方体组成的一个向量,依次类推。
Tensor 基本的属性包括 shape(形状)、dtype(数据类型)、device(位置:cpu or gpu) 。
import torch
tensor = torch.rand((3,4), dtype=torch.float32)
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 在创建时默认是创建在CPU上,也可以指定创建在GPU上。因为我的笔记本上没有GPU,所以下面的代码读到的设备是CPU。
import torch
# 方式1:直接在GPU上生成张量
shape = (2,3)
if torch.cuda.is_available():
tensor = torch.rand(shape, device='cuda')
#方式2:将张量从CPU移到GPU上
tensor = torch.rand(shape)
if torch.cuda.is_available():
tensor = tensor.to('cuda')
print(f'tensor:\n{tensor}')
print(f'device:\n{tensor.device}')
# tensor:
# tensor([[0.4419, 0.7996, 0.6684],
# [0.3035, 0.1892, 0.2249]])
# device:
# cpu
可以使用torch.tensor( ) 完成转换。
import torch
data = [[1, 2], [3, 4]]
tensor = torch.tensor(data)
print(f'tensor:\n{tensor}')
# tensor:
# tensor([[1, 2],
# [3, 4]])
可以使用torch.tensor( ) 、torch.from_numpy( ) 完成转换。
将tensor 转换为numpy 时,tensor.numpy( ) 即可。
import torch
import numpy as np
np_data = np.array([[1, 2], [3, 4]])
np_tensor = torch.from_numpy(np_data) #等价 np_tensor = torch.tensor(np_data)
print(f'np_tensor:\n{np_tensor}')
# np_tensor:
# tensor([[1, 2],
# [3, 4]], dtype=torch.int32)
利用原张量的shape 和 dtype 创建新张量(全零张量、全一张量、随机张量),也可以override改变原张量的dtype。
import torch
import numpy as np
np_data = np.array([[1, 2], [3, 4]])
np_tensor = torch.from_numpy(np_data) #等价 np_tensor = torch.tensor(np_data)
ones_tensor = torch.ones_like(np_tensor) #获取原有的shape和dtype属性
rand_tensor = torch.rand_like(np_tensor, dtype=torch.float) #覆盖dtype属性
print(f'ones_tensor:\n{ones_tensor}\n'
f'rand_tensor:\n{rand_tensor}\n')
# ones_tensor:
# tensor([[1, 1],
# [1, 1]], dtype=torch.int32)
# rand_tensor:
# tensor([[0.8663, 0.5340],
# [0.5892, 0.9921]])
import torch
shape = (2, 3)
rand_tensor_shape = torch.rand(shape)
ones_tensor_shape = torch.ones(shape)
zeros_tensor_shape = torch.zeros(shape)
print(f'rand_tensor_shape:\n{rand_tensor_shape}\n'
f'ones_tensor_shape:\n{ones_tensor_shape}\n'
f'zeros_tensor_shape:\n{zeros_tensor_shape}\n')
# rand_tensor_shape:
# tensor([[0.9950, 0.8967, 0.2755],
# [0.7054, 0.4058, 0.1672]])
# ones_tensor_shape:
# tensor([[1., 1., 1.],
# [1., 1., 1.]])
# zeros_tensor_shape:
# tensor([[0., 0., 0.],
# [0., 0., 0.]])
import torch
tensor = torch.ones(4,4)
print('First row: ', tensor[0])
print('First column: ', tensor[:, 0])
print('Last column: ', tensor[:, -1])
tensor[:, 1] = 0
print(tensor)
# First row: tensor([1., 1., 1., 1.])
# First column: tensor([1., 1., 1., 1.])
# Last column: tensor([1., 1., 1., 1.])
# tensor([[1., 0., 1., 1.],
# [1., 0., 1., 1.],
# [1., 0., 1., 1.],
# [1., 0., 1., 1.]])
torch.cat算子沿着给定的维度dim 对输入的Tensor 进行合并。
import torch
tensor = torch.ones(2,2)
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)
# tensor([[1., 1., 1., 1., 1., 1.],
# [1., 1., 1., 1., 1., 1.]])
import torch
tensor = torch.ones(2,2)
# 张量乘法,可以通过以下三种方式实现
y1 = tensor @ tensor.T # 乘法 方法1
y2 = tensor.matmul(tensor.T) # 乘法 方法2
y3 = torch.rand_like(tensor)
torch.matmul(tensor, tensor.T, out=y3) # 乘法 方法3
# 矩阵元素点乘,也有三种实现方式
z1 = tensor * tensor # 点乘 方法1
z2 = tensor.mul(tensor) # 点乘 方法2
z3 = torch.rand_like(tensor) # 点乘 方法3
torch.mul(tensor, tensor, out=z3)
print(f'tensor:\n{tensor}')
print(f'matrix multiplication 1:\n{z1}')
print(f'matrix multiplication 2:\n{z2}')
print(f'matrix multiplication 3:\n{z3}')
输入输出相同的地址(也就是在原对象上进行修改)
操作时以_为后缀,如 x.add_, x.copy_ 等。
import torch
tensor = torch.ones(2,2)
print(tensor, "\n")
tensor.add_(5)
print(tensor)
# tensor([[1., 1.],
# [1., 1.]])
#
# tensor([[6., 6.],
# [6., 6.]])