혈당치를 예측하는 공부(그 1~PytorchLightning의 LSTM~)

무엇을 하는가



혈당치 데이터를 pytorch의 LSTM에서 예측해 보겠습니다.

왜 할까



이유 그 1: 기술적 관심


  • 기계 학습용의 데이터는 넷을 찾으면 여러가지 떨어지고 있어 분석용 소스 코드도 많이 있어, 모델도 좋은 느낌으로 만들어 주거나, 하이퍼파라미터 튜닝 후이거나로 간단하게 좋은 점수가 나간다. 실제 원시 데이터로부터 분석(의 고생)을 해보고 싶다.
  • 괜찮은 기계 학습 코드를 작성하는 것은 처음에 e 자격을 얻기 위해 공부합니다

  • 이유 그 弐 : 혈당 관리


  • 어쩌면 카보 (탄수화물량)와 지금까지의 추이에서 치러야 할 인슐린량을 제안해 주었으면 한다 (꽤 앞선 목표)

  • 어떻게 하는가


  • 사용할 데이터:
  • 자신의 혈당치 데이터

  • 분석에 사용하는 것:
  • pytorch-lightning


  • 데이터 검색



  • 이 항목으로 작성된 구성의 MongoDB에서 데이터를 추출합니다
  • 2020/11/28-2020/12/5까지 (때로는 누락되지만) 5 분 간격으로 혈당치 데이터


  • 그래프는 이런 느낌(날짜마다 색칠), 상당히 담당 의사에게 화난 느낌의 그래프


  • 분석 코드



    훈련용 데이터 6, 검증용 데이터 2, 테스트 데이터 2로 나누기


    #6:2:2に分ける
    n_train = int(len(x) * 0.6)
    n_val = int(len(x) * 0.2)
    
    x_train, t_train = x[0: n_train], t[0: n_train]
    x_val, t_val = x[n_train: n_train+n_val], t[n_train: n_train+n_val]
    x_test, t_test = x[n_train+n_val:], t[n_train+n_val:]
    
    
    #train, validation, testにまとめる
    train = torch.utils.data.TensorDataset(x_train, t_train)
    val = torch.utils.data.TensorDataset(x_val, t_val)
    test = torch.utils.data.TensorDataset(x_test, t_test)
    

    결정의 Net (훈련용, 검증용, 테스트용)


    import torch.nn as nn
    import torch.nn.functional as F
    
    import pytorch_lightning as pl
    from pytorch_lightning import Trainer
    
    # 学習データの処理
    class TrainNet(pl.LightningModule):
    
        @pl.data_loader
        def train_dataloader(self):
            return torch.utils.data.DataLoader(train, self.batch_size, num_workers=self.num_workers)
    
        def training_step(self, batch, batch_nb):
            x, t = batch
            y = self.forward(x)
            loss = self.lossfun(y, t)
            tensorboard_logs = {'train_loss': loss}
            results = {'loss': loss, 'log':tensorboard_logs}
            return results
    
    # 学習データの処理
    class ValidationNet(pl.LightningModule):
    
        @pl.data_loader
        def val_dataloader(self):
            return torch.utils.data.DataLoader(val, self.batch_size)
    
        def validation_step(self, batch, batch_nb):
            x, t = batch
            y = self.forward(x)
            loss = self.lossfun(y, t)
            results = {'val_loss': loss}
            return results
    
        def validation_end(self, outputs):
            avg_loss = torch.stack([x['val_loss'] for x in outputs]).mean()
            tensorboard_logs = {'val_loss': avg_loss}
            results = {'val_loss': avg_loss, 'log':tensorboard_logs}
            return results
    
    # テストデータの処理
    class TestNet(pl.LightningModule):
    
        @pl.data_loader
        def test_dataloader(self):
            return torch.utils.data.DataLoader(test, self.batch_size)
    
        def test_step(self, batch, batch_nb):
            x, t = batch
            y = self.forward(x)
            loss = self.lossfun(y, t)
            results = {'test_loss': loss}
            return results
    
        def test_end(self, outputs):
            avg_loss = torch.stack([x['test_loss'] for x in outputs]).mean()
            tensorboard_logs = {'test_loss': avg_loss}
            results = {'test_loss': avg_loss, 'log':tensorboard_logs}
            return results
    

    LSTM


  • Optimizer는 Adam, loss 함수는 MSELoss를 사용합니다.
    # LSTM モデルの作成
    class LSTM(TrainNet, ValidationNet, TestNet):
    
        def __init__(self, input_size=1, hidden_size=10, output_size=1, batch_size=32, num_workers=1):
            super().__init__()
            self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
            self.linear = nn.Linear(hidden_size, output_size)
            self.batch_size = batch_size
            self.num_workers = num_workers
    
        def forward(self, x):
            x = x.view(x.size(0), 1, 1)
            x, (h, c) = self.lstm(x)
            x = self.linear(x.view(x.size(0), -1))
            return x
    
        def lossfun(self, y, t):
            return F.mse_loss(y.float(), t.float())
    
        def configure_optimizers(self):
            return torch.optim.Adam(self.parameters(), lr=0.01)
    

    훈련


    from pytorch_lightning.callbacks import ModelCheckpoint
    
    # 再現性を確保するためシードを固定する
    torch.manual_seed(0)
    
    # モデルをインスタンス化
    net = LSTM()
    
    # モデルのパラメータの保存場所を指定
    checkpoint_callback = ModelCheckpoint(
        filepath='drive/MyDrive/glu_analysis/weights.ckpt',
        verbose=True,
        monitor='val_loss',
        mode='min'
    )
    
    
    # 学習の実行
    trainer = Trainer(checkpoint_callback=checkpoint_callback, min_epochs=1000)
    trainer.fit(net)
    

    추론


    # チェックポイントからモデルのパラメータをロード
    checkpoint = torch.load('drive/MyDrive/glu_analysis/weights.ckpt/_ckpt_epoch_219.ckpt')
    
    # インスタンスを作成、モデルのパラメータをセット
    model = LSTM()
    model.load_state_dict(checkpoint['state_dict'])
    
    # 推論モードにする
    model.eval()
    model.freeze()
    
    # テストデータを食べさせる 
    outputs = model(x_test)
    
    

    tensorboard로 시각화



    (※log를 나중에 출력했으므로, 상기의 실행의 결과와는 바뀌고 있을 가능성 있음)
    %load_ext tensorboard
    %tensorboard --logdir ./lightning_logs/version_1/
    


    이마이치 같은 느낌,,,

    예측 결과(파랑: 예측, 오렌지: 실제)


  • 조금, 내려가는 곳이 예측되고 있지만, 좀처럼 그대로는 어렵다.


  • 실은 정직 경향이 맞다고는 생각하고 있지 않았다,,,,, 지금까지의 데이터로부터 밥의 시간이 예측되고 있다고 하는 것인가,,,,! ?

  • 미래


  • 우선 처음으로 일련의 흐름을 통과할 수 있었으므로 향후 여러가지 개선해 나가고 싶다.
  • 다음 단계는 statemodel을 사용하여 추세 성분 등을 나누어 분석한다.
  • 외부 입력으로서, 인슐린량(기초 인슐린료 포함한다)이나, 카보(탄수화물)를 넣어 예측할 수 없는 것,, ,

  • 참고


  • htps : // cp p ぇ 아 r 마인 g. 이 m / py와 rch-gght 마늘 g /
  • 현장에서 사용할 수 있는 Pytorch 개발 입문
  • htps : // 구루타카-ぉg. 코 m / py와 rch-Go-Go-Coboura와 ry-t Neso r 보아 rd
  • 좋은 웹페이지 즐겨찾기