PyTorchを使ってMLPを実現し、MNISTデータセットで検証方式


概要
これは深さ学習コースの最初の実験で、主な目的はPytochフレームワークを熟知することです。MLPは多层感知器です。今回実现したのは四层センサーです。コードと考え方はネット上の多くの文章を参考にしました。個人的には、知覚器のコードは大同小異で、特にPytochで実現します。階数とパラメータ以外にコードは全部似ています。
Pytoch書き込み神経ネットワークの主な手順は主に以下の通りです。
1ネットワーク構造の構築
2データセットをロードする
3神経ネットワークを訓練する(最適化器の選択とLossの計算を含む)
4試験神経ネットワーク
この4つの面からPytochがMLPを構築する過程を紹介します。
プロジェクトコード住所:lab 1
プロセス
ネットワーク構造を構築する
神経ネットワークの最も重要なのはネットワークを構築することであり、第一歩はネットワーク構造を定義することである。ここでは四階のセンサーを作成しました。パラメータはMNISTデータセットによって設定されています。ネットワーク構造は以下の通りです。

#            
class MLP(torch.nn.Module):  #    torch   Module
  def __init__(self):
    super(MLP,self).__init__()  # 
    #                    ,     
    self.fc1 = torch.nn.Linear(784,512) #        
    self.fc2 = torch.nn.Linear(512,128) #       
    self.fc3 = torch.nn.Linear(128,10)  #    
    
  def forward(self,din):
    #     ,    :din,     dout
    din = din.view(-1,28*28)    #       Tensor,     
    dout = F.relu(self.fc1(din))  #    relu     
    dout = F.relu(self.fc2(dout))
    dout = F.softmax(self.fc3(dout), dim=1) #       softmax     
    # 10       10   ,       ,                
    return dout
ネットの構造は実はとても簡単で、3階のLinearを設置しました。暗黙層活性化関数はReluを使用する。出力層はSoftmaxを使用します。ネット上には他の構造があります。ドラウポタを使っています。入門はちょっと高級だと思います。そしてここに置いても役に立たないです。面倒くさいです。正確さを上げることができません。
データセットを読み込み
第二ステップはグローバル変数を定義し、MNISTデータセットをロードすることです。

#       
n_epochs = 10   # epoch    
batch_size = 20 #           

#          ,       ,   
train_data = datasets.MNIST(root = './data', train = True, download = True, transform = transforms.ToTensor())
test_data = datasets.MNIST(root = './data', train = True, download = True, transform = transforms.ToTensor())
#      
train_loader = torch.utils.data.DataLoader(train_data, batch_size = batch_size, num_workers = 0)
test_loader = torch.utils.data.DataLoader(test_data, batch_size = batch_size, num_workers = 0)
ここはパラメータが多いので、注意すべき点がたくさんあります。
rootパラメータのフォルダは存在しなくても大丈夫です。自動的に作成されます。
transformパラメータは、データセットの変化が分かりません。ここでは自動的に無視できます。
batchsizeパラメータのサイズは、各epochで逆方向に伝搬する回数を定義するのに相当する1回のトレーニングの数を決定します。
numworkersパラメータはデフォルトでは0です。すなわちデータを並列に処理しません。私はここで0より大きい設定をすると、いつもエラーが発生します。標準値に設定することをおすすめします。
epochとbatchを理解しないとsizeさん、インターネットで資料を調べられます。深勉強を始めたばかりの時も分かりませんでした。
神経網を訓練する
第三ステップはトレーニングネットワークです。コードは以下の通りです。

#       
def train():
  #           
  lossfunc = torch.nn.CrossEntropyLoss()
  optimizer = torch.optim.SGD(params = model.parameters(), lr = 0.01)
  #     
  for epoch in range(n_epochs):
    train_loss = 0.0
    for data,target in train_loader:
      optimizer.zero_grad()  #              
      output = model(data)  #      
      loss = lossfunc(output,target) #        
      loss.backward()     #       ,        
      optimizer.step()    #           net   parameters  
      train_loss += loss.item()*data.size(0)
    train_loss = train_loss / len(train_loader.dataset)
    print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch + 1, train_loss))
