病状診断 PyTorch

病状診断

病状診断は医療分野に属する複雑な問題であり、実際の医療診断には十分なデータセットや専門知識が必要です。

ここでは、サンプルとしてシンプルな乳がんの診断を行うコードを示します。

乳がんの診断は二値分類問題で、PyTorchを使用して簡単なニューラルネットワークを構築して実行します。

このサンプルでは、乳がんのデータセットであるBreast Cancer Wisconsin (Diagnostic) Data Setを使用します。

データセットはscikit-learnライブラリから利用できます。

また、結果を分かりやすくするためにMatplotlibを使用してグラフ化します。

まず、必要なライブラリをインポートします。

1
2
3
4
5
6
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

次に、データセットをロードして前処理を行います。

1
2
3
4
5
6
7
8
9
10
# データセットの読み込み
data = load_breast_cancer()
X, y = data.data, data.target

# データをPyTorchのテンソルに変換
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.float32).view(-1, 1)

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

次に、簡単なニューラルネットワークモデルを定義します。

1
2
3
4
5
6
7
8
9
10
11
12
13
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(30, 16)
self.fc2 = nn.Linear(16, 8)
self.fc3 = nn.Linear(8, 1)
self.sigmoid = nn.Sigmoid()

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

次に、モデルを訓練して、結果をグラフ化します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# モデルの初期化
model = SimpleModel()

# 損失関数とオプティマイザの設定
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 訓練ループ
num_epochs = 100
train_losses = []
test_losses = []

for epoch in range(num_epochs):
# 訓練
model.train()
optimizer.zero_grad()
outputs = model(X_train)
loss = criterion(outputs, y_train)
loss.backward()
optimizer.step()
train_losses.append(loss.item())

# テスト
model.eval()
with torch.no_grad():
outputs = model(X_test)
loss = criterion(outputs, y_test)
test_losses.append(loss.item())

# グラフのプロット
plt.plot(train_losses, label='Train Loss')
plt.plot(test_losses, label='Test Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

このコードでは、訓練データとテストデータに対する損失の推移を可視化しています。

訓練データとテストデータの損失が共に減少していることが確認できれば、モデルがうまく機能していることが分かります。

ただし、このサンプルはあくまで簡単なものであり、実際の医療診断にはより高度なモデルや専門知識が必要です。

[実行結果]

ソースコード解説

このソースコードは、PyTorchを使用して単純なニューラルネットワークモデルを定義し、乳がんデータセットを使ってそのモデルを訓練し、訓練とテストの損失をプロットするプログラムです。

  1. データの準備:

    • ライブラリのインポート: 必要なライブラリをインポートします。
      PyTorchのニューラルネットワーク関連のモジュール(torch, torch.nn, torch.optim)やデータセットの読み込みに使うScikit-learn関連のモジュール(sklearn.datasets, sklearn.model_selection)をインポートしています。
    • データセットの読み込み: Scikit-learnのload_breast_cancer()関数を使って乳がんデータセットをロードします。
      このデータセットは、乳がんの診断に関連する特徴量と対応するラベル(0: 悪性、1: 良性)を持つものです。
  2. データの前処理:

    • データをPyTorchのテンソルに変換: NumPy配列からPyTorchのテンソルに変換します。
      特徴量Xは浮動小数点数のテンソルに変換され、ラベルyは浮動小数点数のテンソルに変換され、さらに1次元テンソルに変形(.view(-1, 1))されます。
    • 訓練データとテストデータに分割: train_test_split()関数を使ってデータを訓練データとテストデータに分割します。
      ここでは、全体の20%をテストデータとして使用し、乱数のシードを固定して再現性を確保しています。
  3. ニューラルネットワークモデルの定義:

    • SimpleModelクラス: PyTorchのnn.Moduleを継承した単純なニューラルネットワークモデルを定義しています。
      このモデルは、3つの全結合層(nn.Linear)とそれらの間の活性化関数(nn.Sigmoid)で構成されています。
  4. モデルの初期化:

    • model = SimpleModel(): SimpleModelクラスからモデルをインスタンス化します。
  5. 損失関数とオプティマイザの設定:

    • criterion = nn.BCELoss(): 二値交差エントロピー損失関数(Binary Cross Entropy Loss)を使用します。
      この損失関数は、二値分類問題に適しています。
    • optimizer = optim.Adam(model.parameters(), lr=0.01): Adamオプティマイザを使用して、モデルのパラメータを最適化します。
      学習率(lr)は0.01です。
  6. 訓練ループ:

    • num_epochs = 100: エポック数を100に設定します。
      エポックとは、データセット全体を一度学習することを意味します。
    • train_lossestest_losses: 訓練中に各エポックの訓練損失とテスト損失を保存するためのリストです。
  7. 訓練とテストの実行:

    • model.train(): モデルを訓練モードに設定します。
    • 訓練データで順伝播を行い、損失を計算します。
      そして逆伝播とオプティマイザのステップ(パラメータ更新)を行います。
    • model.eval(): モデルを評価モードに設定します。
      これにより、ドロップアウトなどの評価時にのみ適用されるレイヤーが適切に動作します。
    • テストデータで順伝播を行い、テスト損失を計算します。
      逆伝播は行いません。
  8. グラフのプロット:

    • 訓練とテストの損失をエポックごとにプロットします。
      プロットされたグラフは、訓練損失とテスト損失のエポックごとの変化を可視化するのに役立ちます。

このプログラムは、単純なニューラルネットワークを使って乳がんデータセットを分類するタスクを行っており、訓練とテストの損失を監視することでモデルの学習の進行状況を確認できます。