Pytorch筆記之 多層感知機實現MNIST資料集分類
前言
複雜的神經網路也是由許多神經元組成,在深度學習領域,神經元即感知機。深度學習透過許多感知機,儘可能的學習一個任務的複雜數學表示。神經網路在模擬生物神經元時,創造性的引入非線性的函式,透過判斷是否達到閾值,來覺得訊號是否輸出,完成資訊傳遞。因此,在階躍函式的基礎上,進一步最佳化,擴充,得到sigmoid啟用函式、Relu、leak ReLu等,細細品味,你將發現這構思的巧妙性、合理性。
一、Torch相關包介紹
torch.nn :完成神經網路一些相關操作,包含了在計算機視覺任務中常用到的卷積,池化等一些列API介面實現。
torch.nn.fubctional : 可以比nn更進一步接觸實現底層程式碼的修改。
torch.nn.optim:最佳化器,提供了學習率設定,及更好的梯度下降方式的選擇。
torchvision:計算機視覺任務的工具,提供了常用的資料集,模型,轉換函式等。實現視覺類任務如分類、目標檢測、分割必不可少的。
匯入所需包(示例):
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
若提示出錯,可使用命令列視窗,進行 conda install 安裝。或者在pycharm中進行安裝,以pycharm為例:輸入要安裝的包,點選安裝即可。
二、搭建多層感知機
1.MNIST介紹
MNIST簡介: 包含0-9 共10個手寫數字,每個數字由7000張(高度28*寬度28)的影像,將70k資料,分為了訓練集60K,測試集10大小。本節,透過感知機實現對MNIST手寫數字的分類。
程式碼如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2.下載MNIST資料集
程式碼如下:
‘./data’:設定要儲存的下載目錄。
train=True:設定要下載的是60k的訓練資料集。
download=True:如果當前資料夾沒有資料集,則從網上下載。
transforms.ToTensor():下載的資料集為numpy格式,需要轉換為張量格式。
transforms.Normalize((0.1307,), (0.3081,):(此項非必要設定項)為了更好的訓練結果,因為影像的資料值是0-1之間,將資料值正則花在0左右,對模型梯度下降效果更好。
batch_size=batch_size, shuffle=True:設定批次大小,隨機打算資料。
測試集設定類似
#MNIST 資料集
#設定訓練的批次大小、學習率、及訓練代數
batch_size=200
learning_rate=0.001
epochs=20
#下載資料集
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=False, download=True, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)
3.搭建神經網路層
1.權重和偏置
程式碼如下:
w1,b1:第一層網路感知機。輸入影像大小是28*28=784,因此輸入為784,輸出設定為100(這個引數隨意設定,可以嘗試不同的數目檢視效果)因為W要轉置所以輸入放後面,輸出放前面。b1為第一層網路對應的偏置項。
w2, b2:與上敘述類似。
==w3, b3 ==:注意輸出要與分類的10個數字類別數一致,其他與上述類似。
requires_grad=True:此項設定為True,表示要對w,b求梯度。
#生成 三個神經網路成,對應感知節分別為第一層100,第二成200,第三層10,即要分類的數目
w1, b1 = torch.randn(100, 784, requires_grad=True),\
torch.zeros(100, requires_grad=True)
w2, b2 = torch.randn(200, 100, requires_grad=True),\
torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200, requires_grad=True),\
torch.zeros(10, requires_grad=True)
2.定義前向計算網路
程式碼如下:
relu啟用函式:確保網路的非線性,實現更好的分類效果。
#定義前向網路計算,每層神經網路輸出後增加relu啟用函式,確保網路的非線性,實現更好的分類效果
def forward(x):
x = x@w1.t() + b1
x = F.relu(x)
x = x@w2.t() + b2
x = F.relu(x)
x = x@w3.t() + b3
x = F.relu(x)
return x
3.定義梯度最佳化器及損失函式設定
程式碼如下:
.CrossEntropyLoss():損失採用交叉熵損失函式。
.SGD:採用隨機梯度下降,並設定學習率。
#定義最佳化器,採用SGD隨機梯度下降的方式對w1, b1, w2, b2, w3, b3進行最佳化
optimizer = optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate)
#定義採用交叉熵作為損失函式
criteon = nn.CrossEntropyLoss()
4.完成程式設計
程式碼如下:
#設定迭代次數
for epoch in range(epochs):
for batch_idx, (data, target) in enumerate(train_loader):
#將資料打平為(批次,高度*寬度),-1代表所有
data = data.view(-1, 28*28)
#將資料輸入到網路中
cal_data = forward(data)
#將計算的資料與目標資料求誤差損失
loss = criteon(cal_data, target)
#將梯度值初始化為0
optimizer.zero_grad()
#pytorch計算梯度值
loss.backward()
#更新梯度值
optimizer.step()
#每隔25*batcsize(200) = 5000 列印輸出結果
if batch_idx % 25 == 0:
print('訓練代數: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
#將測試誤差及正確率清0
test_loss = 0
correct = 0
#取測試集資料及目標資料
for data, target in test_loader:
data = data.view(-1, 28 * 28)
logits = forward(data)
#誤差累加
test_loss += criteon(logits, target).item()
#取出預測最大值的索引編號,即預測值
pred = logits.data.argmax(dim=1)
#統計正確預測的個數
correct += pred.eq(target.data).sum()
test_loss /= len(test_loader.dataset)
#列印輸出測試誤差及準確率
print('\n測試集: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
三、完整程式碼程式
因為我們自己隨機生成的初始化 w1,w2,w3,達到的效能並不好。所以我們可以採用大神何凱明的初始化權重對w1,w2,w3 進行初始化賦值,準確率可以達到90%。小夥伴們可以嘗試下,將初始化賦值程式碼遮蔽,對比檢視效果。
程式碼如下:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
#MNIST 資料集
#設定訓練的批次大小、學習率、及訓練代數
batch_size=200
learning_rate=0.001
epochs=20
#下載資料集
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=False, download=True, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])), 北海購房網
batch_size=batch_size, shuffle=True)
#生成三層神經網路成,對應感知機分別為第一層100,第二成200,第三層10,即要分類的數目
w1, b1 = torch.randn(100, 784, requires_grad=True),\
torch.zeros(100, requires_grad=True)
w2, b2 = torch.randn(200, 100, requires_grad=True),\
torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200, requires_grad=True),\
torch.zeros(10, requires_grad=True)
#採用何凱明大神的初始化權重,準確率更高,權重的合理初始化很重要
torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3)
#定義前向網路計算,每層神經網路輸出後增加relu啟用函式,確保網路的非線性,實現更好的分類效果
def forward(x):
x = x@w1.t() + b1
x = F.relu(x)
x = x@w2.t() + b2
x = F.relu(x)
x = x@w3.t() + b3
x = F.relu(x)
return x
#定義最佳化器,採用SGD隨機梯度下降的方式對w1, b1, w2, b2, w3, b3進行最佳化
optimizer = optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate)
#定義採用交叉熵作為損失函式
criteon = nn.CrossEntropyLoss()
# 設定迭代次數
for epoch in range(epochs):
for batch_idx, (data, target) in enumerate(train_loader):
# 將資料打平為(批次,高度*寬度),-1代表所有
data = data.view(-1, 28 * 28)
# 將資料輸入到網路中
cal_data = forward(data)
# 將計算的資料與目標資料求誤差損失
loss = criteon(cal_data, target)
# 將梯度值初始化為0
optimizer.zero_grad()
# pytorch計算梯度值
loss.backward()
# 更新梯度值
optimizer.step()
# 每隔25*batcsize(200) = 5000 列印輸出結果
if batch_idx % 25 == 0:
print('訓練代數: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
# 將測試誤差及正確率清0
test_loss = 0
correct = 0
# 取測試集資料及目標資料
for data, target in test_loader:
data = data.view(-1, 28 * 28)
logits = forward(data)
# 誤差累加
test_loss += criteon(logits, target).item()
# 取出預測最大值的索引編號,即預測值
pred = logits.data.argmax(dim=1)
# 統計正確預測的個數
correct += pred.eq(target.data).sum()
test_loss /= len(test_loader.dataset)
# 列印輸出測試誤差及準確率
print('\n測試集: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
輸出結果。
總結
這一節,我們從底層搭建了一個三層的感知機神經網路,對手寫數字資料集MNIST進行訓練和測試,達到了92%的正確率。權重的隨機初始化,對結果是很重要的,但在torch更高層的API使用中提供了很好的初始化。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2766904/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- torch--多層感知機實現影像分類
- 深度學習(一)之MNIST資料集分類深度學習
- 深度學習:多層感知機和異或問題(Pytorch實現)深度學習PyTorch
- 基於PyTorch框架的多層全連線神經網路實現MNIST手寫數字分類PyTorch框架神經網路
- 分類演算法-多層感知機 Multi-layer Perceptron演算法
- Pytorch實現分類器PyTorch
- 前饋神經網路進行MNIST資料集分類神經網路
- MNIST資料集詳解及視覺化處理(pytorch)視覺化PyTorch
- Alink漫談(十五) :多層感知機 之 迭代優化優化
- 目標檢測(2):LeNet-5 的 PyTorch 復現(MNIST 手寫資料集篇)PyTorch
- [譯] 使用 PyTorch 在 MNIST 資料集上進行邏輯迴歸PyTorch邏輯迴歸
- MNIST資料集介紹
- [深度學習]多層感知機(MLP)深度學習
- 基於Pytorch實現貓狗分類PyTorch
- Alink漫談(十四) :多層感知機 之 總體架構架構
- 【Python機器學習實戰】感知機和支援向量機學習筆記(三)之SVM的實現Python機器學習筆記
- 【小白學PyTorch】8 實戰之MNIST小試牛刀PyTorch
- TensorFlow 入門(MNIST資料集)
- CNN+pytorch實現文字二分類CNNPyTorch
- 【原創】python實現BP神經網路識別Mnist資料集Python神經網路
- Pytorch搭建MyNet實現MNIST手寫數字識別PyTorch
- [PyTorch 學習筆記] 3.2 卷積層PyTorch筆記卷積
- pytorch載入語音類自定義資料集PyTorch
- 機器學習筆記——資料集分割機器學習筆記
- 訓練一個影像分類器demo in PyTorch【學習筆記】PyTorch筆記
- 使用自己的資料集訓練MobileNet、ResNet實現影象分類(TensorFlow)
- python 將Mnist資料集轉為jpg,並按比例/標籤拆分為多個子資料集Python
- tf.keras實現線性迴歸和多層感知器Keras
- 機器學習之資料集的劃分機器學習
- 基於pytorch實現Resnet對本地資料集的訓練PyTorch
- 筆記-資料結構之 Hash(OC的粗略實現)筆記資料結構
- Pytorch學習筆記之tensorboardPyTorch筆記ORB
- 資料探勘之 層次聚類聚類
- 棉花病害影像分類資料集
- 水稻病害影像分類資料集
- Redis多機資料庫實現Redis資料庫
- Pytorch MNIST Multi-layerPyTorch
- Pytorch使用資料並行,單機多卡PyTorch並行