前饋神經網絡
常見的前饋神經網絡有感知機(Perceptrons)、BP(Back Propagation)網絡等。前饋神經網絡(FNN)是人工智能領域中最早發明的簡單人工神經網絡類型。各神經元分層排列。每個神經元只與前一層的神經元相連。接收前一層的輸出,并輸出給下一層.各層間沒有反饋。在它內部,參數從輸入層經過隱含層向輸出層單向傳播。與遞歸神經網絡不同,在它內部不會構成有向環。下圖為一個簡單前饋神經網絡示意圖:
整個網絡中無反饋,信號從輸入層向輸出層單向傳播,可用一個有向無環圖表示
感知器
感知器實際上是神經網絡結構中的一個神經元,那么一個感知器就構成了最簡單的神經網絡。
感知器是前向結構的人工神經網絡,可以被看作是一個有向圖,由多個的節點層所組成,每一層都全連接到下一層。除了輸入節點,每個節點都是一個帶有非線性激活函數的神經元(或稱處理單元)
實現前饋神經網絡
之前的blog已經說過如何搭建windows系統的pytorch-gpu環境,我們使用pytorch來實現第一個前饋神經網絡:
源代碼:
源碼中我作了詳細的注釋,供參考
import torch
import torch.nn as nn
import torchvision.datasets as dsets #torchvision為一個做圖形處理的庫,加載數據集
import torchvision.transforms as transforms'''
torchvision.datasets這個包中包含MNIST、FakeData、COCO、LSUN、ImageFolder、DatasetFolder、ImageNet、CIFAR等一些常用的數據集,并且提供了數據集設置的一些重要參數設置,可以通過簡單數據集設置來進行數據集的調用。從這些數據集中我們也可以看出數據集設置的主要變量有哪些并且有什么功能對將來自己數據集的設置也有極大的幫助。
以上數據集的接口基本上很相近。它們至少包括兩個公共的參數transform和target_transform,以便分別對輸入和和目標做變換
'''
from torch.autograd import Variable
#torch.autograd提供了類和函數用來對任意標量函數進行求導。
import torch.utils.data as Data
#我們需要使用torch.utils.data.DataLoader加載數據
import matplotlib.pyplot as plt
#畫圖所需的庫# Hyper Parameters 超參數(hyperparameters)/算法參數 根據經驗進行設定,影響到權重和偏置的大小,比如迭代次數、隱藏層的層數、每層神經元的個數、學習速率等
input_size = 784
hidden_size = 500
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001# MNIST Dataset 數據集
train_dataset = dsets.MNIST(root='./data', #指定數據集的目錄train=True, transform=transforms.ToTensor(),
# transforms.ToTensor() 將numpy的ndarray或PIL.Image讀的圖片轉換成形狀為(C,H, W)的Tensor格式,且/255歸一化到[0,1.0]之間download=True)test_dataset = dsets.MNIST(root='./data', train=False, transform=transforms.ToTensor())# Data Loader (Input Pipeline)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
'''
dataset:加載數據的數據集
batch_size:加載批訓練的數據個數
shuffle:在每個Epoch中打亂數據
'''
test_y=test_dataset.test_labels# Neural Network Model (1 hidden layer)
class Net(nn.Module):#初始化網絡結構def __init__(self, input_size, hidden_size, num_classes):super(Net, self).__init__()self.fc1 = nn.Linear(input_size, hidden_size) #輸入層,線性(liner)關系self.relu = nn.ReLU()#隱藏層,使用ReLU函數self.fc2 = nn.Linear(hidden_size, num_classes) #輸出層,線性(liner)關系#forword 參數傳遞函數,網絡中數據的流動def forward(self, x):out = self.fc1(x)out = self.relu(out)out = self.fc2(out)return outnet = Net(input_size, hidden_size, num_classes)# Loss and Optimizer
criterion = nn.CrossEntropyLoss() #設置loss為最小二乘loss
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)
#設置優化器,torch.optim.Adam
# Train the Model
for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader): #enumrate# Convert torch tensor to Variableimages = Variable(images.view(-1, 28*28))#圖片大小為28*28labels = Variable(labels)#pytorch都是有tensor計算的,而tensor里面的參數都是Variable的形式# Forward + Backward + Optimizeoptimizer.zero_grad() # zero the gradient bufferoutputs = net(images)loss = criterion(outputs, labels)loss.backward()optimizer.step()if (i+1) % 100 == 0:print ('Epoch [%d/%d], Step [%d/%d], Loss: %.4f' %(epoch+1, num_epochs, i+1, len(train_dataset)//batch_size, loss.item()))
#每訓練100個step輸出一次結果
# Test the Model
correct = 0
total = 0
for images, labels in test_loader:images = Variable(images.view(-1, 28*28))outputs = net(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)#計算所有的label數量correct += (predicted == labels).sum()#計算預測對的label數量print('Accuracy of the network on the 10000 test images: %d %%' % (100 * torch.true_divide(correct, total)))# Save the Model
for i in range(1,4):plt.imshow(train_dataset.train_data[i].numpy(), cmap='gray') plt.title('%i' % train_dataset.train_labels[i]) plt.show()
torch.save(net.state_dict(), 'model.pkl')
#net.state_dict(),模型文件
test_output = net(images[:20]) pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze() print('prediction number',pred_y) print('real number',test_y[:20].numpy())
最小二乘Loss
class torch.nn.CrossEntropyLoss(weight=None, size_average=True)[source]
此標準將LogSoftMax和NLLLoss集成到一個類中。
當訓練一個多類分類器的時候,這個方法是十分有用的。
weight(tensor): 1-D tensor,n個元素,分別代表n類的權重,如果你的訓練樣本很不均衡的話,是非常有用的。默認值為None。
調用時參數:
input : 包含每個類的得分,2-D tensor,shape為 batch*n
target: 大小為 n 的 1—D tensor,包含類別的索引(0到 n-1)。
Loss可以表述為以下形式:
當weight參數被指定的時候,loss的計算公式變為:
torch.optim.Adam
torch.optim是一個實現了各種優化算法的庫。大部分常用的方法得到支持,并且接口具備足夠的通用性,使得未來能夠集成更加復雜的方法。
·
為了使用torch.optim,需要構建一個optimizer對象。這個對象能夠保持當前參數狀態并基于計算得到的梯度進行參數更新。
·
為了構建一個Optimizer,需要給它一個包含了需要優化的參數(必須都是Variable對象)的iterable。然后,你可以設置optimizer的參 數選項,比如學習率,權重衰減,等等。
·
例如:
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001)
·
對于Adam
class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)[source]
參數:
params (iterable) – 待優化參數的iterable或者是定義了參數組的dict lr (float, 可選) –學習率(默認:1e-3) betas (Tuple[float, float], 可選) –用于計算梯度以及梯度平方的運行平均值的系數(默認:0.9,0.999) eps (float, 可選) –為了增加數值計算的穩定性而加到分母里的項(默認:1e-8) weight_decay (float, 可選) –
權重衰減(L2懲罰)(默認: 0)
附上pytorch文檔的解釋
torch.max
output = torch.max(input, dim)
1.輸入
input是softmax函數輸出的一個tensor
dim是max函數索引的維度0/1,0是每列的最大值,1是每行的最大值
2. 輸出
函數會返回兩個tensor,第一個tensor是每行的最大值,softmax的輸出中最大的是1,所以第一個tensor是全1的tensor;第二個tensor是每行最大值的索引。
torch.nn.state_dict()
pytorch 中的 state_dict 是一個簡單的python的字典對象,將每一層與它的對應參數建立映射關系.(如model的每一層的weights及偏置等等)
(注意,只有那些參數可以訓練的layer才會被保存到模型的state_dict中,如卷積層,線性層等等)
squeeze函數
import numpy as npx = np.array([[[0], [1], [2]]])
print(x)
"""
x=[[[0][1][2]]]
"""
print(x.shape) # (1, 3, 1)x1 = np.squeeze(x) # 從數組的形狀中刪除單維條目,即把shape中為1的維度去掉print(x1) # [0 1 2]
print(x1.shape) # (3,)
總結
以上是生活随笔為你收集整理的(菜鸟入门)使用pytorch框架实现前馈神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。