Pytorch神经网络构建与训练测试全流程入门
最基本的简单神经网络有三种构建方式:
1. 手动构建一个类
2. 用 torch.nn.Sequential()
3. 用 torch.nn.Sequential( OrderedDict )
from torch import nn # 第1种构建方法,最灵活 class Network(nn.Module): def __init__(self): super().__init__() # Inputs to hidden layer linear transformation self.hidden = nn.Linear(784, 256) # Output layer, 10 units - one for each digit self.output = nn.Linear(256, 10) # Define sigmoid activation and softmax output self.sigmoid = nn.Sigmoid() self.softmax = nn.Softmax(dim=1) def forward(self, x): # Pass the input tensor through each of our operations x = self.hidden(x) x = self.sigmoid(x) x = self.output(x) x = self.softmax(x) return x nn1 = Network() nn1
'''结果:
Network( (hidden): Linear(in_features=784, out_features=256, bias=True) (output): Linear(in_features=256, out_features=10, bias=True) (sigmoid): Sigmoid() (softmax): Softmax(dim=1) )
''' # 第2种构建方法,Sequential类 input_size = 784 hidden_size = [128, 64] output_size = 10 nn2 = nn.Sequential( nn.Linear(input_size, hidden_size[0]), nn.ReLU(), nn.Linear(hidden_size[0], hidden_size[1]), nn.ReLU(), nn.Linear(hidden_size[1], output_size), nn.Softmax(dim=1) ) nn2 '''结果:
Sequential( (0): Linear(in_features=784, out_features=128, bias=True) (1): ReLU() (2): Linear(in_features=128, out_features=64, bias=True) (3): ReLU() (4): Linear(in_features=64, out_features=10, bias=True) (5): Softmax(dim=1) )
'''
# 第3种构建方法,同样是Sequential类,但是传入字典类型,更加易用 from collections import OrderedDict nn3 = nn.Sequential(OrderedDict([ ('fc1', nn.Linear(input_size, hidden_size[0])), ('relu1', nn.ReLU()), ('fc2', nn.Linear(hidden_size[0], hidden_size[1])), ('relu2', nn.ReLU()), ('output', nn.Linear(hidden_size[1], output_size)), ('softmax', nn.Softmax(dim=1)) ])) nn3
'''结果:
Sequential(
(fc1): Linear(in_features=784, out_features=128, bias=True)
(relu1): ReLU()
(fc2): Linear(in_features=128, out_features=64, bias=True)
(relu2): ReLU()
(output): Linear(in_features=64, out_features=10, bias=True)
(softmax): Softmax(dim=1)
)
'''
然后查看模型结构的方法分别如下:
nn1 = Network() nn1 print(nn1.hidden) print(nn2[2]) print(nn3[4]) print(nn3.output) ''' Linear(in_features=784, out_features=256, bias=True) Linear(in_features=128, out_features=64, bias=True) Linear(in_features=64, out_features=10, bias=True) Linear(in_features=64, out_features=10, bias=True) '''
模型训练与测试的全流程。
案例1:最简单的学习模型——线性回归。
## linear regression simply implement # https://blog.csdn.net/qq_27492735/article/details/89707150 import torch from torch import nn, optim from torch.autograd import Variable # 读取训练数据,这里不读取了,直接定义一个最简单的数据x及其标签y x = Variable(torch.Tensor([[1, 2], [3, 4], [4, 2]]), requires_grad=False) y = Variable(torch.Tensor([[3], [7], [6]]), requires_grad=False) # model constract def model(): # 模型 net = nn.Sequential( nn.Linear(2, 4), nn.ReLU6(), nn.Linear(4, 3), nn.ReLU(), nn.Linear(3, 1) ) # 优化器与损失函数 optimizer = optim.Adam(net.parameters(), lr=0.01) loss_fun =nn.MSELoss() # 迭代步骤 for i in range(300): # 1 前向传播 out = net(x) # 2 计算损失 loss = loss_fun(out, y) print(loss) # 3 梯度清零 optimizer.zero_grad() # 4 反向传播 loss.backward() # 5 更新优化器 optimizer.step() # 计算预测值 print(net(x)) # 保存训练好的模型(参数) # torch.save(net, 'simplelinreg.npy') return net net = model()
以上模型大概是最简单的了,毕竟没有比线性回归更简单的机器学习模型了。
案例2: RNN循环神经网络的搭建以及训练流程。
我通常把pytorch训练神经网络细分为8个步骤,或者3个部分。
第1部分:声明 1 模型 Model、2 损失函数 Loss function、3 优化器 Optimizer
第2部分:读取数据通常都是采用DataLoader做的,不过简单的任务直接用 numpy 定义就行。比较大规模的任务都用DataLoader进行批量处理。4 前向传播。
第3部分:更新参数,通常是固定的三个操作 5 计算损失函数 6 optimizer.zero_grad() 、7 loss.backward()、8 optimizer.step()。
""" torch.nn.RNN() input_size: hidden_size: num_layers: nonlinearity: 指定非线性函数的使用[tanh, relu],默认tanh bias: True default, dropout:如果非%gui除了最后一层之外其他层输出都会套上一个drouput层 batch_first: if True, Tensor的shape就是(batch, seq, feature),输出也是 bidirectional: False default """ import numpy as np import matplotlib.pyplot as plt import torch from torch import nn # from torch.autograd import Variable """ PyTorch基础入门七:PyTorch搭建循环神经网络(RNN) https://blog.csdn.net/out_of_memory_error/article/details/81456501 Example:曲线拟合。拟合一个cos函数 """ class RNNCurveFitting(nn.Module): def __init__(self, INPUT_SIZE): super(RNNCurveFitting, self).__init__() self.rnn = nn.RNN( input_size=INPUT_SIZE, hidden_size=32, num_layers=1, batch_first=True ) self.out = nn.Linear(32, 1) def forward(self, x, h_state): r_out, h_state = self.rnn(x, h_state) outs = [] for time in range(r_out.size(1)): outs.append(self.out(r_out[:, time, :])) return torch.stack(outs, dim=1), h_state # hyper parameters TIME_STEP=10 INPUT_SIZE=1 LR = 0.02 # Step1 model model = RNNCurveFitting(INPUT_SIZE) # Step2 3 loss function and optimizer loss_func = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=LR) h_state = None for step in range(300): start, end = step * np.pi, (step+1)*np.pi steps = np.linspace(start, end, TIME_STEP, dtype=np.float32) x_np = np.sin(steps) y_np = np.cos(steps) # Step (4) 如果用的DataLoader则不需要这一步骤, read data, from_numpy: 数组转换成张量,所得tensor和原array共享内存 x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis]) y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis]) # x = Variable(torch.from_numpy(x_np[np.newaxis, :, np.newaxis])) # y = Variable(torch.from_numpy(y_np[np.newaxis, :, np.newaxis])) # Step 4 前向传播 prediction, h_state = model(x, h_state) h_state = h_state.data # Step 5 6 7 8 loss = loss_func(prediction, y) optimizer.zero_grad() loss.backward() optimizer.step() plt.plot(steps, y_np.flatten(), 'r-') plt.plot(steps, prediction.data.numpy().flatten(), 'b-') plt.show()
案例3:DataLoader的使用。
首先用 torchvision.datasets.MNIST 数据集为例
import torchvision import torch import torchvision.transforms as transforms import torchvision train_set = torchvision.datasets.MNIST(root="./mnist_data",train=True,download=True) test_set = torchvision.datasets.MNIST(root="./mnist_data",train=False,download=True) #pil型对象显示 print(test_set.classes) print(test_set[0]) for i in range(10): img,label=test_set[i] print(test_set.classes[label]) img.show() ''' ['0 - zero', '1 - one', '2 - two', '3 - three', '4 - four', '5 - five', '6 - six', '7 - seven', '8 - eight', '9 - nine'] (<PIL.Image.Image image mode=L size=28x28 at 0x290E792BE80>, 7) ''' batch_size = 256 # Data loader train_loader = torch.utils.data.DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True) test_loader = torch.utils.data.DataLoader(dataset=test_set, batch_size=batch_size, shuffle=False)
end