好了,我們來實戰演練。你將使用 Fashion-MNIST 數據集。對於神經網絡來說,MNIST 的規模很小,可以輕鬆地達到 97% 的準確率。Fashion-MNIST 包括很多 28x28 灰色服飾圖像。它比 MNIST 更復雜,也更貼近實際現實需求。
你要在這個 notebook 裏構建神經網絡。其實你可以用 Part 3 notebook 裏的代碼,但是這樣就學不到任何知識了。只有自己編寫代碼並確保代碼能運行,才能實現最佳學習效果。當然,你可以參考 Part 3 notebook。
首先,通過 torchvision 加載數據集。
import torch
from torchvision import datasets, transforms
import helper
# Define a transform to normalize the data
transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))])
# Download and load the training data
trainset = datasets.FashionMNIST('~/.pytorch/F_MNIST_data/', download=True, train=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
# Download and load the test data
testset = datasets.FashionMNIST('~/.pytorch/F_MNIST_data/', download=True, train=False, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=True)
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz
Processing…
Done!
下面是一個圖像示例。
image, label = next(iter(trainloader))
helper.imshow(image[0,:]);
構建網絡
你要先定義網絡。和 MNIST 一樣,每個圖像是 28x28 = 784 像素,並且有 10 個類別。你應該至少包含一個隱藏層。建議對層級使用 ReLU 激活函數,並返回前向傳播的對數或 log-softmax。你可以決定添加多少個層級以及這些層級的大小。
# TODO: Define your network architecture here
from torch import nn, optim
import torch.nn.functional as F
class Classifier_fashion(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Linear(784,256)
self.layer2 = nn.Linear(256,128)
self.layer3 = nn.Linear(128,64)
self.layer4 = nn.Linear(64,10)
def forward(self, x):
x = x.view(x.shape[0],-1)
x = F.relu(self.layer1(x))
x = F.relu(self.layer2(x))
x = F.relu(self.layer3(x))
x = F.log_softmax(self.layer4(x), dim=1)
return x
訓練網絡
現在,來試試創建並訓練網絡。首先,你需要定義條件(例如 nn.CrossEntropyLoss
)和優化器(通常是 optim.SGD
或 optim.Adam
)。
然後編寫訓練代碼。你可以參考這個流程:
*通過網絡進行正向傳遞以獲取logits
*使用 logits 計算損失
- 通過
loss.backward()
在網絡中反向傳播以計算梯度 - 使用優化器更新權重
通過調整參數(隱藏單元、學習速率等),你應該能夠使訓練損失低於 0.4。
# TODO: Create the network, define the criterion and optimizer
model = Classifier_fashion()
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.parameters(),lr=0.003)
# TODO: Train the network here
epochs = 5
for e in range(epochs):
running_loss = 0
for images, labels in trainloader:
log_ps = model(images)
loss = criterion(log_ps, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
print("Trainning loss:{}".format(running_loss/len(trainloader)))
Trainning loss:0.521082957575062
Trainning loss:0.3933480036442976
Trainning loss:0.358206258828579
Trainning loss:0.3316666531219665
Trainning loss:0.31710777687492653
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import helper
# Test out your network!
dataiter = iter(testloader)
images, labels = dataiter.next()
img = images[0]
# Convert 2D image to 1D vector
img = img.resize_(1, 784)
# TODO: Calculate the class probabilities (softmax) for img
ps = torch.exp(model(img))
# Plot the image and probabilities
helper.view_classify(img.resize_(1, 28, 28), ps, version='Fashion')