基于pytorch的BP神经网络模型构建
小伙伴好,最近想要認(rèn)真學(xué)習(xí)一波pytorch,打算通過(guò)pytorch去構(gòu)建一系列的網(wǎng)絡(luò)模型,包括CNN、LSTM、Transform等,后續(xù)都會(huì)進(jìn)行搭建。一個(gè)不斷學(xué)習(xí)的小菜雞,也希望有問(wèn)題小伙伴能指出。
MINST數(shù)據(jù)集是手寫(xiě)數(shù)字的識(shí)別,圖片尺寸為(28,28,1),標(biāo)簽為數(shù)字的類(lèi)別。
?
1、加載數(shù)據(jù)
本文這次主要是對(duì)MNIST數(shù)據(jù)集進(jìn)行測(cè)試。利用pytorch加載數(shù)據(jù)的方法如下:
# 利用datasets中可加載不同的數(shù)據(jù)集,本次選用MNIST數(shù)據(jù)集 from torchvision import datasets, transformsbatch_size = 128# 加載數(shù)據(jù) def load_data():# 下載數(shù)據(jù)train_data = datasets.MNIST(root='./data/',train=True,transform=transforms.ToTensor(),download=True)test_data = datasets.MNIST(root='./data/',train=False,transform=transforms.ToTensor())# 返回一個(gè)數(shù)據(jù)迭代器# shuffle:是否打亂順序train_loader = torch.utils.data.DataLoader(dataset=train_data,batch_size=batch_size,shuffle=True)test_loader = torch.utils.data.DataLoader(dataset=test_data,batch_size=batch_size,shuffle=False)print("Loaded Data successfully!")return train_loader, test_loader獲取數(shù)據(jù)的命令:
datasets.MNIST(root,train=True,transform=None,target_transform=None,download=False)
其中:
數(shù)據(jù)分批加載:
torch.utils.data.DataLoader(dataset=train_data,batch_size=Config.batch_size,shuffle=True)?
主要實(shí)現(xiàn)對(duì)數(shù)據(jù)的加載,批次的數(shù)據(jù)量設(shè)置,是否打亂設(shè)置。一般訓(xùn)練集打亂,測(cè)試集不打亂。
如果是對(duì)自己的數(shù)據(jù)集處理,則dataset=自己的數(shù)據(jù)集,不需要使用上述加載MNIST數(shù)據(jù)集的流程。?
2、構(gòu)建模型
這次主要使用BP神經(jīng)網(wǎng)絡(luò)構(gòu)建,后續(xù)還會(huì)構(gòu)建一些常見(jiàn)的CNN網(wǎng)絡(luò),如:LeNet、AlexNet、ResNet等進(jìn)行構(gòu)建。
本次構(gòu)建主要包含輸入層維度為28*28,輸出層維度為10,隱藏層128。本次主要是對(duì)工具的使用進(jìn)行介紹,小伙伴可以根據(jù)自己的需要構(gòu)建網(wǎng)絡(luò),提高模型準(zhǔn)確率等。
import torch import torch.nn as nnclass BP(nn.Module):def __init__(self):super(BP, self).__init__()# 構(gòu)建隱藏層self.fc1 = nn.Sequential(nn.Linear(28*28, 128),nn.ReLU())# 構(gòu)建輸出層self.fc2 = nn.Sequential(nn.Linear(128, 10),nn.Sigmoid())def forward(self, x):# 將照片鋪平為1維向量x = x.view(-1,784)x = self.fc1(x)x = self.fc2(x)return xdata = torch.randn(1,28,28) net = BP() outputs = net(data) print(outputs.shape)構(gòu)建的模型輸出維度為(1,10),10代表標(biāo)簽的類(lèi)別數(shù)目
3、訓(xùn)練模型
選擇合適的優(yōu)化器,損失函數(shù)幫助我們的模型快速收斂,一般優(yōu)化器選擇Adam,SGD等效果較好,損失函數(shù)一般回歸問(wèn)題選擇MSE,分類(lèi)問(wèn)題選擇交叉熵?fù)p失。
# 選擇損失為交叉熵?fù)p失 criterion = nn.CrossEntropyLoss() # 選擇優(yōu)化器為Adam optimizer = torch.optim.Adam()對(duì)于一些參數(shù)的選擇可以自行搜索
def train_step(self):print("Training & Evaluating based on BP......")file = './result/raw_train_mnist.txt'fp = open(file,'w',encoding='utf-8')fp.write('epoch\tbatch\tloss\taccuracy\n')# 循環(huán)輪次for epoch in range(Config.epoch):# 顯示當(dāng)前輪print("Epoch {:3}.".format(epoch + 1))# 循環(huán)批次,每一批的數(shù)目當(dāng)前設(shè)置128for batch_idx,(data, label) in enumerate(self.train):# 這里設(shè)置主要是我利用GPU訓(xùn)練,用cpu訓(xùn)練的可以忽略data, label = Variable(data.cuda()), Variable(label.cuda())# 優(yōu)化器初始化self.optimizer.zero_grad()outputs = self.net(data)# 計(jì)算損失loss = self.criterion(outputs, label)loss.backward()# 進(jìn)行優(yōu)化計(jì)算self.optimizer.step()# 每100次打印一次結(jié)果if batch_idx % Config.print_per_step == 0:# 每100批次計(jì)算當(dāng)前準(zhǔn)確率_, predicted = torch.max(outputs, 1)correct = 0for _ in predicted == label:if _:correct += 1accuracy = correct / Config.batch_sizemsg = "Batch: {:5}, Loss: {:6.2f}, Accuracy: {:8.2%}."# 輸出準(zhǔn)確率print(msg.format(batch_idx, loss, accuracy))fp.write('{}\t{}\t{}\t{}\n'.format(epoch,batch_idx,loss,accuracy))fp.close()test_loss = 0.test_correct = 0for data, label in self.test:data, label = Variable(data.cuda()), Variable(label.cuda())outputs = self.net(data)loss = self.criterion(outputs, label)test_loss += loss * Config.batch_size_, predicted = torch.max(outputs, 1)correct = int(sum(predicted == label))test_correct += correctaccuracy = test_correct / len(self.test.dataset)loss = test_loss / len(self.test.dataset)print("Test Loss: {:5.2f}, Accuracy: {:6.2%}".format(loss, accuracy))torch.save(self.net.state_dict(),'./result/raw_train_mnist_model.pth')4、整體代碼以及模型訓(xùn)練
import torch from torchvision import datasets, transforms import torch.nn as nn import torch.optim as optim from torch.autograd import Variable import numpy as npdevice = torch.device('cuda:0')class Config:batch_size = 128epoch = 10alpha = 1e-3print_per_step = 100 # 控制輸出class BP(nn.Module):def __init__(self):super(BP, self).__init__()self.fc1 = nn.Sequential(nn.Linear(28*28, 128),nn.ReLU())self.fc2 = nn.Sequential(nn.Linear(128, 10),nn.Sigmoid())def forward(self, x):x = x.view(-1,784)x = self.fc1(x)x = self.fc2(x)return xclass TrainProcess:def __init__(self):self.train, self.test = self.load_data()self.net = BP().to(device)self.criterion = nn.CrossEntropyLoss() # 定義損失函數(shù)self.optimizer = optim.Adam(self.net.parameters(), lr=Config.alpha)@staticmethoddef load_data():train_data = datasets.MNIST(root='./data/',train=True,transform=transforms.ToTensor(),download=True)test_data = datasets.MNIST(root='./data/',train=False,transform=transforms.ToTensor())# 返回一個(gè)數(shù)據(jù)迭代器# shuffle:是否打亂順序train_loader = torch.utils.data.DataLoader(dataset=train_data,batch_size=Config.batch_size,shuffle=True)test_loader = torch.utils.data.DataLoader(dataset=test_data,batch_size=Config.batch_size,shuffle=False)return train_loader, test_loaderdef train_step(self):print("Training & Evaluating based on BP......")file = './result/raw_train_mnist.txt'fp = open(file,'w',encoding='utf-8')fp.write('epoch\tbatch\tloss\taccuracy\n')for epoch in range(Config.epoch):print("Epoch {:3}.".format(epoch + 1))for batch_idx,(data, label) in enumerate(self.train):data, label = Variable(data.cuda()), Variable(label.cuda())self.optimizer.zero_grad()outputs = self.net(data)loss = self.criterion(outputs, label)loss.backward()self.optimizer.step()# 每100次打印一次結(jié)果if batch_idx % Config.print_per_step == 0:_, predicted = torch.max(outputs, 1)correct = 0for _ in predicted == label:if _:correct += 1accuracy = correct / Config.batch_sizemsg = "Batch: {:5}, Loss: {:6.2f}, Accuracy: {:8.2%}."print(msg.format(batch_idx, loss, accuracy))fp.write('{}\t{}\t{}\t{}\n'.format(epoch,batch_idx,loss,accuracy))fp.close()test_loss = 0.test_correct = 0for data, label in self.test:data, label = Variable(data.cuda()), Variable(label.cuda())outputs = self.net(data)loss = self.criterion(outputs, label)test_loss += loss * Config.batch_size_, predicted = torch.max(outputs, 1)correct = 0for _ in predicted == label:if _:correct += 1test_correct += correctaccuracy = test_correct / len(self.test.dataset)loss = test_loss / len(self.test.dataset)print("Test Loss: {:5.2f}, Accuracy: {:6.2%}".format(loss, accuracy))torch.save(self.net.state_dict(),'./result/raw_train_mnist_model.pth')if __name__ == "__main__":p = TrainProcess()p.train_step()訓(xùn)練結(jié)果:
Training & Evaluating based on BP...... Epoch 1. Batch: 0, Loss: 2.31, Accuracy: 10.16%. Batch: 100, Loss: 1.68, Accuracy: 83.59%. Batch: 200, Loss: 1.60, Accuracy: 89.84%. Batch: 300, Loss: 1.60, Accuracy: 85.94%. Batch: 400, Loss: 1.55, Accuracy: 91.41%. Epoch 2. Batch: 0, Loss: 1.54, Accuracy: 91.41%. Batch: 100, Loss: 1.56, Accuracy: 89.84%. Batch: 200, Loss: 1.53, Accuracy: 91.41%. Batch: 300, Loss: 1.56, Accuracy: 91.41%. Batch: 400, Loss: 1.51, Accuracy: 96.09%. Epoch 3. Batch: 0, Loss: 1.50, Accuracy: 97.66%. Batch: 100, Loss: 1.54, Accuracy: 92.19%. Batch: 200, Loss: 1.52, Accuracy: 93.75%. Batch: 300, Loss: 1.51, Accuracy: 95.31%. Batch: 400, Loss: 1.53, Accuracy: 93.75%. Epoch 4. Batch: 0, Loss: 1.51, Accuracy: 94.53%. Batch: 100, Loss: 1.50, Accuracy: 94.53%. Batch: 200, Loss: 1.52, Accuracy: 95.31%. Batch: 300, Loss: 1.53, Accuracy: 93.75%. Batch: 400, Loss: 1.50, Accuracy: 96.88%. Epoch 5. Batch: 0, Loss: 1.49, Accuracy: 96.88%. Batch: 100, Loss: 1.50, Accuracy: 96.09%. Batch: 200, Loss: 1.50, Accuracy: 97.66%. Batch: 300, Loss: 1.50, Accuracy: 93.75%. Batch: 400, Loss: 1.50, Accuracy: 95.31%. Epoch 6. Batch: 0, Loss: 1.51, Accuracy: 96.88%. Batch: 100, Loss: 1.51, Accuracy: 94.53%. Batch: 200, Loss: 1.54, Accuracy: 92.97%. Batch: 300, Loss: 1.48, Accuracy: 97.66%. Batch: 400, Loss: 1.51, Accuracy: 96.09%. Epoch 7. Batch: 0, Loss: 1.50, Accuracy: 96.88%. Batch: 100, Loss: 1.51, Accuracy: 95.31%. Batch: 200, Loss: 1.49, Accuracy: 96.88%. Batch: 300, Loss: 1.50, Accuracy: 94.53%. Batch: 400, Loss: 1.49, Accuracy: 94.53%. Epoch 8. Batch: 0, Loss: 1.49, Accuracy: 96.88%. Batch: 100, Loss: 1.49, Accuracy: 97.66%. Batch: 200, Loss: 1.49, Accuracy: 96.88%. Batch: 300, Loss: 1.51, Accuracy: 96.09%. Batch: 400, Loss: 1.51, Accuracy: 96.88%. Epoch 9. Batch: 0, Loss: 1.49, Accuracy: 96.88%. Batch: 100, Loss: 1.50, Accuracy: 95.31%. Batch: 200, Loss: 1.49, Accuracy: 96.09%. Batch: 300, Loss: 1.49, Accuracy: 96.09%. Batch: 400, Loss: 1.49, Accuracy: 98.44%. Epoch 10. Batch: 0, Loss: 1.48, Accuracy: 97.66%. Batch: 100, Loss: 1.48, Accuracy: 98.44%. Batch: 200, Loss: 1.50, Accuracy: 95.31%. Batch: 300, Loss: 1.49, Accuracy: 97.66%. Batch: 400, Loss: 1.49, Accuracy: 97.66%. Test Loss: 1.51, Accuracy: 97.02%這里訓(xùn)練了10的epoch就可以達(dá)到97%,而且是非常簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)。希望可以幫助大家可以快速上手pytorch。
總結(jié)
以上是生活随笔為你收集整理的基于pytorch的BP神经网络模型构建的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 诺顿企业版10.0 简体中文版
- 下一篇: springcloud篇面试宝典