Deep Learning for Time Series No.2
2020年初投稿です。
コロナで殆どの就活が止まり、推薦で進んでいた某JTBCは落ち、 泣きっ面にJASSMな中の人です。
お祈りメールを受ける30分前に前回の Deep Learning for Time Series No. 1 にスターがついたって通知が来て、こんな事やってたなって思い出したので、ちまちま書いていきます。
今回のお題は、CNNを使ってセンサーデータを分類するタスク。
準備
前回と同じく、SensorDatasetCollection の中に入ってるUCR HARデータセットを使います。 インストールは以下のようにして下さい。
pip install git+https://github.com/khirotaka/SensorDatasetCollection.git
次に、自分がKaggleや修士の研究のために作っている PyTorchラッパーをインストールしましょう。
pip install enchanter
Enchanterは comet.ml にガッツリ依存するように設計しているので、この先に進むには、アカウントを取得することをお勧めします。
実装
まずは使うモジュールの読み込みと、データセットの準備をします。
from comet_ml import Experiment import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader import enchanter import enchanter.addons as addons from sdc.datasets.uci import load_har (x_train, y_train), (x_test, y_test) = load_har(raw=True) x_train = x_train.astype("float32") # PyTorchの入力は float32 なので x_test = x_test.astype("float32") y_train = y_train.astype("int64") # PyTorchのラベルはint64なので y_test = y_test.astype("int64") y_train = y_train.reshape(-1, ) - 1 # データセットのラベルが1はじまりなので y_test = y_test.reshape(-1, ) - 1
データセットの準備が終わったので、次はPyTorchに流せるようにします。 今回のデータセットは固定長なので、次のようにするだけで解決です。
train_ds = enchanter.engine.modules.get_dataset(x_train, y_train) test_ds = enchanter.engine.modules.get_dataset(x_test, y_test) train_loader = DataLoader(train_ds, batch_size=512) test_loader = DataLoader(test_ds, batch_size=512)
あとは、ネットワークの実装をするだけです。 ここで実装するネットワークは非常に簡単なCNNで、活性化関数にMishを使っています。 理由はなんとなく。 ちゃんと設計するのだったら、層数や中間層のパラメータ、活性化関数の種類、あとはモデル構造(ResNetとか)を考える。
class Network(nn.Module): def __init__(self, in_channels, n_class): super().__init__() self.conv = nn.Sequential( nn.Conv1d(in_channels, 32, 3), nn.MaxPool1d(3), addons.Mish() ) self.fc = nn.Sequential( nn.Linear(32 * 42, 128), addons.Mish(), nn.Linear(128, n_class) ) def forward(self, x): x = x.permute(0, 2, 1) out = self.conv(x) out = out.view(-1, 32*42) out = self.fc(out) return out model = Network(9, 6) optimizer = optim.Adam(model.parameters())
これで準備が完了です。あとはラッパーに丸投げしましょう。
runner = enchanter.wrappers.ClassificationRunner( model, optimizer, nn.CrossEntropyLoss(), Experiment("XXXXXXXXXXXXXXXXXX") # Comet.ml のAPIキー ) runner.add_loader("train", train_loader) runner.add_loader("test", test_loader) runner.train_config(epochs=50) runner.run()
Enchanterの RunnerはGPUが使える場合は、自動的に使ってくれます。 明示的に指定する場合は、
runner.device = torch.device("gpu:1") # or runner.device = torch.device("cpu")
とすればOK。
最後に
これで、RNN・CNNの両方で、時系列データ(センサーデータ)を使ってニューラルネットで分類タスクを行う事ができました。 やる気が出れば、Transformer(Self-Attention) 系を使って時系列分類タスクを行おうと思います。
就活ツライ、どっか拾ってくんねぇかな... 人柄もスキルもとても評価してくれたなら採用してくれよ!
あ、あと、Kaggleで銀メダル取りました!!拾って下さい!
EnchanterのAPIに関しては、 enchanter.readthedocs.io