著者:chen_h
マイクロ・シグナル&QQ:862251340
マイクロチャネル公共数:coderpai
(C)pytorchの研究ノート
すぐに建てられた行動
トーチが邪魔に利便性の多くを提供し、同じニューラルネットワークが高速であることができ、高速、我々は同じリカレントニューラルネットワークを構築するための簡単な方法を使用する方法を見ています。
素早くビルド
前ニューラルネットワークを書き込む際に使用されるステップで見てみましょう。私たちはnet1
、このように構築されたニューラルネットワークの代わりに。
class Net(torch.nn.Module):
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, n_hidden)
self.predict = torch.nn.Linear(n_hidden, n_output)
def forward(self, x):
x = F.relu(self.hidden(x))
x = self.predict(x)
return x
net1 = Net(1, 10, 1) # 这是我们用这种方式搭建的 net1
私たちは、ニューラルネットワークアーキテクチャのクラスがトーチを継承使用して、いくつかの変更をしたが、速い動きがあり、一つの文章には、上記のすべての内容を要約したもの!
net2 = torch.nn.Sequential(
torch.nn.Linear(1, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 1)
)
我々は2つの構造を比較します:
print(net1)
"""
Net (
(hidden): Linear (1 -> 10)
(predict): Linear (10 -> 1)
)
"""
print(net2)
"""
Sequential (
(0): Linear (1 -> 10)
(1): ReLU ()
(2): Linear (10 -> 1)
)
"""
我々は見つけるでしょうnet2
、彼は一緒にまた、しかしに組み込まれた活性化関数置くので?理由は、マルチディスプレイ一部のコンテンツを、net1
活性化関数は、実際にされたforward()
機能だけで呼ばれていましたが、これは比較して、説明してnet2
、net1
利点は、あなたがそのような(RNN)としてあなたの個人的なパーソナライズあなた自身の前方伝播プロセスに応じてより多くの必要があるかもしれません、です。しかし、あなたは7788のプロセスを必要としない場合は、私がいることを信じてnet2
、このフォームはあなたのために、より適しています。
保存エキス
まあ、トレーニングモデル、我々は確かに直接直接抽出を使用するには、次の時間滞在する、それを保存したい、これは友人のこのセクションの内容である。我々は、保全エキスを達成するために、たとえば、回帰ニューラルネットワークを使用していました。
保存
私たちは迅速にネットワークを構築するために、データを構築します:
torch.manual_seed(1) # reproducible
# 假数据
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1)
y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1)
def save():
# 建网络
net1 = torch.nn.Sequential(
torch.nn.Linear(1, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 1)
)
optimizer = torch.optim.SGD(net1.parameters(), lr=0.5)
loss_func = torch.nn.MSELoss()
# 训练
for t in range(100):
prediction = net1(x)
loss = loss_func(prediction, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
次は、私たちは、保存するために二つの方法があります
torch.save(net1, 'net.pkl') # 保存整个网络
torch.save(net1.state_dict(), 'net_params.pkl') # 只保存网络中的参数 (速度快, 占内存少)
抽出ネットワーク
このアプローチは、全体のニューラルネットワークを抽出し、ネットワークに大きな時間が遅くなることがあります。
def restore_net():
# restore entire net1 to net2
net2 = torch.load('net.pkl')
prediction = net2(x)
唯一のネットワークパラメータを抽出
このアプローチは、すべてのパラメータを抽出して、新しいネットワークを配置します。
def restore_params():
# 新建 net3
net3 = torch.nn.Sequential(
torch.nn.Linear(1, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 1)
)
# 将保存的参数复制到 net3
net3.load_state_dict(torch.load('net_params.pkl'))
prediction = net3(x)
検索結果表示
上記で作成したいくつかの機能を呼び出し、その後、プロットします。
# 保存 net1 (1. 整个网络, 2. 只有参数)
save()
# 提取整个网络
restore_net()
# 提取网络参数, 复制到新网络
restore_params()
認定トレーニング
トーチと呼ばれる、あなたのデータ構造を整理するために良いことを提供しDataLoader
、我々は彼らのデータをパッケージ化するために使用することができ、バッチ訓練。訓練のバッチと、さまざまな方法を持つことができます。
データローダー
DataLoader
トーチはラッパーをあなた自身(numpyの配列または他の)テンソルにロードされたデータフォーマットについて話すようにします。あなたのデータをパッケージ化するためのツールを提供し、次に置くために。使用DataLoader
何が良いの?それをであることを彼らの助け例えば、あなた効率的な反復データ、:
import torch
import torch.utils.data as Data
torch.manual_seed(1) # reproducible
BATCH_SIZE = 5 # 批训练的数据个数
x = torch.linspace(1, 10, 10) # x data (torch tensor)
y = torch.linspace(10, 1, 10) # y data (torch tensor)
# 先转换成 torch 能识别的 Dataset
torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)
# 把 dataset 放入 DataLoader
loader = Data.DataLoader(
dataset=torch_dataset, # torch TensorDataset format
batch_size=BATCH_SIZE, # mini batch size
shuffle=True, # 要不要打乱数据 (打乱比较好)
num_workers=2, # 多线程来读数据
)
for epoch in range(3): # 训练所有!整套!数据 3 次
for step, (batch_x, batch_y) in enumerate(loader): # 每一步 loader 释放一小批数据用来学习
# 假设这里就是你训练的地方...
# 打出来一些数据
print('Epoch: ', epoch, '| Step: ', step, '| batch x: ',
batch_x.numpy(), '| batch y: ', batch_y.numpy())
"""
Epoch: 0 | Step: 0 | batch x: [ 6. 7. 2. 3. 1.] | batch y: [ 5. 4. 9. 8. 10.]
Epoch: 0 | Step: 1 | batch x: [ 9. 10. 4. 8. 5.] | batch y: [ 2. 1. 7. 3. 6.]
Epoch: 1 | Step: 0 | batch x: [ 3. 4. 2. 9. 10.] | batch y: [ 8. 7. 9. 2. 1.]
Epoch: 1 | Step: 1 | batch x: [ 1. 7. 8. 5. 6.] | batch y: [ 10. 4. 3. 6. 5.]
Epoch: 2 | Step: 0 | batch x: [ 3. 9. 2. 6. 7.] | batch y: [ 8. 2. 9. 5. 4.]
Epoch: 2 | Step: 1 | batch x: [ 10. 4. 8. 1. 5.] | batch y: [ 1. 7. 3. 10. 6.]
"""
図から分かるように、各ステップ5データが学ぶ派生。そして、最初の後にエクスポート破壊され、各エポックのデータをエクスポートします。
我々はそれを変更する場合、これは本当に便利なポイントではありません。BATCH_SIZE = 8
私たちが知っているので、step=0
8つのデータをエクスポートしますが、step=1
データがデータベース8に存在しない、それを行う方法:
BATCH_SIZE = 8 # 批训练的数据个数
...
for ...:
for ...:
...
print('Epoch: ', epoch, '| Step: ', step, '| batch x: ',
batch_x.numpy(), '| batch y: ', batch_y.numpy())
"""
Epoch: 0 | Step: 0 | batch x: [ 6. 7. 2. 3. 1. 9. 10. 4.] | batch y: [ 5. 4. 9. 8. 10. 2. 1. 7.]
Epoch: 0 | Step: 1 | batch x: [ 8. 5.] | batch y: [ 3. 6.]
Epoch: 1 | Step: 0 | batch x: [ 3. 4. 2. 9. 10. 1. 7. 8.] | batch y: [ 8. 7. 9. 2. 1. 10. 4. 3.]
Epoch: 1 | Step: 1 | batch x: [ 5. 6.] | batch y: [ 6. 5.]
Epoch: 2 | Step: 0 | batch x: [ 3. 9. 2. 6. 7. 10. 4. 8.] | batch y: [ 8. 2. 9. 5. 4. 1. 7. 3.]
Epoch: 2 | Step: 1 | batch x: [ 1. 5.] | batch y: [ 10. 6.]
"""
この場合、step=1
それはちょうどあなたがうまくデータの残りの部分で、この時代に戻っ与えることです。
オプティマイザオプティマイザ
この図は、さまざまな部コントラストオプティマイザということです。
ダミーデータ
様々なオプティマイザの効果を比較、我々はいくつかのデータを持っている必要があり、今日我々はまだいくつかの擬似コンパイルされたデータを所有し、このように、これらのデータには:
import torch
import torch.utils.data as Data
import torch.nn.functional as F
import matplotlib.pyplot as plt
torch.manual_seed(1) # reproducible
LR = 0.01
BATCH_SIZE = 32
EPOCH = 12
# fake dataset
x = torch.unsqueeze(torch.linspace(-1, 1, 1000), dim=1)
y = x.pow(2) + 0.1*torch.normal(torch.zeros(*x.size()))
# plot dataset
plt.scatter(x.numpy(), y.numpy())
plt.show()
# 使用上节内容提到的 data loader
torch_dataset = Data.TensorDataset(x, y)
loader = Data.DataLoader(dataset=torch_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=2,)
ニューラルネットワークを最適化するために、各オプティマイザ
オプティマイザのそれぞれを比較するために、我々は彼らそれぞれがニューラルネットワークを作成するには与えるが、ニューラルネットワークは同じであるNet
フォーム。
# 默认的 network 形式
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(1, 20) # hidden layer
self.predict = torch.nn.Linear(20, 1) # output layer
def forward(self, x):
x = F.relu(self.hidden(x)) # activation function for hidden layer
x = self.predict(x) # linear output
return x
# 为每个优化器创建一个 net
net_SGD = Net()
net_Momentum = Net()
net_RMSprop = Net()
net_Adam = Net()
nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]
オプティマイザオプティマイザ
次に、異なるトレーニングネットワークごとに異なるオプティマイザを作成し、作成loss_func
誤差を計算するために使用される。我々は、使用するいくつかの一般的な最適化、SGD
、Momentum
、RMSprop
、Adam
。
# different optimizers
opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam]
loss_func = torch.nn.MSELoss()
losses_his = [[], [], [], []] # 记录 training 时不同神经网络的 loss
トレーニング/上映
次のトレーニングや損失の描画。
for epoch in range(EPOCH):
print('Epoch: ', epoch)
for step, (b_x, b_y) in enumerate(loader):
# 对每个优化器, 优化属于他的神经网络
for net, opt, l_his in zip(nets, optimizers, losses_his):
output = net(b_x) # get output for every net
loss = loss_func(output, b_y) # compute loss for every net
opt.zero_grad() # clear gradients for next train
loss.backward() # backpropagation, compute gradients
opt.step() # apply gradients
l_his.append(loss.data.numpy()) # loss recoder
SGD
最も一般的なオプティマイザで、何の促進効果がありません、と言うことができMomentum
ているSGD
勢い原則の後ろを追加修正版が、RMSprop
あるMomentum
アップグレード版とAdam
でRMSprop
、アップグレードされたバージョン。しかし、この結果から、我々が見ますAdam
効果は、以上のようでRMSprop
少し小さい。そうではない、より高度なオプティマイザ、良い結果。私たちはあなたのデータ/ネットワーク最適化のために最も適したを見つけるために、独自の実験で異なる最適化を試すことができます。
リンク:
https://morvanzhou.github.io/tutorials/machine-learning/torch/
https://github.com/MorvanZhou/PyTorch-Tutorial/blob/master/tutorial-contents/303_build_nn_quickly.py
https://github.com/MorvanZhou/PyTorch-Tutorial/blob/master/tutorial-contents/304_save_reload.py
https://github.com/MorvanZhou/PyTorch-Tutorial/blob/master/tutorial-contents/305_batch_train.py
https://github.com/MorvanZhou/PyTorch-Tutorial/blob/master/tutorial-contents/306_optimizer.py