(pytorch-深度学习系列)pytorch实现对Fashion-MNIST数据集进行图像分类
pytorch實現對Fashion-MNIST數據集進行圖像分類
導入所需模塊:
import torch import torchvision import torchvision.transforms as transforms import matplotlib.pyplot as plt import time import sys對數據集的操作(讀取數據集):
由于像素值為0到255的整數,所以剛好是uint8所能表示的范圍,包括transforms.ToTensor()在內的一些關于圖片的函數就默認輸入的是uint8型,若不是,可能不會報錯但可能得不到想要的結果。所以,如果用像素值(0-255整數)表示圖片數據,那么一律將其類型設置成uint8,避免不必要的bug
通過torchvision的torchvision.datasets來下載這個數據集。第一次調用時數據集目錄不存在,會自動從網上獲取數據。
獲取標簽:
def get_fashion_mnist_labels(labels):text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]定義畫圖函數:
def use_svg_display():# 用矢量圖顯示display.set_matplotlib_formats('svg')def set_figsize(figsize=(3.5, 2.5)):use_svg_display()# 設置圖的尺寸plt.rcParams['figure.figsize'] = figsizedef show_fashion_mnist(images, labels):use_svg_display()# 這里的_表示我們忽略(不使用)的變量_, figs = plt.subplots(1, len(images), figsize=(12, 12))for f, img, lbl in zip(figs, images, labels):f.imshow(img.view((28, 28)).numpy())f.set_title(lbl)f.axes.get_xaxis().set_visible(False)f.axes.get_yaxis().set_visible(False)plt.show()展示數據集中的前10個樣本:
X, y = [], [] for i in range(10):X.append(mnist_train[i][0])y.append(mnist_train[i][1]) show_fashion_mnist(X, get_fashion_mnist_labels(y))PyTorch的DataLoader允許使用多進程來加速數據讀取
通過參數num_workers來設置4個進程讀取數據:
初始化模型參數:
num_inputs = 784 # 784個樣本 num_outputs = 10 # 分為10類W = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_outputs)), dtype=torch.float) b = torch.zeros(num_outputs, dtype=torch.float) # 模型參數梯度回調 W.requires_grad_(requires_grad=True) b.requires_grad_(requires_grad=True)定義softmax運算:
softmax運算會先通過exp函數對每個元素做指數運算,再對exp矩陣同行元素求和,最后令矩陣每行各元素與該行元素之和相除。這樣一來,最終得到的矩陣每行元素和為1且非負。因此,該矩陣每行都是合法的概率分布。softmax運算的輸出矩陣中的任意一行元素代表了一個樣本在各個輸出類別上的預測概率。
定義模型:
def net(X): # 定義模型return softmax(torch.mm(X.view((-1, num_inputs)), W) + b)def cross_entropy(y_hat, y): # 交叉熵損失函數return - torch.log(y_hat.gather(1, y.view(-1, 1)))def accuracy(y_hat, y): # 定義準確率計算return (y_hat.argmax(dim=1) == y).float().mean().item()這里講一下為什么使用softmax可以將輸出定在(0-9)這樣的離散類別中
因為,模型中使用到的線性規劃層:輸出=輸入*w+b
其中w是一個(輸入,輸出)維度的張量,b是一個(輸出)維度的向量
根據矩陣運算,輸入*w+b的結果就是一個向量,該向量列數為輸出(也就是類別數),而softmax做的,就是將該向量的元素進行歸一化處理,使得其變為概率向量,這樣,該模型的輸出就可以代表樣本為某一類別的概率,其和為1.
訓練模型:
num_epochs, lr = 5, 0.1def sgd(params, lr, batch_size): # 隨機梯度下降算法for param in params:param.data -= lr * param.grad / batch_size # 注意這里更改param時用的param.datadef evaluate_accuracy(data_iter, net):acc_sum, n = 0.0, 0for X, y in data_iter:acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()n += y.shape[0]return acc_sum / ndef train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,params=None, lr=None, optimizer=None):for epoch in range(num_epochs):train_l_sum, train_acc_sum, n = 0.0, 0.0, 0for X, y in train_iter:y_hat = net(X)l = loss(y_hat, y).sum()# 梯度清零if optimizer is not None:optimizer.zero_grad() # 這里我們沒有用到優化器,所以直接對參數進行梯度清零elif params is not None and params[0].grad is not None:for param in params:param.grad.data.zero_()l.backward()if optimizer is None:sgd(params, lr, batch_size)else:optimizer.step() # 簡潔實現將用到優化器這里train_l_sum += l.item()train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0] test_acc = evaluate_accuracy(test_iter, net)print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'% (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr)注意,這里的每一個train_iter是以batch_size個樣本為實例的,所以每一個train_iter包含多個(tensor, type)組合。
訓練完畢進行預測:
X, y = iter(test_iter).next()true_labels = get_fashion_mnist_labels(y.numpy()) pred_labels = get_fashion_mnist_labels(net(X).argmax(dim=1).numpy()) titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)] show_fashion_mnist(X[0:9], titles[0:9])總結
以上是生活随笔為你收集整理的(pytorch-深度学习系列)pytorch实现对Fashion-MNIST数据集进行图像分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 现代中国第一位数学博士是谁?
- 下一篇: PHP框架编写和应用知识点,php框架知