[Pytorch学習-2] pytorchの紹介

このメモは、導入部分のすべてのコードを実装しているため、実行できる必要があります。
(Jupyterノートブックを使用)
注意深くタイプセットされたメモリンク:
pytorchエントリメモ

以下は、ノートの内容であることを見るためにリンクを使用することをお勧めします。
2 Pytorchクイックスタート
2.1の最初の段階取得に開始
2.2.1テンソル
テンソルはA高とみなすことができるPytorch、データ構造であります次元配列。Tensorはnumpyのndarrayに似ていますが、TensorはGPUアクセラレーションを使用できます。
テンソルの基本的な使い方:
から将来の輸入print_functionの
輸入トーチTとして
"「」---------------------------------- -------------------------------- "" "
x = t.Tensor(5、3)#ビルド5 * 3マトリックス、割り当てられたスペース、初期化されていない
print(x)
"" "----------------------------------- ------------------------------- "" "
x = t.rand(5、3)#[0、1を使用] 2次元配列の均一に分散されたランダム初期化
print(x)
"" "-------------------------------- ---------------------------------- "" "
print(x.size())#の形状を表示x
print(x.size()[0]、x。
"" "----------------------------------------------- ------------------- "" "
y = t.rand(5、3)
print(x + y)#加算を書き込む最初の方法
t.add(x 、y)#足し算を書く2番目の方法

加算を書き込む3番目の方法:結果として加算結果の出力先を指定します

result = t.Tensor(5,3)#スペースを事前に割り当てます
t.add(x、y、out = result)#
結果への入力結果
“” "--------------- --------------------------------------------------- -"" "
print("初期y: ")
print(y)
print("最初の加算、yの結果: ")
y.add(x)#yの内容を変更せずに通常の加算
print(y)
print( "2番目の加算、yの結果:")

関数名の後にアンダースコア_が付いている関数は、Tensor自体を変更します

y.add_(x)#インプレース加算、yを
print(y)
"" "に変更------------------------------ ------------------------------------ "" "

Tensorの選択操作はnumpyに似ています

x [:、1]
“” "----------------------------------------- ------------------------- "" "
a = t.ones(5)#新建一004全是1テンソル
b = a.numpy( )#テンソル-> numpy
“” "---------------------------------------- -------------------------- "" "
import numpy as np
a = np.ones(5)
b = t.from_numpy(a)# Numpy-> Tensor
print(a)
print(b)
“” "----------------------------------- ------------------------------- "" "
b.add_(1)

_で終わる関数は自分自身を変更します

print(a)
print(b)#TensorとNumpyの共有メモリ
"" "--------------------------------- --------------------------------- "" "

cudaをサポートしていないマシンでは、次のステップは実行されません

if t.cuda.is_available():
x = x.cuda()
y = y.cuda()
print(x + y)
2.2.2 Autograd:自動差分
深層学習の本質は、バックプロパゲーションを通じて導出を取得することです。 Autogradモジュールはこの機能を実装します。Autogradは、Tensorでのすべての操作について、自動微分を提供し、逆数を手動で計算する複雑なプロセスを回避できます。
autograd.VariableはAutogradのコアクラスであり、Tensorをカプセル化するだけで、ほとんどすべてのTensor操作をサポートします。TensorがVariableとしてカプセル化された後、その.backwardを呼び出してバックプロパゲーションを実現し、すべての勾配を自動的に計算できます。変数のデータ構造は次のとおりです。

変数には主に次の3つの属性が含まれます。
データ:変数に含まれるテンソルを保存します。
grad:データに対応する勾配を保存します。勾配も変数であり、テンソルではなく、データと同じ形状です。
grad_fn:関数オブジェクトをポイントします。この関数は、バックプロパゲーション計算入力の勾配を計算するために使用されます。
torch.autogradインポート変数から

Tensorを使用して変数を作成します

必要な導関数を表すテンソルのrequires_gradフラグを設定します

pytorchは自動的にautogradを呼び出して操作を記録します

x = Variable(t.ones(2,2)、requires_grad = True)

前のステップはと同等です

x = t.ones(2,2)

x.requires_grad = True

print(x)
“” "------------------------------------------- ----------------------- "" "
y = x.sum()
print(y)
print(y.grad_fn)
print(y.backward)

y = x.sum()=(x [0] [0] + x [0] [1] + x [1] [0] + x [1] [1])

各値の勾配は1です

print(x.grad)
“” "----------------------------------------- ------------------------- "" "

gradはバックプロパゲーションに蓄積されます。つまり、バックプロパゲーションを実行するたびに、グラデーションは前のグラデーションを蓄積します。

したがって、逆伝播の前に勾配をクリアする必要があります

y.backward()
x.grad
y.backward()
x.grad

アンダースコアで終わる関数はインプレース演算です

x.grad.data.zero _()
y.backward()
x.grad
"" "------------------------------ ------------------------------------ "" "
2.2.3ニューラルネットワーク
Autogradはバックプロパゲーション機能を実現し、ただし、ディープラーニングの記述に直接使用されるコードは、多くの場合、まだ少し複雑です。Torch.nnは、ニューラルネットワーク専用に設計されたモジュラーインターフェイスです。nnはAutograd上に構築されており、ニューラルネットワークの定義と実行に使用できます。nn.Moduleは、nnの中で最も重要なクラスです。これは、ネットワークの各層の定義とforwardメソッドを含むネットワークカプセル化と見なすことができます。forward(入力)メソッドを呼び出すと、フォワード伝播の結果を返すことができます。nn.Moduleを使用して実装する方法を確認するために、最も初期の畳み込みニューラルネットワークLeNetを例として取り上げましょう。LeNetのネットワーク構造は次のとおりです。

これは基本的なフィードフォワードネットワークです。入力を受け取り、レイヤーを介して操作を渡し、出力を取得します。
ネットワークの定義ネットワークを定義するとき
は、nn.Moduleを継承し、そのforwardメソッドを実装する必要があります。学習可能なパラメーターを含むレイヤーをコンストラクターinitに配置します。レイヤー(ReLUなど)に学習可能なパラメーターがない場合は、コンストラクターに配置するか、そのままにしておくことができます。
import torch as t
import torch.nn as nn
import torch.nn.functional as F

クラスネット(nn.Module):
デフのinit(自己):
nn.Moduleサブクラスの#関数はコンストラクタで親クラスのコンストラクタを実行する必要があります
#次の式がnn.Moduleと同等です。INIT(自己)
スーパー(Net、self)。init()
#畳み込み層「1」は入力画像が単一チャネルであることを意味し、「6」は出力チャネルの数を意味します
#「5」は畳み込みカーネルが5 * 5であることを意味します
#畳み込み層
self.conv1 = nn .Conv2d(1、6、5)
self.conv2 = nn.Conv2d(6、16、5)
#アフィン層/完全に接続された層y = Wx + b
self.fc1 = nn.Linear(16 5
5、120 self.fc2 = nn.Linear(
120、84 self.fc3 = nn.Linear(84、10)

def forward(self, x): 
    # 卷积 -> 激活 -> 池化
    x = F.max_pool2d(F.relu(self.conv1(x)),(2, 2))
    x = F.max_pool2d(F.relu(self.conv2(x)), 2)
    # reshape, '-1' 表示自适应
    x = x.view(x.size()[0], -1)
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    return x

net = Net()
print(net)
フォワード関数がnn.Moduleのサブクラスで定義されている限り、バックワード関数は自動的に実装されます(Autogradを使用)。forward関数では、Variableでサポートされている任意の関数を使用できます。また、if、forループ、print、logなどのPython構文を使用することもできます。書き込み方法は標準のPython書き込み方法と一致しています。
ネットワークの学習可能なパラメーターはnet.parameters()によって返され、net.named_pa​​rametersは学習可能なパラメーターと名前を同時に返すことができます。
params = list(net.parameters())
print(len(params))#
出力に含まれるパラメーターの数
print(params)#各パラメーターには具体的に値
"" "が含まれます---------- -------------------------------------------------- ------ "" "

各レイヤーの名前とtorch.sizeを出力します

名前の場合、net.named_pa​​rameters()のパラメーター:
print(name、“:”、parameters.size())
forward関数の入力と出力は変数であり、Variableのみが自動導出の機能を持ち、Tensorはそうではありません。入力するときは、Tensorを変数に変換し
ますinput = Variable(t.randn(1、1、32、32))
out = net(input)
out.size()
"" "--------- --- ----------------------------------------------- --- ---- "" "
net.zero_grad()#すべてのパラメーターがクリアされます
。backward(t.ones(
1、10 ))#逆伝播は、torch.nnがミニのみをサポートすることに注意する必要があります。バッチは入力をサポートしません。一度に1つのサンプルのみ、つまり、一度に1つのバッチを入力する必要があります。1つのサンプルのみを入力する場合は、input.unsqueeze(0)を使用してbatch_sizeを1に設定します。たとえば、nn.Conv2dの入力は、nSamples * nChannels * Height * Widthのように4次元である必要があります。nSamplesを1、つまり1 * nChannels * Height * Widthに設定できます。
損失関数
nnは、ニューラルネットワークのほとんどの損失関数を実装します。たとえば、nn.MSELossは平均二乗誤差の計算に使用され、nn.CrossEntropyLossはクロスエントロピー損失の計算に使用されます。
出力=ネット(入力)
target = t.arange(0.0、10)
print(target)
criteria = nn.MSELoss()
loss = Criteria(output、target)
print(loss)損失
のソースを(grad_fn属性を使用して)逆伝播すると、次のようになります。その計算図は次のとおりです。
入力-> conv2d-> relu-> maxpool2d-> conv2d-> relu-> maxpool2d-
> view-> linear-> relu-> linear-> relu-> linear-> MSELoss-> loss
#実行します。bakcward、呼び出しの
前後の勾配を観察しますnet.zero_grad()#ネット
プリント内のすべての学習可能なパラメーターの勾配をクリアします(「バックプロパゲーション前のconv1.grad.biasの勾配」)
print(net.conv1.bias.grad )
loss.backward()
print( "バックプロパゲーション後のconv1.biasの勾配")
print(net.conv1.bias。
grad)オプティマイザー
バックプロパゲーションのすべてのパラメーターの勾配を計算した後、最適化手法を使用してネットワークの重みとパラメーターを更新する必要もあります。たとえば、確率的勾配降下法(SGD)の更新戦略は次のとおりです
。weight= weight-learning_rate *勾配
手動実験は次のとおりです。

net.parameters()のfのlearning_rate = 0.01
f.data.sub_(f.grad.data * Learning_rate)#
インプレース減算torch.optimは、RMSProp、Adam、SGDなどの深層学習のほとんどの最適化手法を実装します。などの方が使い勝手が良いので、通常は上記のコードを手動で書く必要はありません。
torch.optimをoptimとしてインポートします

新しいオプティマイザーを作成し、調整するパラメーターと学習率を指定します

オプティマイザー= optim.SGD(net.parameters()、lr = 0.01)

トレーニング中

最初にグラデーションをクリアします(net.zero_grad()も同じ効果があります)

オプティマイザー.zero_grad()

損失を計算する

出力=ネット(入力)
損失=基準(出力、ターゲット)

誤差逆伝播法

loss.backward()
#パラメーターの更新
optimizer.step()
print(loss)
データの読み込みと前処理
ディープラーニングでは、データの読み込みと前処理は非常に複雑で面倒ですが、PyTorchはデータ処理を簡素化および高速化するための簡単な回答をいくつか提供しますプロセスツール。同時に、一般的に使用されるデータセットの場合、PyTorchは、ユーザーがすばやく呼び出すためのカプセル化されたインターフェイスも提供します。これらのデータセットは主にトーチビジョンに保存されます。
Torchvisionは、ImageNet、CIFAR10、MNISTなどの一般的な画像データ読み込み機能と、データ読み込みを大幅に容易にする一般的なデータ変換操作を実装しています。
2.2.4小さなテスト:CIFAR-10の分類
CIFAR10データセットの分類を試してみましょう。手順は次のとおりです。
(1)トーチビジョンを使用してCIFAR10データセットをロードして前処理します。
(2)ネットワークを定義します。
(3)損失関数とオプティマイザを定義します。
(4)ネットワークをトレーニングし、ネットワークパラメータを更新します。
(5)ネットワークをテストします。

(1)CIFAR-10データセットのロードと前処理
CIFAR-10は、一般的に使用されるカラー画像データセットであり、飛行機、自動車、鳥、猫、鹿、犬、カエル、馬、船、トラックの10のカテゴリがあります。各画像は3 * 32 * 32、つまり解像度32 * 32の3チャンネルカラー画像です。こうしたEとして、事前にデータセットをダウンロードして、指定したディレクトリに配置します。。/データ/このディレクトリに、ローダポイントファイルがすでに存在していることをプログラムの検出のルートパラメータとは、それを直接解凍
のtとしてインポートトーチを
インポートtorch.nn as nn
import torch.nn.functional as F
from torch import optim
import torchvision as tv
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage
show = ToPILImage()#テンソルを画像に変換して簡単に視覚化できます

プログラムtorchvisionを最初に実行すると、CIFAR-10データセットが自動的にダウンロードされます。

ある程度の時間がかかります(約1億)

CIFAR-10をダウンロードした場合は、rootパラメーターで指定できます。

データの前処理を定義します

transform = transforms.Compose(
[
transforms.ToTensor()、#Tensorに
変換するtransforms.Normalize((0.5、0.5,0.5)、(0.5、0.5、0.5))、#正規化
])

トレーニングセット

trainset = tv.datasets.CIFAR10(
root = '/ home / cy / data'、
train = True、
download = True、
transform = transform)
trainloader = t.utils.data.DataLoader(trainset

batch_size = 4、
shuffle = True 、
num_workers = 2)

テストセット

testset = tv.datasets.CIFAR10(
root = '/ home / cy / data'、
train = False、
download = True、
transform = transoform)
testloader = t.utils.data.DataLoader(
testset、
batch_size = 4、
shuffle = False 、
num_workers = 2)

カテゴリー

クラス=( '飛行機'、 '車'、 '鳥'、 '猫'、 '鹿'、 '犬'、 'カエル'、 '馬'、 '船'、 'トラック')

Datasetオブジェクトはデータセットであり、次の方法でアクセスできます。戻り値(データ、ラベル)データ
(データ、ラベル)= trainset [100]
print(classes [label])

(data + 1)/ 2は正規化されたデータを復元するためのもので、プログラムによって出力される画像を以下に示します。

show((data + 1)/ 2).resize((100、100))

データローダーは、データセットから返された各データサンプルをバッチにスプライスし、マルチスレッドを使用して最適化とデータスクランブリングを高速化する反復可能なオブジェクトです。プログラムがデータセットのすべてのデータをトラバースすると、データローダーも完了します。1回の反復。
dataiter = iter(trainloader)
images、labels = dataiter.next()#4つの画像とラベルを返し
ますprint( "" .join(”%11s "%classes [labels [j]] for j in range(4)))
show (tv.utils.make_grid((images + 1)/ 2))。resize((400、100))

(2)ネットワーク
クラスを定義しますNet(nn.Module):
def init(self):
super(Net、self)。init()
self.conv1 = nn.Conv2d(3、6、5)#(入力チャネル、出力チャネル、畳み込みカーネルサイズ)
self.conv2 = nn.Conv2d(6、16、5)
self.fc1 = nn.Linear(16 5
5、120 self.fc2 = nn.Linear(
120、84 self.fc3 = nn.Linear(84、10)

def forward(self, x):
    # 卷积->激活->池化
    x = F.max_pool2d(F.relu(self.conv1(x)), 2)
    x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))
    x = x.view(x.size()[0], -1)
    x = F.relu(self.fc1(x)) 
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    return x

net = Net()
print(net)

(3)損失関数とオプティマイザを定義します。
トーチからインポート最適
基準= nn.CrossEntropyLoss()
オプティマイザー= optim.SGD(net.parameters()、lr = 0.001、momentum = 0.9)
(4)ネットワークをトレーニングし、ネットワークパラメーターを更新します。
すべてのネットワークのトレーニングプロセスは似ています!torch.autogradからの
トレーニングデータの
順方向伝搬+逆方向伝搬
更新パラメーターrange(10)のエポックの
変数

running_loss = 0.0
for i、enumerate(trainloader、0)の
データ#入力データ
入力、ラベル=データ
入力、ラベル= Variable(inputs)、Variable(labels)
#勾配クリア
オプティマイザー
.zero_grad ()#フォワード+バックワード
出力= net(入力)
損失=基準(出力、ラベル)
loss.backward()
#パラメーターを更新
optimizer.step()
#情報の印刷
running_loss + =損失
ifi%2000 == 1999:#トレーニングステータスを2000バッチごとに1回
印刷print( "[%d、%5d]損失:%。3f"%(epoch + 1、i + 1、running_loss / 2000))
running_loss = 0.0

print(“終了したトレーニング”)

(5)ネットワークをテストします。
dataiter = iter(trainloader)
images、labels = dataiter.next()#4つの画像とラベルを返す
print( "Actual Labels" + '、' .join ( '%11s'%classes [labels [j]] for j in range (4)))
show(tv.utils.make_grid((images)/2-0.5))。resize((400,100))

「」「----------------------------------------------」 「」

ネットワーク予測結果テスト

出力= net(Variable(images))

最高のカテゴリー

_、predicted = t.max(outputs.data、1)

print( "予測結果:"、 "" .join( "%5s"%classes [predicted [j]] for j in range(4)))

「」「----------------------------------------------」 「」

テストセット全体でテストする

正しい= 0#正しい写真をテストする
合計= 0#テスト
ローダー内のデータの写真の総数
画像、ラベル=データ
出力= net(Variable(images))
_、予測= t.max(outputs.data、1)

「_」アンダースコアの目的は、正しいカテゴリを受け取ることです

total += labels.size(0)
correct +=(predicted == labels).sum()

print( "10000枚のテストセットの正解率:%d %%"%(100 *正解/合計))

おすすめ

転載: blog.csdn.net/Leomn_J/article/details/112792451