案例源碼鏈接 http://studyai.com/pytorch-1.2/beginner/fanshionmnist_tutorial.html
1、打開PyCharm,創建項目,新建python文件,hello.py
從上到下依次粘貼鏈接的代碼,注意修改如下:
① 添加代碼,其后的所有代碼必須縮進 if __name__ == "__main__":
② transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
改為
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
因為處理的是單通道的灰度圖,而不是三通道。為什么是這兩個數,點擊參考?
2、下載FASHION-MNIST數據,放到項目目錄..\PycharmProjects\untitled4\data\fashiomnist\FashionMNIST\raw,運行程序會自動解壓的。
3、運行程序
【全部程序如下】
import matplotlib.pyplot as plt import numpy as np import torch import torchvision import torchvision.transforms as transforms print("PyTorch Version: ", torch.__version__) print("Torchvision Version: ", torchvision.__version__) # 忽略 warnings import warnings warnings.filterwarnings("ignore") if __name__ == "__main__": ############################### 1 使用 torchvision 加載和規范訓練和測試數據集 batch_size = 16 #transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) trainset = torchvision.datasets.FashionMNIST(root='./data/fashiomnist', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True, num_workers=2) testset = torchvision.datasets.FashionMNIST(root='./data/fashiomnist', train=False, download=True, transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=2) classes = ('T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot') print("訓練集大小:", len(trainloader) * batch_size) print("測試集大小:", len(testloader) * batch_size) ########################################## 展示訓練集中的圖片 # 用於顯示一張圖像的函數 def imshow(img): img = img / 2 + 0.5 # 去歸一化 npimg = img.numpy() plt.imshow(np.transpose(npimg, (1, 2, 0))) # 獲取一個批次的圖像,一次迭代取出batch_size張圖片 dataiter = iter(trainloader) images, labels = dataiter.next() # 顯示一個批次的圖像 imshow(torchvision.utils.make_grid(images)) # 輸出 對應批次圖像的標簽 print(' '.join('%5s' % classes[labels[j]] for j in range(batch_size))) ######################################## 定義網絡模型 import torch.nn as nn import torch.nn.functional as F class Net1(nn.Module): def __init__(self): super(Net1, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.conv2_drop = nn.Dropout2d() self.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) self.bn = nn.BatchNorm2d(20) def forward(self, x): x = F.max_pool2d(self.conv1(x), 2) x = F.relu(x) + F.relu(-x) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) x = self.bn(x) x = x.view(-1, 320) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) x = self.fc2(x) x = F.softmax(x, dim=1) return x class Net2(nn.Module): def __init__(self): super(Net2, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.conv2_drop = nn.Dropout2d() self.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) def forward(self, x): x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) x = self.fc2(x) x = F.log_softmax(x, dim=1) return x class Net3(nn.Module): """ Simple network""" def __init__(self): super().__init__() self.features = nn.Sequential( nn.Conv2d(1, 32, kernel_size=3, padding=1), # 28 nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), # 14 nn.Conv2d(32, 64, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2) # 7 ) self.classifier = nn.Sequential( nn.Dropout(), nn.Linear(64 * 7 * 7, 128), nn.ReLU(inplace=True), nn.Linear(128, 10) ) def forward(self, x): x = self.features(x) x = x.view(x.size(0), 64 * 7 * 7) x = self.classifier(x) return x ################################### 將模型寫入文件並用TensorBoard查看 from tensorboardX import SummaryWriter # 無意義輸入,與MNIST的一個batch數據的shape相同 dummy_input = torch.autograd.Variable(torch.rand(batch_size, 1, 28, 28)) model1 = Net1() print(model1) with SummaryWriter(comment='_fashionmnist_net1') as w: w.add_graph(model1, (dummy_input,)) model2 = Net2() print(model2) with SummaryWriter(comment='_fashionmnist_net2') as w: w.add_graph(model2, (dummy_input,)) model3 = Net3() print(model3) with SummaryWriter(comment='_fashionmnist_net3') as w: w.add_graph(model3, (dummy_input,)) ################################## 定義損失函數和優化器 import torch.optim as optim device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print(device) # 選擇上面定義的任意一個模型 model1,model2,model3,... net = model3.to(device) # or = model2 loss = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) writer = SummaryWriter(comment='_fashionmnist_logs') ########################################################### 計算初始網絡的准確率 correct = 0 total = 0 with torch.no_grad(): for data in testloader: images, labels = data[0].to(device), data[1].to(device) outputs = net(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total)) ##開始訓練 num_epochs = 10 num_batches = len(trainloader) for epoch in range(num_epochs): running_loss = 0.0 for step, data in enumerate(trainloader): n_iter = epoch * num_batches + step images, labels = data[0].to(device), data[1].to(device) # 將梯度清零 optimizer.zero_grad() # 向前傳遞 out = net(images) # 計算損失 loss_value = loss(out, labels) # 向后傳遞 loss_value.backward() # 優化 optimizer.step() # 記錄日志 writer.add_scalar('loss', loss_value.item(), n_iter) running_loss += loss_value.item() if step % 500 == 499: # 每 500 個 mini-batches 就輸出一次訓練信息 print('[%d, %5d] loss: %.3f' % (epoch + 1, step + 1, running_loss / 500)) running_loss = 0.0 writer.close() print('Finished Training') ############################################################ 開始測試 correct = 0 total = 0 with torch.no_grad(): for data in testloader: images, labels = data[0].to(device), data[1].to(device) outputs = net(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total)) ############################################################ 展示每個樣本上的准確率 num_classes = len(classes) class_correct = list(0. for i in range(num_classes)) class_total = list(0. for i in range(num_classes)) with torch.no_grad(): for data in testloader: images, labels = data[0].to(device), data[1].to(device) outputs = net(images) _, predicted = torch.max(outputs, 1) c = (predicted == labels).squeeze() for i in range(batch_size): label = labels[i] class_correct[label] += c[i].item() class_total[label] += 1 for i in range(num_classes): print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i])) ############################################ 展示測試樣本、真實標簽和測試標簽 dataiter = iter(testloader) images, labels = dataiter.next() # print images imshow(torchvision.utils.make_grid(images)) print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(batch_size))) outputs = net(images.to(device)) _, predicted = torch.max(outputs, 1) print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] for j in range(batch_size)))