pytorch学习笔记1-pytorch基础
1 Tensor
Tensor类型:
torch.FloatTensor 32位浮点型(默认)
torch.DoubleTensor 64位
torch.ShortTensor 16位整型
torch.IntTensor 32位整型
torch.LongTensor 64位整型
Tensor操作:
1.1 创建
1.1.1 创建默认类型
import torch
# Tensor默认是torch.FloatTensor数据类型
a = torch.Tensor([[2, 3], [4, 8], [7, 9]])
print('a is: {}'.format(a))
print('a size is {}'.format(a.size())) #a.size() = 3, 2
a is: tensor([[2., 3.],
[4., 8.],
[7., 9.]])
a size is torch.Size([3, 2])
1.1.2创建其他类型
# 注意所有的Tensor都要用‘[]’括起来
b = torch.LongTensor([[2, 3], [4, 8], [7, 9]])
print('b is :{}'.format(b))
b is :tensor([[2, 3],
[4, 8],
[7, 9]])
1.1.3 创建全是0或取正态分布作为随机初始值:
# 正态分布
c = torch.zeros((3, 2))
print('zero tensor: {}'.format(c))
zero tensor: tensor([[0., 0.],
[0., 0.],
[0., 0.]])
# 随机
d = torch.randn((3, 2))
print('normal randon is: {}'.format(d))
normal randon is: tensor([[-0.9482, -0.8189],
[-1.9248, 0.3190],
[ 1.2413, 0.6045]])
1.2 修改
a[0, 1] = 100 #把a的第一行第二列改为100
print('changed a is:{}'.format(a))
changed a is:tensor([[ 2., 100.],
[ 4., 8.],
[ 7., 9.]])
1.3 与numpy相互转换
核心:
1.将Tensor转换成成numpy:a.numpy()
2.将numpy转换成Tensor:torch.from_numpy(a)
# 转换成numpy
numpy_b = b.numpy() # 将Tensor转换成成numpy
print('conver to numpy is \n {}'.format(numpy_b))
conver to numpy is
[[2 3]
[4 8]
[7 9]]
import numpy as np # 后面常要用到这种缩写,一开始就要写好
e = np.array([[2, 3], [4, 5]])
torch_e = torch.from_numpy(e) # numpy转换成Tensor
print('from numpy to torch.Tensor is {}'.format(torch_e))
f_torch_e = torch_e.float()
print('change data type to float tensor: {}'.format(f_torch_e))
from numpy to torch.Tensor is tensor([[2, 3],
[4, 5]], dtype=torch.int32)
change data type to float tensor: tensor([[2., 3.],
[4., 5.]])
2 Variable
2.1 结构
Variable有三个属性:data、grad、grad_fn
data:取出Variable里面的Tensor的数值
grad:Variable的反向传播梯度
grad_fn:得到这个Variable的操作,比如:加减还是乘除
2.2 操作
2.2.1 创建Variable
# 创建Variable
from torch.autograd import Variable # 要运行必须import一下
x = Variable(torch.Tensor([1]), requires_grad = True)
y = Variable(torch.Tensor([2]), requires_grad = True)
z = Variable(torch.Tensor([3]), requires_grad = True)
2.2.2 计算梯度
标量梯度计算
# 构造一个计算图
w = 2 # w一般是权重,这里初始化,方便运行,不然会报“未定义”错
y = w * x + b
重点:
requires_grad默认为False,设置为True的时候表示需要对变量求梯度
ERROR:
“#” 计算梯度
y.backward()
这个运行报错了:
RuntimeError: grad can be implicitly created only for scalar outputs
此时,因为输出不是一个标量,因此需要改为
# 计算梯度
y.backward(y.data)
# 输出梯度
print(x.grad) # 输出y对x的梯度
print(w.grad) # 输出y对w的梯度
print(b.grad) # 输出y对b的梯度
矩阵梯度计算
x = torch.randn(3)
x = Variable(x, requires_grad = True)
y = x * 2
print(y)
y.backward(torch.FloatTensor([1, 0.1, 0.01])) # 在原来的基础上分别乘上1, 0.1, 0.01
print(x.grad)
tensor([-1.0545, 2.6542, 4.2048], grad_fn=)
tensor([2.0000, 0.2000, 0.0200])
3 Dataset
3.1 自定义数据类
包:torch.utils.data.Dataset
可以自定义数据类继承、重写抽象类(只需要定义__len__和__getitem__两个函数)
class myDataset(Dataset):
def __init__(self, csv_file, txt_file, root_dir, other_file):
self.csv_data = pd.read_csv(csv_file)
with open(txt_file, 'r') as f:
data_list = f.readlines()
self.txt_data = data_list
self.root_dir = root_dir
def __len__(self):
return len(self.csv_data)
def __getitem__(self, idx):
data = (self.csv_data[idx], self.txt_data[idx])
return data
3.2 迭代器定义
以上可以定义需要的数据类,通过迭代方式取得每一个数据,但是很难实现batch, shuffle或者多线程读取数据,可以通过torch.utils.data.DataLoader来定义一个新的迭代器:
dataiter = DataLoader(myDataset, batch_size = 32, shuffle = True, collate_fn = default_collate)
3.3 图数据读取
torchvision有ImageFolder数据读取类,主要功能是处理图片
调用torchvision.ImageFloder:
dset = ImageFloder(root = 'root_path', transform = None, loader = default_loader)
4 nn.Module
4.1 功能
所有的层结构和损失函数都来自 torch.nn
所有的模型构建都是从基类 nn.Module 继承的
4.2 计算图模板
class net_name(nn.Module):
def __init__(self, other_arguments):
super(net_name, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size)
# 其他层结构
def forward(self, x):
x = self.conv1(x)
return x
上述结构可服用,每次调用就相当于用该计算图定义的相同参数做一次前向传播。
4.3 定义损失函数
调用已经定义好的损失函数:
criterion = nn.CrossEntropyLoss() # 交叉熵损失函数
loss = criterion(output, target)
5 优化
5.1 一阶优化算法
最常用的一阶优化算法:梯度下降
网络的参数更新公式:
5.2 二阶优化算法
包:torch.optim
将需要优化的参数传入,这些参数都必须是Variable,然后传入一些基本设定,比如学习率或动量等。
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01, momentum = 0.9)
在优化之前,需要将梯度归零:optimizer.zeros();
然后反向传播:loss.backward(),自动求导得到每个参数的梯度;
然后参数更新:optimizer.step()。
6 模型的保存和加载
6.1 保存
6.1.1 方式
1.保存整个模型的结构信息和参数信息,保存的对象是模型 model;
2.保存模型的参数,保存的对象是模型的状态 model.state_dict()。
6.1.2 代码
torch.save(model, './model.pth')
torch.save(model.state_dict(), './model_state.pth')
6.2 加载
6.2.1 方式
1.加载完整的模型结构和参数信息,使用 load_model = torch.load(‘model.pth’),在网络较大的时候加载时间较长,存储空间也比较大
2.加载模型参数信息,需要先导入模型的结构,然后通过 model.load_state_dic(torch.load(‘model_state.pth’)) 导入
参考资料
《深度学习入门之PyTorch》廖星宇 编著