一、库&数据集
1. 数据集简介
- 样本数:60,000
- 样本(图片像素):28*28
- 10个类别:
0 T-shirt/top
1 Trouser
2 Pullover
3 Dress 礼服
4 Coat 外套
5 Sandal 凉鞋
6 Shirt 衬衫
7 Sneaker 运动鞋
8 Bag
9 Ankle boot 高跟鞋
import torchfrom torchvision import datasets, transforms#Transform for the datatransform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5, ))])#training datatrainset = datasets.FashionMNIST('~/.pytorch/F_MNIST_data', download=True, train=True, transform=transform)trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)#test datatestset= datasets.FashionMNIST('~/.pytorch/F_MNIST_data', download=True, train=False, transform=transform)testloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
2. 目标
指标:训练损失低于某一阈值
二、模型的基本框架
1. 搭建网络结构
#方法1)nn.Sequential()model = nn.Sequential(nn.Linear(784, 196)nn.ReLU(),nn.Linear(196, 49),nn.ReLU(),nn.Linear(49, 10))#方法2)封装成类(继承nn.Module)class Classifier(nn.Module):def __init__(self):super().__init__()self.fc1 = nn.Linear(784, 256)self.fc2 = nn.Linear(256, 128)self.fc3 = nn.Linear(128, 64)self.fc4 = nn.Linear(64, 10)def forward(self, x):x = x.view(x.shape[0], -1)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = F.relu(self.fc3(x))x = F.log_softmax(self.fc4(x), dim=1)return x
2. 训练+验证测试
- 目标函数(损失函数)
nn.CrossEntropyLoss()- 优化器(权值更新)
optim.SGD()
optim.Adam()
#目标函数(损失函数)criterion = nn.CrossEntropyLoss() #相当于 nn.LogSoftmax(dim=1) & nn.NLLLoss()#优化器(权值更新)optimizer = optim.SGD(model.parameters(), lr=0.03)#模型训练epoch = 5for e in range(epoch):running_loss = 0for images, labels in trainloader:images = images.view(images.shape[0], -1)optimizer.zero_grad()logits = model(images)loss = criterion(logits, labels)loss.backward()optimizer.step()running_loss += loss.item()print("Training loss: {} \n" .format(running_loss/len(trainloader)))#验证测试%matplotlib inline%config InlineBackend.figure_format = 'retina'import helper #自定义模块dataiter = iter(testloader)images, labels = dataiter.next()img = images[0]img = img.resize_(1, 784) #行向量ps = F.softmax(model(img), dim=1) #model 是nn.Sequantial()网络 缺少输出层#可视化helper.view_classify(img.resize_(1, 28, 28), ps, version='Fashion')

三、模型优化
1. 针对过拟合
- 方法1)早期停止early-stopping@复杂度图
比如8-10次迭代即可 - 方法2)dropout
随机关闭输入(针对中间隐藏层),防止一部分权值“拥兵自重”
#dropout完整代码class Network(nn.Module):def __init__(self):super().__init__()self.fc1 = nn.Linear(784, 196)self.fc2 = nn.Linear(196, 49)self.fc3 = nn.Linear(49, 10)self.dropout = nn.Dropout(p=0.25)def forward(self, x):x = x.view(x.shape[0], -1)x = self.dropout(F.relu(self.fc1(x)))x = self.dropout(F.relu(self.fc2(x)))x = F.log_softmax(self.fc3(x), dim=1)return x#训练模型model = Network()criterion = nn.NLLLoss()optimizer = optim.Adam(model.parameters(), lr=0.002)epochs = 6train_losses, test_losses = [],[]for e in range(epochs):running_loss = 0for images, labels in trainloader:optimizer.zero_grad()log_ps = model(images)loss = criterion(log_ps, labels)loss.backward()optimizer.step()running_loss += loss.item()test_loss = 0accuracy = 0with torch.no_grad():model.eval() #设置dropoutfor images, labels in testloader:log_ps = model(images) #结果维度 64*10test_loss += criterion(log_ps, labels)ps = torch.exp(log_ps)tp_ps, tp_class = ps.topk(1, dim=1) #结果维度 64*1equals = (tp_class == labels.view(*tp_class.shape))accuracy += torch.mean(equals.type(torch.FloatTensor))train_losses.append(running_loss/len(trainloader))test_losses.append(test_loss/len(testloader))model.train()print("{}" .format())#验证测试%matplotlib inline%config InlineBackend.figure_format = 'retina'import helper #自定义模块model.eval() #测试环节,关闭dropoutdataiter = iter(testloader)images, labels = dataiter.next()img = images[0]img = img.view(1, 784) #行向量with torch.no_grad():output = model(img)ps = torch.exp(output)#可视化helper.view_classify(img.view(1, 28, 28), ps, version='Fashion')


