文章目錄
- 前言
- 一、Torch相關包介紹
- 二、搭建多層感知機
- 1.MNIST介紹
- 2.下載MNIST資料集
- 3.搭建神經網路層
- 1.權重和偏置
- 2.定義前向計算網路
- 3.定義梯度優化器及損失函式設定
- 4.完成程式設計
- 三、完整代碼程式
- 總結
前言
復雜的神經網路也是由許多神經元組成,在深度學習領域,神經元即感知機,深度學習通過許多感知機,盡可能的學習一個任務的復雜數學表示,神經網路在模擬生物神經元時,創造性的引入非線性的函式,通過判斷是否達到閾值,來覺得信號是否輸出,完成資訊傳遞,因此,在階躍函式的基礎上,進一步優化,拓展,得到sigmoid激活函式、Relu、leak ReLu等,細細品味,你將發現這構思的巧妙性、合理性,
本節主要MNIST的代碼實作,關于感知機,激活函式等介紹,大家可以參考入手這本書,通俗易懂,內容詳實,極具閱讀價值,
pdf 地址如下,僅供學習參考:
鏈接: https://wwe.lanzous.com/ieOE2noazwj.

一、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資料集
如果下載失敗,也可使用下載好的資料集,還在目錄下:
鏈接: https://wwe.lanzous.com/b01c9d0sj.
密碼:3dii


代碼如下:
‘./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使用中提供了很好的初始化,會在下一節中進行講解,最后勞煩小伙伴,動手點個贊吧,給予我爆發小宇宙的能量,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/273241.html
標籤:python
下一篇:python筆記整理
