【概要】
本記事では、深層学習(Deep Learning)の基本となるモデルを
まずは動かしてみたいという人に向けて、
実装コードを展開するという内容になっています。
そのため、本記事では学習の安定化を図るドロップアウトや
バッチ正規化の実装、ニューラルネットに関する理論等、
については、取り扱っていないためご注意ください。
【本編】
初めに実装全体を眺めてみたいと思います。実装は、以下の通りです。
import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.utils.data import DataLoader, TensorDataset
class Net(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim, lr, batch_size, epoch):
# パラメータの設定 ★
# 学習率
self.lr = lr
# バッチサイズ
self.batch_size = batch_size
# エポック数(データ全体に対する学習の反復回数)
self.epoch = epoch
# 層構造の定義 ★
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.act1 = nn.ReLU()
self.fc2 = nn.Linear(hidden_dim, output_dim)
self.layers = [self.fc1, self.act1, self.fc2]
# 損失関数
self.criterion = nn.MSELoss()
# 最適化手法の指定
self.optimizer = torch.optim.Adam(self.parameters(), lr=self.lr)
def forward(self, x):
# 順伝播
for layer in self.layers:
x = layer(x)
return x
def fit(self, X, y=None, **params):
# 学習フェーズへ切り替え
self.train()
# 学習データの変換
tensorX = torch.from_numpy(X).float()
tensorY = torch.from_numpy(y).float()
train = TensorDataset(tensorX, tensorY)
# 学習データ全体をランダムに並び替え、バッチサイズごとにループ処理できるように変換
train_loader = DataLoader(train, batch_size=self.batch_size, shuffle=True)
# 学習
for epoch in range(self.epoch):
total_loss = 0
# バッチサイズ単位での処理
for train_x, train_y in train_loader:
train_x, train_y = Variable(train_x), Variable(train_y)
# 勾配の初期化
self.optimizer.zero_grad()
# 順伝播
output = self(train_x)
# 損失の算出
loss = self.criterion(output, train_y)
# 誤差逆伝播
loss.backward()
self.optimizer.step()
total_loss += loss.data
if (epoch+1) % 10 == 0:
print(f'[epoch:{epoch+1}] loss:{loss}')
return self
def predict(self, X):
# 検証フェーズへ切り替え
self.eval()
tensorX = torch.from_numpy(X).float()
test_X = Variable(tensorX)
return self(test_X)
基本的な実装ですが、
古典的な機械学習モデルや
scikit-learnのインターフェイスに慣れている人からすると、
実装コードの行数が多く、
Deep Learnig の実装は、大変に感じるかも知れません。
少なくとも、私はそうでした。。。
そんなとき、基本的なモデルで、
パラメータを変えて遊べるものがあればと思うことがあり、
同じような困り感がある人の助けになればと考え、
本記事を書くに至りました。
学習や予測に使われる関数群
forward()、fit()、predict()の中身はさておき、
(理論を学んだことがある方向けに、コードにはコメントを記載していますが、)
チューニングすべきパラメータは、コード上の「★」がついている箇所の
・ パラメータの設定 ★
・ 層構造の定義 ★
の部分のみです。
正規化/正則化の後、チューニングすべきかもしれませんが、
本記事の目標は、まずは動かすことなので、
ご容赦いただければと。。。
例えば、以下のようにパラメータを設定して、
動かすことができます。
※input_dimは特徴量の数、output_dimは目的変数の形式に応じて、
設定してください。
nn = Net(input_dim=10, hidden_dim=50, output_dim=1, lr=1e-4, batch_size=8, epoch=100)
nn.fit(train_X, train_y) # train_X:説明変数 train_y:目的変数
pred_y = nn.predict(test_X).data.numpy() # test_X:テストデータ
皆さんもよろしければ、Google Colab などで、動かしてみてください!