PyTorch学习记录
PyTorch是一个Python机器学习框架
基础语法
张量
Tensors
Tensors很像矩阵、向量,在PyTorch中使用Tensors编码输入和输出
构造
import torchimport numpy as npdata = [[1 , 2 ],[3 , 4 ]] x_data = torch.tensor(data) np_array = np.array(data) x_np = torch.from_numpy(np_array) shape = (2 ,3 ,) rand_tensor = torch.rand(shape) ones_tensor = torch.ones(shape) zeros_tensor = torch.zeros(shape)
训练一个NN
数据集
Datasets
PyTorch提供了一些预加载的数据集
加载数据集
from torch.utils.data import Datasetfrom torchvision import datasetsfrom torchvision.transforms import ToTensortraining_data = datasets.FashionMNIST( root="data" , train=True , download=True , transform=ToTensor() ) train_dataloader = DataLoader(training_data, batch_size=64 )
规范数据集
Tramsforms
数据格式可能不符合算法输入需要,于是需要用Transforms做处理
training_data = datasets.FashionMNIST( root="data" , train=True , download=True , transform=ToTensor(), target_transform=Lambda(lambda y: torch.zeros(10 , dtype=torch.float ).scatter_(0 , torch.tensor(y), value=1 )) )
ToTensor()
的作用是将图片、数组转化为FloatTensor
,将图片像素的值缩放到[0, 1]
torch.zeros(10, dtype=torch.float)
创建了一个10x1的的张量,其内容全为0.0f
scatter_(0, torch.tensor(y), value=1)
的作用是将10x1张量的第y
位设为1
生成NN
Neural Network
获取设备
device = ( "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu" )
NN类
class NeuralNetwork (nn.Module): def __init__ (self ): super ().__init__() self.flatten = nn.Flatten() self.linear_relu_stack = nn.Sequential( nn.Linear(28 *28 , 512 ), nn.ReLU(), nn.Linear(512 , 512 ), nn.ReLU(), nn.Linear(512 , 10 ), ) def forward (self, x ): x = self.flatten(x) logits = self.linear_relu_stack(x) return logits
自动差异化
训练NN最常用的算法是反向传播(back propagation),这是一种根据损失函数(loss function)的梯度(gradient)调整参数的方法
梯度下降法:目标是搜索出一个函数值尽可能小的位置,函数的极小值很有可能是函数的最小值,每次迭代时都将自变量减去 “学习率 x 偏导数”,最后偏导趋近平缓,自变量趋于稳定,且位于极值点处
损失函数
损失函数是用于计算模型输出与目标间的差异,常见的损失函数有:
Loss Function
用途
意义
nn.MSELoss
回归任务
Mean Square Error
nn.NLLLoss
分类
Negative Log Likelihood
nn.CrossEntropyLoss
分类
nn.LogSoftmax + nn.NLLLoss
优化循环
我们需要循环迭代,来调整模型的参数
learning_rate = 1e-3 epochs = 5 loss_fn = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) for t in range (epochs): print (f"Epoch {t+1 } \n-------------------------------" ) train_loop(train_dataloader, model, loss_fn, optimizer) test_loop(test_dataloader, model, loss_fn)
每一个循环被称为一个epoch ,每一个epoch包含两个部分:
训练循环:训练迭代测试集,试图收敛到最佳参数
测试循环:测试模型性能是否有提升
训练循环
batch_size = 64 def train_loop (dataloader, model, loss_fn, optimizer ): size = len (dataloader.dataset) model.train() for batch, (X, y) in enumerate (dataloader): pred = model(X) loss = loss_fn(pred, y) loss.backward() optimizer.step() optimizer.zero_grad() if batch % 100 == 0 : loss, current = loss.item(), batch * batch_size + len (X) print (f"loss: {loss:>7f} [{current:>5d} /{size:>5d} ]" )
测试循环
def test_loop (dataloader, model, loss_fn ): model.eval () size = len (dataloader.dataset) num_batches = len (dataloader) test_loss, correct = 0 , 0 with torch.no_grad(): for X, y in dataloader: pred = model(X) test_loss += loss_fn(pred, y).item() correct += (pred.argmax(1 ) == y).type (torch.float ).sum ().item() test_loss /= num_batches correct /= size print (f"Test Error: \n Accuracy: {(100 *correct):>0.1 f} %, Avg loss: {test_loss:>8f} \n" )
保存和加载模型
torch.save(model, 'model.pth' ) model = torch.load('model.pth' )
强化学习
参考
Learn the Basics