PyTorch入門一:ボリュームニューラルネットワークMNIST手書きデジタル識別を実現
47460 ワード
まずいくつかの入門PyTorchの良い資料を提供します: PyTorch公式チュートリアル(中国語版):http://pytorch123.com 「手作業で深く学ぶ」PyTorch版:https://github.com/ShusenTang/Dive-into-DL-PyTorch
1.PyTorch紹介
PyTorchはTorch 7チームが開発したもので、Torchとの違いはPyTorchが開発言語としてPythonを使用している点であり、同様にPython優先の深さ学習フレームワークであり、強力なGPU加速を実現するだけでなく、動的ニューラルネットワークもサポートしていることを示しており、TensorFlowなど多くの主流フレームワークではサポートされていない.さらにPyTorchは簡単に拡張でき、ここ2年はTensorFlowを追い抜く勢いがある.
2.コンボリューションニューラルネットワーク(CNN)
コンボリューションニューラルネットワーク(CNN-Convolutional Neural Network)は、フィードフォワードニューラルネットワークである.長い間、画像認識分野のコアアルゴリズムの1つであるこれはボリュームとニューラルネットワーク機構の概略図であり、次の各部分を理解してみましょう.入力層(Input Layer):私たちにとって入力されたのは画像ですが、コンピュータにとって入力されたのはマトリクスタイプのデータで、これらのデータはこの画像の画素値 を表しています.ボリューム層(Convolution Layers):入力されたデータを特徴抽出し、各ボリュームコアが1つの小領域から1つの特徴値を抽出するたびに、すべての特徴値を組み合わせて1つの特徴図が得られ、複数のボリューム照合で入力データを特徴抽出すると、複数の特徴図が得られる.このボリュームコアは と呼ばれています活性化関数(Activation Function):人工ニューラルネットワークのニューロン上で動作する関数で、ニューロンの入力を出力端にマッピングし、活性化関数を導入するのはニューラルネットワークモデルの非線形性 を増加させるためである.プール化層(Pooling Layer):特徴品質に影響を及ぼさずに画像を圧縮してパラメータを減らし、プール化は主に2種類あり、1つはMaxPooling、1つはAvePoolingである.プール化されたカーネルが2*2の行列であると仮定し、MaxPoolingを用いるとその最大値を出力し、AvePoolingを用いるとすべてのデータの平均値 を出力する.フルコネクション層(Fully Connected Layer、略称FC):ボリュームニューラルネットワーク全体にわたって「分類器」の役割を果たす.ボリューム層、プール化層、アクティブ化関数層などの動作が元のデータを暗黙層の特徴空間にマッピングする場合、全接続層は、学習した「分布式特徴表現」をサンプルタグ空間にマッピングする役割を果たす .出力層(Output Layer):コンボリューションニューラルネットワークにおける出力層の上流は通常、全接続層であるため、その構造および動作原理は従来のフィードフォワードニューラルネットワークにおける出力層と同じである.画像分類問題では、出力層は論理関数または正規化指数関数(softmax function)を使用して分類ラベルを出力する.物体認識(object detection)問題では、出力層は、出力物体の中心座標、大きさ、分類として設計することができる.画像の意味分割において、出力層は、各画素の分類結果 を直接出力.
ボリュームニューラルネットワークを理解したら、PyTorchのボリュームニューラルネットワークを見てみましょう.
3.PyTorchにおける畳み込みニューラルネットワーク
3.1ボリューム:nn.Conv2d()
パラメータは次のとおりです. in_channels:入力信号のチャネル数. out_channels:ボリューム後に出力結果のチャネル数. kernel_size:ボリュームコアの形状.例えばkernel_size=(3,2)は3 X 2の畳み込みコアを表し、幅と高さが同じであれば1つの数字だけで を表すことができる. stride:移動するステップの長さをロールアップし、デフォルトは1です. padding:境界を処理するときの塗りつぶし0の数、デフォルトは0(塗りつぶしなし)です. dilation:サンプリング間隔の数、デフォルトは1、無間隔サンプリング groups:入力と出力チャネルのパケット数.1でない場合、デフォルトは1(フル接続) です. biasがTrueの場合、バイアスを加える.
3.2池化層:nn.MaxPool2d()
パラメータは次のとおりです. kernel_Size:最大プール化操作時のウィンドウサイズ stride:最大プール化操作時のウィンドウ移動のステップ長、デフォルト値はkernel_size padding:入力エッジごとに暗黙的に0を補う数 dilation:ウィンドウ内の要素のステップ長を制御するパラメータ return_indices:Trueに等しい場合、max pooling結果を返しながら最大値のインデックスを返します.これは、その後のUnpoolingで に役立ちます. ceil_mode:Trueに等しい場合、計算出力が大きい場合、デフォルトの下方向の整列の代わりに上向きの整列が採用される .
4.MNIST手書きデジタル認識を実現
次にpytorchを用いて,手書き数字を訓練し識別するためのボリュームニューラルネットワークを構築する.
4.1ライブラリ関数の導入
4.2スーパーパラメータの設定
4.3データセットのロード
ここではdataloader反復器を使用してデータセットをロードします
上記のコードの役割は、次のとおりです. mnistトレーニングセットとテストセットをフォルダdataの にダウンロードは、tensorデータ型への変換を含むデータを変化させ、トレーニングセットのテストセットの独立した同分布を保証するために、データを正規分布 に正規化する.データは一括して保存され、順序が乱れ、後続の訓練が便利である.
4.4ネットワーク構造の設計
単純なボリュームニューラルネットワークの構造であり、一般的には:畳み込み層Conv:畳み込みコアにより画像特徴を抽出し、feature map を得る.プール化層Pool:ボリュームチェックを利用してfeature mapをダウンサンプリングし、サイズを減らす.最大プール化層はスライドウィンドウ内の最大画素であり、平均プール化層はスライドウィンドウ内の平均画素結果である. フル接続レイヤ:複数のlinear model+アクティブ化関数eg:ReLU.これで基本的なCNNが構成されていますが、私たちは勉強が好きな心理状態から、モデルの汎化能力を高めるために、深い学習訓練過程のtricksを理解したほうがいいです. batch normalization:簡単に言えば、前のレイヤの重み付け合計のすべての出力結果を一括正規化(標準正規分布)し、線形モデルを入力してアクティブ化関数に接続します. DropOut:全接続層では、確率を設定してランダムにこの層のいくつかの重みを0にし、ニューロンが無効になることに相当します.
4.5訓練前準備
4.6訓練
4.7予測
4.8運転
5結果
用のpytorch=0.4 CPUで走る
1.PyTorch紹介
PyTorchはTorch 7チームが開発したもので、Torchとの違いはPyTorchが開発言語としてPythonを使用している点であり、同様にPython優先の深さ学習フレームワークであり、強力なGPU加速を実現するだけでなく、動的ニューラルネットワークもサポートしていることを示しており、TensorFlowなど多くの主流フレームワークではサポートされていない.さらにPyTorchは簡単に拡張でき、ここ2年はTensorFlowを追い抜く勢いがある.
2.コンボリューションニューラルネットワーク(CNN)
コンボリューションニューラルネットワーク(CNN-Convolutional Neural Network)は、フィードフォワードニューラルネットワークである.長い間、画像認識分野のコアアルゴリズムの1つであるこれはボリュームとニューラルネットワーク機構の概略図であり、次の各部分を理解してみましょう.
ボリュームニューラルネットワークを理解したら、PyTorchのボリュームニューラルネットワークを見てみましょう.
3.PyTorchにおける畳み込みニューラルネットワーク
3.1ボリューム:nn.Conv2d()
パラメータは次のとおりです.
3.2池化層:nn.MaxPool2d()
パラメータは次のとおりです.
4.MNIST手書きデジタル認識を実現
次にpytorchを用いて,手書き数字を訓練し識別するためのボリュームニューラルネットワークを構築する.
4.1ライブラリ関数の導入
import torch.nn as nn # pytorch ,
import torch.nn.functional as F # , softmax
import torch.optim as optim # , , Adam SGD
from torch.optim import lr_scheduler # ,
from torchvision import transforms # pytorch
from torchvision import datasets # pytorch
4.2スーパーパラメータの設定
# (
BATCH_SIZE = 64 # ,
EPOCHS = 3 #
# torch GPU, GPU ,
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
learning_rate = 0.001 #
4.3データセットのロード
ここではdataloader反復器を使用してデータセットをロードします
#
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(mean=(0.5,), std=(0.5,)) #
])),
batch_size=BATCH_SIZE, shuffle=True) # , , 。
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])),
batch_size=BATCH_SIZE, shuffle=True)
上記のコードの役割は、次のとおりです.
4.4ネットワーク構造の設計
単純なボリュームニューラルネットワークの構造であり、一般的には:
#
class ConvNet(nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
#
self.features = nn.Sequential(
#
# 1, ,
# 32( 32 ),
# kernel_size 3 * 3,stride 1
# padding , 1
nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=1, padding=1),# ((28-3+2*1)/1)+1=28 28*28*1 》 28*28*32
# , out_channels ,
nn.BatchNorm2d(num_features=32), #28*28*32 》 28*28*32
# ,inplace=true
nn.ReLU(inplace=True),
nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1), # ((28-3+2*1)/1)+1=28 28*28*32 》 28*28*32
nn.BatchNorm2d(32),
nn.ReLU(inplace=True),
#
# kernel_size 2 * 2
# stride 2, 2
# , 1/4, 28 * 28 -》 7 * 7
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.Conv2d(64, 64, kernel_size=3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2)
)
#
self.classifier = nn.Sequential(
# Dropout
# p = 0.5 0.5 0
nn.Dropout(p=0.5),
# 64 * 7 * 7, 512
nn.Linear(64 * 7 * 7, 512),
nn.BatchNorm1d(512),
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(512, 512),
nn.BatchNorm1d(512),
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(512, 10),
)
#
def forward(self, x):
#
x = self.features(x)
#
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
4.5訓練前準備
# GPU CPU
ConvModel = ConvNet().to(DEVICE)
#
criterion = nn.CrossEntropyLoss().to(DEVICE)
# : ,
optimizer = torch.optim.Adam(ConvModel.parameters(), lr=learning_rate)
# : , step_size,gamma
exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=6, gamma=0.1)
# 。 lr = 0.05, step_size 30, gamma=0.01
# Assuming optimizer uses lr = 0.05 for all groups
# >>> # lr = 0.05 if epoch < 30
# >>> # lr = 0.005 if 30 <= epoch < 60
# >>> # lr = 0.0005 if 60 <= epoch < 90
4.6訓練
def train(num_epochs, _model, _device, _train_loader, _optimizer, _lr_scheduler):
_model.train() #
_lr_scheduler.step() #
for epoch in range(num_epochs):
#
for i, (images, labels) in enumerate(_train_loader):
samples = images.to(_device)
labels = labels.to(_device)
# , CNN , ,
# reshape -1 n
# reshape n , 28 * 28,
output = _model(samples.reshape(-1, 1, 28, 28))
#
loss = criterion(output, labels)
# 0
optimizer.zero_grad()
#
loss.backward()
#
optimizer.step()
if (i + 1) % 100 == 0:
print("Epoch:{}/{}, step:{}, loss:{:.4f}".format(epoch + 1, num_epochs, i + 1, loss.item()))
4.7予測
def test(_test_loader, _model, _device):
_model.eval() # evaluation
loss = 0
correct = 0
with torch.no_grad(): # backward , , 。
for data, target in _test_loader:
data, target = data.to(_device), target.to(_device)
output = ConvModel(data.reshape(-1, 1, 28, 28))
loss += criterion(output, target).item() #
pred = output.data.max(1, keepdim=True)[1] # ,
correct += pred.eq(target.data.view_as(pred)).cpu().sum() # .cpu() cpu 。
loss /= len(_test_loader.dataset)
print('
Average loss: {:.4f}, Accuracy: {}/{} ({:.3f}%)
'.format(
loss, correct, len(_test_loader.dataset),
100. * correct / len(_test_loader.dataset)))
4.8運転
for epoch in range(1, EPOCHS + 1):
train(epoch, ConvModel, DEVICE, train_loader, optimizer, exp_lr_scheduler)
test(test_loader,ConvModel, DEVICE)
test(train_loader,ConvModel, DEVICE)
5結果
用のpytorch=0.4 CPUで走る
Epoch:1/1, step:100, loss:0.1579
Epoch:1/1, step:200, loss:0.0809
Epoch:1/1, step:300, loss:0.0673
Epoch:1/1, step:400, loss:0.1391
Epoch:1/1, step:500, loss:0.0323
Epoch:1/1, step:600, loss:0.0870
Epoch:1/1, step:700, loss:0.0441
Epoch:1/1, step:800, loss:0.0705
Epoch:1/1, step:900, loss:0.0396
Average loss: 0.0006, Accuracy: 9881/10000 (98.000%)
Epoch:1/2, step:100, loss:0.0487
Epoch:1/2, step:200, loss:0.1519
Epoch:1/2, step:300, loss:0.0262
Epoch:1/2, step:400, loss:0.2133
Epoch:1/2, step:500, loss:0.0161
Epoch:1/2, step:600, loss:0.0805
Epoch:1/2, step:700, loss:0.0927
Epoch:1/2, step:800, loss:0.0663
Epoch:1/2, step:900, loss:0.0669
Epoch:2/2, step:100, loss:0.0124
Epoch:2/2, step:200, loss:0.0527
Epoch:2/2, step:300, loss:0.0256
Epoch:2/2, step:400, loss:0.0138
Epoch:2/2, step:500, loss:0.0894
Epoch:2/2, step:600, loss:0.1030
Epoch:2/2, step:700, loss:0.0528
Epoch:2/2, step:800, loss:0.1106
Epoch:2/2, step:900, loss:0.0044
Average loss: 0.0003, Accuracy: 9930/10000 (99.000%)