python日記:pytorchで簡単なニューラルネットワークを構築する

9308 ワード

最近pytorchのフレームワークを勉強して、最も最も基本的なpytorchでニューラルネットワークを構築し、訓練する方法を共有しています.私は初めてこのような分かち合いの文章を書いて、pytorchを初めて勉強した友达に役に立つことを望んでいます!
一、任務
まず、私たちが構築しなければならないネットワークが完成しなければならない学習任務を話します:私たちのニューラルネットワークに論理的な異或演算を学ばせて、異或演算は俗称の“同じように0を取って、異なるのは1を取ります”です.さらに、私たちのニーズを簡単に言えば、入力(1,1)時に0を出力し、入力(1,0)時に1(同じ0、異なる1)を出力するニューラルネットワークを構築する必要があります.
二、実現構想
私たちのニーズには2つの入力、1つの出力が必要ですので、入力レイヤに2つの入力ノードを設定し、出力レイヤに出力ノードを設定する必要があります.問題が比較的に簡単なため、私達は10個のノードを設置するだけで良い効果を達成することができて、隠し層の活性化関数は私達はReLU関数を採用して、出力層はSigmoid関数を使って、出力を0から1の1つの範囲に維持させて、もし出力が0.5より大きいならば、出力結果を1にして、0.5より小さくて、出力結果を0にします.
三、実現過程
ネットワークを構築する際、簡単な高速構築法を使用します.この方法は積み木のように、ニューラルネットワークを迅速かつ効率的に構築することができます.具体的には、以下のように実現されています.
ステップ1:必要なライブラリの導入
コードは次のとおりです.
import torch
import torch.nn as nn
import numpy as np

pytorchではもちろんtorchパッケージを導入し、コードを書くためにtorchパッケージのnnをnnで代用します.nnというパッケージはneural networkの略で、ニューラルネットワークを構築するためのパッケージです.numpyを導入したのは,入力としてマトリクスを作成するためである.
ステップ2:入力セットの作成
コードは次のとおりです.
#      
x = np.mat('0 0;'
           '0 1;'
           '1 0;'
           '1 1')
x = torch.tensor(x).float()
y = np.mat('1;'
           '0;'
           '0;'
           '1')
y = torch.tensor(y).float()

個人的にはnpが好きです.matという方法でマトリクスを構築するのは、書き方が簡単だと感じます.もちろん、他の方法も使えます.しかし、行列を構築するには必ずこのステップが必要である.tensor(x).float()は、作成した入力をtensor変数に変換する必要があります.
tensorとは何ですか?彼がpytorchで使われている変数であることを簡単に理解することができます.pytorchというフレームワークを使うには、まず変数をtensor変数に変換する必要があります.私たちのこのニューラルネットワークはあなたの入力と出力がfloat浮動小数点型でなければならないことを要求します.tensor変数の浮動小数点型を指しています.npを使っています.matで作成する入力はint型で、tensorに変換しても自動的にitensorのint型に変換されるので、後に付けます.float()は浮動小数点型に変換される.
これにより、入力と出力(それぞれxマトリクスとyマトリクス)を構築し、xは4行2列のマトリクスであり、彼の各行は入力であり、1回に2つの値を入力し、ここではすべての入力状況を列挙した.出力yは4行1列のマトリクスであり、各行は出力であり、xマトリクスの各行の入力に対応する.
ステップ3:ネットワークの構築
コードは次のとおりです.
#     
myNet = nn.Sequential(
    nn.Linear(2, 10),
    nn.ReLU(),
    nn.Linear(10, 1),
    nn.Sigmoid()
)
print(myNet)

nnパッケージのSequentialを使用してネットワークを構築します.この関数は、積み木のようにニューラルネットワークを構築できるものです.
nn.Linear(2,10)の意味で入力層を作り,中の2は入力ノード個数,10は出力ノード個数を表す.Linearは英語の線形です.つまり、この層には他のアクティブ化関数が含まれていません.あなたが入力したものを入力すると、彼はあなたに何を出力しますか.nn.ReLU()これは、アクティブな関数レイヤを表し、さっきの入力をReLU関数に捨てます.それからまたLinearが来て、最後にSigmoid関数に投げました.2,10,1はそれぞれ3つの層の個数を表し,簡単明瞭である.
ステップ4:オプティマイザの設定
コードは次のとおりです.
#      
optimzer = torch.optim.SGD(myNet.parameters(), lr=0.05)
loss_func = nn.MSELoss()

このステップの理解は、ネットワークを訓練するために最適化する方法が必要であるため、私たちが採用する最適化方法を設定しています.
torch.optim.SGDの意味はSGDの方法を採用して訓練して、あなたはただあなたのネットのパラメータと学習率が伝わるだけでいいです.それぞれmyNetです.parametsとlr.loss_funcという文は代価関数を設定し,我々のこの問題は比較的簡単であるため,MSE,すなわち平均二乗誤差代価関数を採用した.
ステップ5:トレーニングネットワーク
コードは次のとおりです.
for epoch in range(5000):
    out = myNet(x)
    loss = loss_func(out, y)  #     
    optimzer.zero_grad()  #     
    loss.backward()
    optimzer.step()

ここでは5000回のサイクル(何度も必要ないかもしれない)を設定し、この訓練の動作を5000回反復させた.毎回の出力はmyNet(x)で、入力をあなたのネットワークに投げ込むと出力out(こんなに簡単で乱暴!)が得られます.そして代価関数とあなたの標準出力yで誤差を求めます.勾配をクリアするステップは、再反復するたびに前回求めた勾配をクリアするために、このステップを覚えておけばいいので、初学はあまり深く理解する必要はありません.loss.backward()はもちろん誤差を逆方向に伝播させ、optimzer.Step()は、設定したばかりのオプティマイザを動作させます.
ステップ6:テスト
コードは次のとおりです.
print(myNet(x).data)

出力結果:
tensor([[0.9424],
        [0.0406],
        [0.0400],
        [0.9590]])

この結果は私たちが期待していた結果に非常に近いことがわかります.もちろん、データテストを変えることもできます.結果も似ています.ここでは、なぜ私たちのコードの末尾に1つ追加されたのかを簡単に説明します.Dataは、私たちのtensor変数は実は2つの部分を含んでいるため、一部はtensorデータで、もう一部はtensorの自動導出パラメータで、私たちは加えます.dataはtensorのデータを出力することを意味し、加算しないと次のように出力されます.
tensor([[0.9492],
        [0.0502],
        [0.0757],
        [0.9351]], grad_fn=)

今日の分かち合いはここまでで、私は初めてブログを出して、不適切なところを書いてまたみんなが指摘することを批判することを望んで、初めてpytorchを学ぶあなたを助けることができるかどうか分からないで、完全なコードは以下の通りです:
import torch
import torch.nn as nn
import numpy as np

#      
x = np.mat('0 0;'
           '0 1;'
           '1 0;'
           '1 1')
x = torch.tensor(x).float()
y = np.mat('1;'
           '0;'
           '0;'
           '1')
y = torch.tensor(y).float()

#     
myNet = nn.Sequential(
    nn.Linear(2, 10),
    nn.ReLU(),
    nn.Linear(10, 1),
    nn.Sigmoid()
)
print(myNet)

#      
optimzer = torch.optim.SGD(myNet.parameters(), lr=0.05)
loss_func = nn.MSELoss()

for epoch in range(5000):
    out = myNet(x)
    loss = loss_func(out, y)  #     
    optimzer.zero_grad()  #     
    loss.backward()
    optimzer.step()


print(myNet(x).data)