Pytorch

数据准备

from torch.utils.data import Dataset,DataLoader
Dataset :构建自己的数据类,需要重写 get 和 len
DataLoader 吐数据的类(包括了 batch 和 shuffle)

1
2
3
4
5
6
7
class MyDataset(Dataset):
	def __init__(self,file):
		self.data = ...
	def __getitem__(self, index):
		return self.data[index]
	def __len__(self):
		return len(self.data)

GPU 计算

1
2
3
torch.cuda.is_available()

x.to('cuda')

梯度计算

函数用 backward() 计算微分,然后对自变量取 gard 得到梯度

定义模型

nn 是神经网络的模块化借口,构建在 autograd 上
四大库:

  • torch.nn.modules
1
2
3
4
5
6
7
8
torch.nn.MSELoss
torch.nn.CrossEntropyLoss 
torch.nn.Conv2d # 封装的是卷积神经网络层
torch.nn.Embedding
torch.nn.LSTM
torch.nn.Linear
torch.nn.dropout
torch.nn.LeakyReLU
  • torch.nn.functional
1
torch.nn.functional.conv2d torch.nn.functional.embedding torch.nn.functional.bilinear
  • torch.nn.parameter :
  • torch.nn.Sequential :

样例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
nn.Linear(input,output)

// 建立自己的模型
class Model(nn.Module):

//初始化
def __init__(self):
	super(Model,self).__init__()
	self.net = nn.Sequential(
		// 类似 keras 的构造
	)

//计算
def forward(self,x):
	return self.net(x)

// 也可以不用 net定义出每一层然后forward时写出计算过程

损失函数

通过一个 model 的 output 和 label 会自动去计算 loss

1
2
torch.nn.MSELoss
torch.nn.CrossEntropyLoss 

Optimization Algorithm

torch.optmi

样例

1
2
3
4
5
6
7
// 需要定义优化器参数
optimizer = torch.optim.SGD(model.parameters(), lr, momentum = 0)

// 步骤
optimizer.zero_gard() //重置模型参数梯度
loss.backward() //反向传播
optimizer.step() //调整模型参数

完整过程

 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
// 准备和定义过程
dataset = MyDataset(file)
tr_set = DataLoader(dataset, batch_size = 16, shuffle = True)
model = MyModel().to(device)
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr = 0.1)

// 神经网络训练循环
for epoch in range(n_epochs):
	model.train() //设置为 train mode 
	for x, y in tr_set:
		optimzer.zero_gard()
		x, y = x.to(device), y.to(device)
		pred = model(x)// forward 计算
		loss = criterion(pred,y)//代价估算
		loss = backward()
		optimzer.step()//更新参数
// 神经网络验证循环
model.eval() //设置为 evaluation mode
total_loss = 0
for x, y in dv_set:
	x, y = x.to(device), y.to(device)
	//python 异常处理用法目标类要重载 __enter__  __exit__
	with torch.no_grad()://关闭梯度计算
		pred = model(x)
		loss = criterion(pred,y)
	total_loss += loss.cpu().item * len(x)//计算 loss
	//cpu 是从 cuda 上取数据item 是把 tensor 转化为 scalar
	avg_loss = total_loss / len(dev_set.dataset) //计算平均 loss
// 神经网络测试循环
model.eval() //设置为 evaluation mode
preds = []
for x in tt_set:
	x= x.to(device)
	with torch.no_grad():
		pred = model(x)
		preds.append(pred.cpu())
// 设置不同模式是因为不同模型在不同阶段做的事情不一样
// 除训练外不计算梯度是因为不希望模型学习这些数据

//保存模型
torch.save(model.state_dict(),path)
//加载模型
ckpt = torch.load(path)
model.load_state_dict(ckpt)