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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms
torch.manual_seed(42)
transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])
train_dataset = datasets.MNIST( './data', train=True, download=False, transform=transform ) test_dataset = datasets.MNIST( './data', train=False, download=False, transform=transform )
train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=64, shuffle=True ) test_loader = torch.utils.data.DataLoader( test_dataset, batch_size=1000 )
class Net(nn.Module): def __init__(self): super(Net, self).__init__() ''' 1. 初始化一个内部字典 _modules,用于存储子模块(如 nn.Linear、nn.Conv2d 等)。 2. 初始化一个内部字典 _parameters,用于存储模型的可学习参数(如权重和偏置)。 3. 初始化其他内部状态,例如钩子函数、设备信息等。 如果你不调用 super().__init__(),这些基础设施将不会被初始化,导致模型无法正常工作。 ''' self.fc1 = nn.Linear(784, 128) self.fc2 = nn.Linear(128, 64) self.fc3 = nn.Linear(64, 10)
def forward(self, x): x = x.view(-1, 784) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return F.log_softmax(x, dim=1)
model = Net() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001)
def train(epoch): model.train() for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step()
if batch_idx % 100 == 0: print(f'Train Epoch: {epoch} [{batch_idx * len(data)}/{len(train_loader.dataset)}' f' ({100. * batch_idx / len(train_loader):.0f}%)]\tLoss: {loss.item():.6f}')
def test(): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: output = model(data) test_loss += criterion(output, target).item() pred = output.argmax(dim=1, keepdim=True) correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset) accuracy = 100. * correct / len(test_loader.dataset) print(f'\nTest set: Average loss: {test_loss:.4f}, Accuracy: {correct}/{len(test_loader.dataset)} ({accuracy:.2f}%)\n')
for epoch in range(1, 6): train(epoch) test()
torch.save(model.state_dict(), "mnist_model.pth")
model = Net() model.load_state_dict(torch.load("mnist_model.pth")) model.eval()
with torch.no_grad(): sample = test_dataset[0][0].unsqueeze(0) output = model(sample) prediction = output.argmax(dim=1).item() print(f"Predicted digit: {prediction}")
|