(C)pytorchの研究ノート

著者:chen_h
マイクロ・シグナル&QQ:862251340
マイクロチャネル公共数:coderpai


(A)pytorchの研究ノート

(B)pytorchの研究ノート

(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()機能だけで呼ばれていましたが、これは比較して、説明してnet2net1利点は、あなたがそのような(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=08つのデータをエクスポートしますが、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誤差を計算するために使用される。我々は、使用するいくつかの一般的な最適化、SGDMomentumRMSpropAdam

# 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アップグレード版とAdamRMSprop、アップグレードされたバージョン。しかし、この結果から、我々が見ます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

公開された414元の記事 ウォンの賞賛168 ビュー470 000 +

おすすめ

転載: blog.csdn.net/CoderPai/article/details/104138452