Sequential:是torch.nn自带的功能函数,实乃相见恨晚,它相当于把神经网络的各层装进一个容器,层与层之间通道数的变化也更加清晰。以基于线性降维的全连接对手写数字识别为例:
代码:
import torch import torch.nn as nn from torchvision import datasets from torchvision import transforms from torch.utils.data import DataLoader import matplotlib.pyplot as plt import sys # 雷同的代码相应注释可查 “从梦到西洲” 早期博客 # 模型加载和进行数据运算可以选择GPU device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # ---------------准备数据集-------------------- batch_size = 100 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) train_dataset = datasets.MNIST(root="../Hello/dataset/mnist", train=True, download=True, transform=transform) test_dataset = datasets.MNIST(root="../Hello/dataset/mnist", train=False, download=True, transform=transform) print(len(train_dataset)) print(len(test_dataset)) train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size) test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size) # ----------- # -----------struct model-------------- # Net是torch.nn.Module的子类 class Net(nn.Module): # __init__初始类中数据成员 def __init__(self, *args): # super()函数的常见的用途是通过构建子类来扩展先前构造的类的功能,从而节省重写子类的这些方法的时间 super(Net, self).__init__() # Sequential可以将多层整合到一起被调用 self.model = nn.Sequential( nn.Linear(784, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 128), nn.ReLU(), nn.Linear(128, 64), nn.ReLU(), nn.Linear(64, 10) ) # forward是定义在每次调用时执行的计算 def forward(self, x): x = x.view(-1, 784) x = self.model(x) return x model = Net() model.to(device) # ------------------------------------ # -----------loss optimizer-------------- criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # ------------------------------------ # -----------train test-------------- train_loss = [] def train(epoch): running_loss = 0.0 for batch_idx, data in enumerate(train_loader): # inputs,target=data inputs, target = data[0].to(device), data[1].to(device) optimizer.zero_grad() # 梯度清零 outputs = model(inputs) # 加载模型 loss = criterion(outputs, target) # 计算损失 loss.backward() # 反向传播 optimizer.step() # 梯度更新 running_loss += loss # 损失叠加 if batch_idx % 600 == 599: train_loss.append((running_loss / 600).item()) # 计算每一轮的损失 print("%d loss: %.3f" % (epoch + 1, running_loss/ 600)) running_loss = 0.0 acc = [] def test(epoch): correct = 0 total = 0 with torch.no_grad(): for data in test_loader: # images,labels=data images, labels = data[0].to(device), data[1].to(device) ouputs = model(images) _, predicted = torch.max(ouputs.data, dim=1) correct += (predicted == labels).sum().item() total += labels.size(0) print("accurancy: %.3f %%" % (correct / total * 100)) acc.append((correct / total) * 100) if __name__ == '__main__': for epoch in range(150): train(epoch) test(epoch) # sys.exit(0) epochs = [] for i in range(0, 150): epochs.append(i) # 刻画测试数据集准确率和轮数的关系 plt.xlabel('epochs') plt.xlabel('acc') plt.plot(epochs, acc) plt.show() # 刻画训练损失和轮数的关系 plt.xlabel('epochs') plt.xlabel('train_loss') plt.plot(epochs, train_loss) plt.show() # ------------------------------------
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)