添加softmax层_PyTorch入门之100行代码实现softmax回归分类
1. 使用pytorch實(shí)現(xiàn)softmax回歸模型
使用pytorch可以更加便利的實(shí)現(xiàn)softmax回歸模型。
1.1 獲取和讀取數(shù)據(jù)
讀取小批量數(shù)據(jù)的方法:
首先是獲取數(shù)據(jù),pytorch可以通過以下代碼很方便的獲取Fashion-MNIST數(shù)據(jù)集。
mnist_train = torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=True,download=True,transform=transforms.ToTensor())mnist_test = torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=False,download=True,transform=transforms.ToTensor())#參數(shù)#root : processed/training.pt 和 processed/test.pt 的主目錄 #train : True = 訓(xùn)練集, False = 測(cè)試集 #download : True = 從互聯(lián)網(wǎng)上下載數(shù)據(jù)集,并把數(shù)據(jù)集放在root目錄下. 如果數(shù)據(jù)集之前下載過,將處理過的數(shù)據(jù)(minist.py中有相關(guān)函數(shù))放在processed文件夾下 #transform = transforms.ToTensor():使所有數(shù)據(jù)轉(zhuǎn)換為Tensor然后是生成一個(gè)迭代器,用來讀取數(shù)據(jù)
#生成迭代器 train_iter = torch.utils.data.DataLoader(mnist_train,batch_size=batch_size,shuffle = True,num_workers = 0)test_iter = torch.utils.data.DataLoader(mnist_test,batch_size = batch_size,shuffle=False,num_workers=0) #參數(shù)#dataset:Dataset類型,從其中加載數(shù)據(jù) #batch_size:int類型,每個(gè)批量加載多少個(gè)數(shù) #shuffle:bool類型,每個(gè)學(xué)習(xí)周期都打亂順序 #num_workers:int類型,加載數(shù)據(jù)時(shí)使用多少子進(jìn)程。默認(rèn)值為0. #collate_fn:定義如何取樣本,可通過定義自己的函數(shù)來實(shí)現(xiàn)。 #pin_memory:鎖頁內(nèi)存處理。 #drop_last:bool類型,如果有剩余的樣本,True表示丟棄;Flase表示不丟棄1.2 定義和初始化模型
由softmax回歸模型的定義可知,softmax回歸模型只有權(quán)重參數(shù)和偏差參數(shù)。因此可以使用神經(jīng)網(wǎng)絡(luò)子模塊中的線性模塊。
使用torch.nn中的init可以快速的初始化參數(shù)。我們令權(quán)重參數(shù)為均值為0,標(biāo)準(zhǔn)差為0.01的正態(tài)分布。偏差為0。
init.normal_(net.linear.weight, mean=0, std=0.01) init.constant_(net.linear.bias, val=0)1.3 softmax運(yùn)算和交叉熵?fù)p失函數(shù)
分開定義softmax運(yùn)算和交叉熵?fù)p失函數(shù)會(huì)造成數(shù)值不穩(wěn)定。因此PyTorch提供了一個(gè)具有良好數(shù)值穩(wěn)定性且包括softmax運(yùn)算和交叉熵計(jì)算的函數(shù)。
loss = nn.CrossEntropyLoss()1.4 定義優(yōu)化算法
依然使用小批量隨機(jī)梯度下降作為優(yōu)化算法。定義學(xué)習(xí)率為0.1。
optimizer = torch.optim.SGD(net.parameters(),lr=0.01)1.5 計(jì)算分類準(zhǔn)確率
計(jì)算準(zhǔn)確率的原理:
我們把預(yù)測(cè)概率最大的類別作為輸出類別,如果它與真實(shí)類別y一致,說明預(yù)測(cè)正確。分類準(zhǔn)確率就是正確預(yù)測(cè)數(shù)量與總預(yù)測(cè)數(shù)量之比首先我們需要得到預(yù)測(cè)的結(jié)果。
從一組預(yù)測(cè)概率(變量y_hat)中找出最大的概率對(duì)應(yīng)的索引(索引即代表了類別)
#argmax(f(x))函數(shù),對(duì)f(x)求最大值所對(duì)應(yīng)的點(diǎn)x。我們令f(x)= dim=1,即可實(shí)現(xiàn)求所有行上的最大值對(duì)應(yīng)的索引。 A = y_hat.argmax(dim=1) #最終輸出結(jié)果為一個(gè)行數(shù)與y_hat相同的列向量然后我們需要將得到的最大概率對(duì)應(yīng)的類別與真實(shí)類別(y)比較,判斷預(yù)測(cè)是否是正確的
B = (y_hat.argmax(dim=1)==y).float() #由于y_hat.argmax(dim=1)==y得到的是ByteTensor型數(shù)據(jù),所以我們通過.float()將其轉(zhuǎn)換為浮點(diǎn)型Tensor()最后我們需要計(jì)算分類準(zhǔn)確率
我們知道y_hat的行數(shù)就對(duì)應(yīng)著樣本總數(shù),所以,對(duì)B求平均值得到的就是分類準(zhǔn)確率
(y_hat.argmax(dim=1)==y).float().mean()上一步最終得到的數(shù)據(jù)為tensor(x)的形式,為了得到最終的pytorch number,需要對(duì)其進(jìn)行下一步操作
(y_hat.argmax(dim=1)==y).float().mean().item() #pytorch number的獲取統(tǒng)一通過.item()實(shí)現(xiàn)整理一下,得到計(jì)算分類準(zhǔn)確率函數(shù)
def accuracy(y_hat,y):return (y_hat.argmax(dim=1).float().mean().item())作為推廣,該函數(shù)還可以評(píng)價(jià)模型net在數(shù)據(jù)集data_iter上的準(zhǔn)確率。
def net_accurary(data_iter,net):right_sum,n = 0.0,0for X,y in data_iter:#從迭代器data_iter中獲取X和yright_sum += (net(X).argmax(dim=1)==y).float().sum().item()#計(jì)算準(zhǔn)確判斷的數(shù)量n +=y.shape[0]#通過shape[0]獲取y的零維度(列)的元素?cái)?shù)量return right_sum/n1.6 訓(xùn)練模型
num_epochs = 5 #一共進(jìn)行五個(gè)學(xué)習(xí)周期def train_softmax(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary):for epoch in range(num_epochs):#損失值、正確數(shù)量、總數(shù) 初始化。train_l_sum,train_right_sum,n= 0.0,0.0,0for X,y in train_iter:y_hat = net(X)l = loss(y_hat,y).sum()#數(shù)據(jù)集損失函數(shù)的值=每個(gè)樣本的損失函數(shù)值的和。 optimizer.zero_grad() #對(duì)優(yōu)化函數(shù)梯度清零l.backward() #對(duì)損失函數(shù)求梯度optimizer(params,lr,batch_size)train_l_sum += l.item()train_right_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0]test_acc = net_accurary(test_iter, net) #測(cè)試集的準(zhǔn)確率print('epoch %d, loss %.4f, train right %.3f, test acc %.3f' % (epoch + 1, train_l_sum / n, train_right_sum / n, test_acc))train_softmax(net,train_iter,test_iter,cross_entropy,num_epochs,batch_size,optimizernet_accurary,net_accurary)訓(xùn)練屬實(shí)是有點(diǎn)慢,只訓(xùn)練了五個(gè)周期。 訓(xùn)練結(jié)果:
1.7 預(yù)測(cè)
使用訓(xùn)練好的模型對(duì)測(cè)試集進(jìn)行預(yù)測(cè)
做一個(gè)模型的最終目的當(dāng)然不是訓(xùn)練了,所以來預(yù)測(cè)一下試試。
#將樣本的類別數(shù)字轉(zhuǎn)換成文本 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]#labels是一個(gè)列表,所以有了for循環(huán)獲取這個(gè)列表對(duì)應(yīng)的文本列表#顯示圖像 def show_fashion_mnist(images,labels):display.set_matplotlib_formats('svg')#繪制矢量圖_,figs = plt.subplots(1,len(images),figsize=(12,12))#設(shè)置添加子圖的數(shù)量、大小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()#從測(cè)試集中獲得樣本和標(biāo)簽 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())#將真實(shí)標(biāo)簽和預(yù)測(cè)得到的標(biāo)簽加入到圖像上 titles = [true + 'n' + pred for true, pred in zip(true_labels, pred_labels)]show_fashion_mnist(X[0:9], titles[0:9])預(yù)測(cè)結(jié)果:
完整程序
import torch from torch import nn from torch.nn import init import numpy as np import sys sys.path.append("..") import torchvision from IPython import display from numpy import argmax import torchvision.transforms as transforms from time import time import matplotlib.pyplot as plt import numpy as npbatch_size =256mnist_train = torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=True,download=True,transform=transforms.ToTensor())mnist_test = torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=False,download=True,transform=transforms.ToTensor())#生成迭代器 train_iter = torch.utils.data.DataLoader(mnist_train,batch_size=batch_size,shuffle = True,num_workers = 4)test_iter = torch.utils.data.DataLoader(mnist_test,batch_size = batch_size,shuffle=False,num_workers=4)num_inputs = 784 num_outputs = 10class LinearNet(nn.Module):def __init__(self,num_inputs,num_outputs):super(LinearNet,self).__init__()self.linear = nn.Linear(num_inputs,num_outputs)#定義一個(gè)輸入層#定義向前傳播(在這個(gè)兩層網(wǎng)絡(luò)中,它也是輸出層)def forward(self,x):y = self.linear(x.view(x.shape[0],-1))#將x換形為y后,再繼續(xù)向前傳播return ynet = LinearNet(num_inputs,num_outputs)#初始化參數(shù) init.normal_(net.linear.weight, mean=0, std=0.01) init.constant_(net.linear.bias, val=0) #損失函數(shù) loss = nn.CrossEntropyLoss()#優(yōu)化函數(shù) optimizer = torch.optim.SGD(net.parameters(),lr=0.01)num_epochs = 5 #一共進(jìn)行五個(gè)學(xué)習(xí)周期#計(jì)算準(zhǔn)確率 def net_accurary(data_iter,net):right_sum,n = 0.0,0for X,y in data_iter:#從迭代器data_iter中獲取X和yright_sum += (net(X).argmax(dim=1)==y).float().sum().item()#計(jì)算準(zhǔn)確判斷的數(shù)量n +=y.shape[0]#通過shape[0]獲取y的零維度(列)的元素?cái)?shù)量return right_sum/ndef 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]#labels是一個(gè)列表,所以有了for循環(huán)獲取這個(gè)列表對(duì)應(yīng)的文本列表def show_fashion_mnist(images,labels):display.set_matplotlib_formats('svg')#繪制矢量圖_,figs = plt.subplots(1,len(images),figsize=(12,12))#設(shè)置添加子圖的數(shù)量、大小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()def train_softmax(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary):for epoch in range(num_epochs):#損失值、正確數(shù)量、總數(shù) 初始化。train_l_sum,train_right_sum,n= 0.0,0.0,0for X,y in train_iter:y_hat = net(X)l = loss(y_hat,y).sum()#數(shù)據(jù)集損失函數(shù)的值=每個(gè)樣本的損失函數(shù)值的和。 optimizer.zero_grad() #對(duì)優(yōu)化函數(shù)梯度清零l.backward() #對(duì)損失函數(shù)求梯度optimizer.step()train_l_sum += l.item()train_right_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0]test_acc = net_accurary(test_iter, net) #測(cè)試集的準(zhǔn)確率print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f' % (epoch + 1, train_l_sum / n, train_right_sum / n, test_acc))train_softmax(net,train_iter,test_iter,loss,num_epochs,batch_size,optimizer,net_accurary)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])最后
在學(xué)習(xí)Python一年中,收集了很多Python學(xué)習(xí)資料,在這里整理一下,分享給各位!
Python入門、數(shù)據(jù)分析、爬蟲、運(yùn)維、機(jī)器學(xué)習(xí)方面的學(xué)習(xí)資料干貨 | Python學(xué)習(xí)資源整理分享?mp.weixin.qq.com如果覺得本文還可以,還請(qǐng)各位點(diǎn)個(gè)贊。
總結(jié)
以上是生活随笔為你收集整理的添加softmax层_PyTorch入门之100行代码实现softmax回归分类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lzw编码过程详解_编码拓展——封装、编
- 下一篇: 原生编辑器_免费开源的GIF制作神器,可