添加softmax层_PyTorch入门之100行代码实现softmax回归分类
1. 使用pytorch實現(xiàn)softmax回歸模型
使用pytorch可以更加便利的實現(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 = 訓練集, False = 測試集 #download : True = 從互聯(lián)網(wǎng)上下載數(shù)據(jù)集,并把數(shù)據(jù)集放在root目錄下. 如果數(shù)據(jù)集之前下載過,將處理過的數(shù)據(jù)(minist.py中有相關函數(shù))放在processed文件夾下 #transform = transforms.ToTensor():使所有數(shù)據(jù)轉換為Tensor然后是生成一個迭代器,用來讀取數(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類型,每個批量加載多少個數(shù) #shuffle:bool類型,每個學習周期都打亂順序 #num_workers:int類型,加載數(shù)據(jù)時使用多少子進程。默認值為0. #collate_fn:定義如何取樣本,可通過定義自己的函數(shù)來實現(xiàn)。 #pin_memory:鎖頁內存處理。 #drop_last:bool類型,如果有剩余的樣本,True表示丟棄;Flase表示不丟棄1.2 定義和初始化模型
由softmax回歸模型的定義可知,softmax回歸模型只有權重參數(shù)和偏差參數(shù)。因此可以使用神經(jīng)網(wǎng)絡子模塊中的線性模塊。
使用torch.nn中的init可以快速的初始化參數(shù)。我們令權重參數(shù)為均值為0,標準差為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運算和交叉熵損失函數(shù)
分開定義softmax運算和交叉熵損失函數(shù)會造成數(shù)值不穩(wěn)定。因此PyTorch提供了一個具有良好數(shù)值穩(wěn)定性且包括softmax運算和交叉熵計算的函數(shù)。
loss = nn.CrossEntropyLoss()1.4 定義優(yōu)化算法
依然使用小批量隨機梯度下降作為優(yōu)化算法。定義學習率為0.1。
optimizer = torch.optim.SGD(net.parameters(),lr=0.01)1.5 計算分類準確率
計算準確率的原理:
我們把預測概率最大的類別作為輸出類別,如果它與真實類別y一致,說明預測正確。分類準確率就是正確預測數(shù)量與總預測數(shù)量之比首先我們需要得到預測的結果。
從一組預測概率(變量y_hat)中找出最大的概率對應的索引(索引即代表了類別)
#argmax(f(x))函數(shù),對f(x)求最大值所對應的點x。我們令f(x)= dim=1,即可實現(xiàn)求所有行上的最大值對應的索引。 A = y_hat.argmax(dim=1) #最終輸出結果為一個行數(shù)與y_hat相同的列向量然后我們需要將得到的最大概率對應的類別與真實類別(y)比較,判斷預測是否是正確的
B = (y_hat.argmax(dim=1)==y).float() #由于y_hat.argmax(dim=1)==y得到的是ByteTensor型數(shù)據(jù),所以我們通過.float()將其轉換為浮點型Tensor()最后我們需要計算分類準確率
我們知道y_hat的行數(shù)就對應著樣本總數(shù),所以,對B求平均值得到的就是分類準確率
(y_hat.argmax(dim=1)==y).float().mean()上一步最終得到的數(shù)據(jù)為tensor(x)的形式,為了得到最終的pytorch number,需要對其進行下一步操作
(y_hat.argmax(dim=1)==y).float().mean().item() #pytorch number的獲取統(tǒng)一通過.item()實現(xiàn)整理一下,得到計算分類準確率函數(shù)
def accuracy(y_hat,y):return (y_hat.argmax(dim=1).float().mean().item())作為推廣,該函數(shù)還可以評價模型net在數(shù)據(jù)集data_iter上的準確率。
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()#計算準確判斷的數(shù)量n +=y.shape[0]#通過shape[0]獲取y的零維度(列)的元素數(shù)量return right_sum/n1.6 訓練模型
num_epochs = 5 #一共進行五個學習周期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ù)的值=每個樣本的損失函數(shù)值的和。 optimizer.zero_grad() #對優(yōu)化函數(shù)梯度清零l.backward() #對損失函數(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) #測試集的準確率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)訓練屬實是有點慢,只訓練了五個周期。 訓練結果:
1.7 預測
使用訓練好的模型對測試集進行預測
做一個模型的最終目的當然不是訓練了,所以來預測一下試試。
#將樣本的類別數(shù)字轉換成文本 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是一個列表,所以有了for循環(huán)獲取這個列表對應的文本列表#顯示圖像 def show_fashion_mnist(images,labels):display.set_matplotlib_formats('svg')#繪制矢量圖_,figs = plt.subplots(1,len(images),figsize=(12,12))#設置添加子圖的數(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()#從測試集中獲得樣本和標簽 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])預測結果:
完整程序
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)#定義一個輸入層#定義向前傳播(在這個兩層網(wǎng)絡中,它也是輸出層)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 #一共進行五個學習周期#計算準確率 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()#計算準確判斷的數(shù)量n +=y.shape[0]#通過shape[0]獲取y的零維度(列)的元素數(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是一個列表,所以有了for循環(huán)獲取這個列表對應的文本列表def show_fashion_mnist(images,labels):display.set_matplotlib_formats('svg')#繪制矢量圖_,figs = plt.subplots(1,len(images),figsize=(12,12))#設置添加子圖的數(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ù)的值=每個樣本的損失函數(shù)值的和。 optimizer.zero_grad() #對優(yōu)化函數(shù)梯度清零l.backward() #對損失函數(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) #測試集的準確率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])最后
在學習Python一年中,收集了很多Python學習資料,在這里整理一下,分享給各位!
Python入門、數(shù)據(jù)分析、爬蟲、運維、機器學習方面的學習資料干貨 | Python學習資源整理分享?mp.weixin.qq.com如果覺得本文還可以,還請各位點個贊。
總結
以上是生活随笔為你收集整理的添加softmax层_PyTorch入门之100行代码实现softmax回归分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lzw编码过程详解_编码拓展——封装、编
- 下一篇: 原生编辑器_免费开源的GIF制作神器,可