訓練の前に損失関数と最適化器を定義します。ここには多くの学問がありますが、本文は言いません。理論が多すぎます。
トレーニングプロセスは2層のforサイクルです。外側の層はトレーニングセットを巡回した回数です。内層は毎回のロットです。最後に、各epochのlossを出力します。毎回の訓練の目的は、訓練セットにおけるより高い精度を達成するために、loss関数を減少させることである。
テスト神経ネットワーク
最後に、テストセットでテストを行います。コードは以下の通りです。

#            
def test():
  correct = 0
  total = 0
  with torch.no_grad(): #            
    for data in test_loader:
      images, labels = data
      outputs = model(images)
      _, predicted = torch.max(outputs.data, 1)
      total += labels.size(0)
      correct += (predicted == labels).sum().item()
  print('Accuracy of the network on the test images: %d %%' % (
    100 * correct / total))
  return 100.0 * correct / total
このテストのコードはクラスメートからもらったものです。このテストのコードはとてもいいです。簡潔で、ずっと使っています。
コードはまずtouch.no_を設定します。grad()は、後のコードを定義して勾配を計算する必要がなく、メモリ空間を節約することができます。そして、テスト集中の各batchをテストし、統計総数と正確数を最後に正確率を計算して出力します。
練習しながらテストするのが普通です。ここではまずステップを踏んでください。
テストコードの前にmodel.eval()を追加する場合があります。これはトレーニング状態を表しています。しかし、ここでは必要ありません。バッtch NormalizationとDropout方法がなければ、プラスとノーの効果は同じです。
完全コード

'''
    : Windows10
Python  : 3.7
PyTorch  : 1.1.0
cuda: no
'''
import torch
import torch.nn.functional as F  #       
from torchvision import datasets
import torchvision.transforms as transforms
import numpy as np

#       
n_epochs = 10   # epoch    
batch_size = 20 #           

#          ,       ,   
train_data = datasets.MNIST(root = './data', train = True, download = True, transform = transforms.ToTensor())
test_data = datasets.MNIST(root = './data', train = True, download = True, transform = transforms.ToTensor())
#      
train_loader = torch.utils.data.DataLoader(train_data, batch_size = batch_size, num_workers = 0)
test_loader = torch.utils.data.DataLoader(test_data, batch_size = batch_size, num_workers = 0)


#            
class MLP(torch.nn.Module):  #    torch   Module
  def __init__(self):
    super(MLP,self).__init__()  # 
    #                    ,     
    self.fc1 = torch.nn.Linear(784,512) #        
    self.fc2 = torch.nn.Linear(512,128) #       
    self.fc3 = torch.nn.Linear(128,10)  #    
    
  def forward(self,din):
    #     ,    :din,     dout
    din = din.view(-1,28*28)    #       Tensor,     
    dout = F.relu(self.fc1(din))  #    relu     
    dout = F.relu(self.fc2(dout))
    dout = F.softmax(self.fc3(dout), dim=1) #       softmax     
    # 10       10   ,       ,                
    return dout

#       
def train():
  #          
  lossfunc = torch.nn.CrossEntropyLoss()
  optimizer = torch.optim.SGD(params = model.parameters(), lr = 0.01)
  #     
  for epoch in range(n_epochs):
    train_loss = 0.0
    for data,target in train_loader:
      optimizer.zero_grad()  #              
      output = model(data)  #      
      loss = lossfunc(output,target) #        
      loss.backward()     #       ,        
      optimizer.step()    #           net   parameters  
      train_loss += loss.item()*data.size(0)
    train_loss = train_loss / len(train_loader.dataset)
    print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch + 1, train_loss))
    #         ,       
    test()

#            
def test():
  correct = 0
  total = 0
  with torch.no_grad(): #            
    for data in test_loader:
      images, labels = data
      outputs = model(images)
      _, predicted = torch.max(outputs.data, 1)
      total += labels.size(0)
      correct += (predicted == labels).sum().item()
  print('Accuracy of the network on the test images: %d %%' % (
    100 * correct / total))
  return 100.0 * correct / total

#        
model = MLP()

if __name__ == '__main__':
  train()

10個のepochのトレーニング効果は、最後に約85%の正確さを達成することができます。適切にepochを追加できますが、コードの中でgpuを使っていないので、遅くなるかもしれません。
以上のPyTorchを使ってMLPを実現しました。MNISTデータ集で検証した方法は小編集で皆さんに共有した内容です。参考にしていただければと思います。どうぞよろしくお願いします。