ニューラルネットワークを用いた教師あり学習のpythonプログラム

ニューラルネットワークClassを作成

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np

nn.Moduleを継承して,ニューラルネットワーク(NN)のニューロン数,optimizer,損失関数を決める.
損失関数によって求まるlossを小さくするようにoptimizerがNNのパラメータを最適化することによって学習を行う.

class Model(nn.Module):
    def __init__(self, input_dim, output_dim):
        super(Model, self).__init__()
        # NNの入出力
        self.fc1 = nn.Linear(input_dim, 100)
        self.fc2 = nn.Linear(100, 100)
        self.fc3 = nn.Linear(100, output_dim)
        # 学習率とパラメータの更新方法
        self.optimizer = optim.SGD(self.parameters(), lr=0.01)
        # loss関数
        self.criterion = nn.MSELoss()

活性化関数を定義

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

誤差逆伝播によって勾配を計算し,optimizerでパラメータ更新を行う.

    def update(self,output, y):
        self.optimizer.zero_grad()
        loss = self.criterion(output, y)
        # 勾配の計算
        loss.backward()
        # パラメータの更新
        self.optimizer.step()
        return loss

実験

# テストデータの作成
def math(x):
    return x*x + 2*x + 1

def make():
    x = np.random.rand(1000)
    y = math(x)
    return x,y

train_x, train_y = make()
test_x, test_y = make()
model = Model(1,1)

# テストデータ
gosa = 0
for i in range(1000):
    output = model(torch.tensor([[float(test_x[i])]]))
    gosa += abs((output - test_y[i]))

print("学習前:",gosa/1000)

# 訓練データを学習
for i in range(1000):
    output = model(torch.tensor([[float(train_x[i])]]))
    loss = model.update(output, torch.tensor([[float(train_y[i])]]))

# テストデータ
gosa = 0
for i in range(1000):
    output = model(torch.tensor([[float(test_x[i])]]))
    gosa += abs((output - test_y[i])[0])

print("学習後:",gosa/1000)

実行結果

学習前: tensor([[2.4048]], grad_fn=<DivBackward0>)
学習後: tensor([0.0174], grad_fn=<DivBackward0>)
Tags: