[Medical AI with Python: P31] AIの「眼」を作る:PyTorchとCNNによる画像認識の世界へ

目次

TL; DR (要約)

AIは、どうやって画像を「見る」のか?その答えが、人間の視覚を模倣したCNNです。
画像からパターンを階層的に学習する「AIの眼」の仕組みと、医療応用における最強のテクニックの要点です。

① AIの「視覚」の仕組み
(CNNの基本)

畳み込み層が画像から線や模様を検出し、プーリング層が情報を要約。これを繰り返し、単純な特徴から複雑な概念(腫瘍など)を認識します。

② 最強のテクニック
(転移学習)

膨大な画像で賢くなった既存AIの「眼」を借り、医療画像用に微調整(ファインチューニング)。データが少なくても高性能なAIを開発できます。

③ AIの3つの「眼」
(主要タスク)

分類:「がんか否か」を判定
物体検出:「どこに」結節があるかを示す
セグメンテーション: 腫瘍の「正確な形」を塗り分ける

この章の学習目標と前提知識

この章の学習目標 前提となる知識
  • なぜ画像認識にCNNが必要なのか、その根本的な理由(パラメータ数、空間構造)を理解する。
  • CNNの心臓部である「畳み込み層」「プーリング層」の役割を、概念的に説明できるようになる。
  • 少ないデータで高性能なモデルを構築する「転移学習」の考え方と、その具体的な手法(ファインチューニング)の概要を掴む。
  • モデルの性能を向上させる「データ拡張」の重要性と、その具体的な手法を学ぶ。
  • 画像認識の主要タスク(分類、物体検出、セグメンテーション)の違いを理解し、CNNが全ての基礎となっていることを知る。
  • AI・機械学習の基本的な概念
    ニューラルネットワーク、学習、パラメータといった基本的な用語に聞き覚えがあること。
  • (推奨) PythonとPyTorchの基礎知識
    コードの解説をより深く理解するために役立ちますが、必須ではありません。本記事は理論の理解を主眼としています。
  • 画像のデジタル表現の初歩的な理解
    「画像がピクセルの集まりである」という程度の、ごく基本的なイメージがあれば十分です。

はじめに:AIは、画像をどう「見て」いるのか?

皆さん、こんにちは!いよいよ「応用モデルと実践トレーニング」編のスタートです。前回の総合演習では、臨床検査値のような「表形式」のデータを扱いましたが、ここからは、AIの応用分野として最も華やかで、そして医療現場での期待が非常に大きい「画像」の世界へと、本格的に足を踏み入れていきます。

皆さんが日々向き合っている、レントゲン、CT、MRI、そして病理組織像…。これらの膨大な画像データの中に、人間の目だけでは捉えきれない微細なパターンや、診断・治療に繋がる重要な情報が眠っているとしたら、素晴らしいと思いませんか?

しかし、これらの画像をAIで扱うのは、実は一筋縄ではいきません。前回まで使ってきた、全結合のニューラルネットワーク(MLP)に、画像をそのまま入力しようとすると、二つの大きな壁が立ちはだかります。

  1. パラメータ数の爆発: 例えば、224×224ピクセルの小さなカラー画像でさえ、\(224 \times 224 \times 3 = 150,528\)個もの数値の集まりです。もし最初の隠れ層のノード数が1000個だとしたら、最初の層だけで1億5千万個以上のパラメータが必要になってしまい、学習が非常に困難です。
  2. 空間構造の喪失: さらに深刻なのが、MLPは入力をただの一列の長いベクトルとして扱うため、ピクセル同士の「位置関係」が完全に失われてしまう、という問題です。画像において、「どのピクセルが、どのピクセルの隣にあるか」という空間的な情報は、意味を理解する上で決定的に重要ですよね。「目」が「鼻」の上にあるから、私たちはそれを顔だと認識できます。この大切な構造を、MLPは壊してしまうのです。

この、画像特有の「空間構造」を保ったまま、効率的にパターンを抽出するために生まれたのが、畳み込みニューラルネットワーク(Convolutional Neural Network, CNN)です。

CNNの設計思想は、生物の視覚野の仕組みに深いヒントを得ています。私たちの脳も、網膜から入ってきた光の信号を、まずエッジや線といった単純な要素を検出するニューロンで処理し、それらを組み合わせて、より複雑な形や物体を認識していきますよね。CNNは、この階層的な特徴抽出のプロセスを、畳み込み層プーリング層という特殊な層を使って、見事に模倣しているのです。まさに、AIに「モノを見るための正しい眼」を与えるアーキテクチャと言えるでしょう。

この記事では、この画像認識の「王者」として長年君臨してきたCNNについて、その基本的な仕組みから、PyTorchでの実装の雰囲気、そして転移学習といった非常に強力な応用テクニックまで、その全体像をダイジェスト形式で一望していきます。より詳細な理論や一つ一つの実装ステップについては、今後の個別記事(14.1〜14.9)でじっくりと掘り下げていく予定ですので、今回はまず「CNNという新しい世界の地図」を手に入れることを目標にしましょう!

14.1 画像データの基礎とTorchVisionでの前処理 〜AIの「眼」に、画像を正しく見せるための下準備〜

さて、私たちが普段何気なく見ている「画像」ですが、コンピュータはこれを一体どのように認識しているのでしょうか?実は、彼らにとって、画像は単なる数値が並んだマス目(グリッド)に過ぎません。

  • 古い白黒写真のようなグレースケール画像は、ピクセルの明るさを0(黒)から255(白)の数値で表した、2次元の「表」(行列)です。
  • 普段目にするカラー画像は、この表が「赤(R)」「緑(G)」「青(B)」の3枚重ねになっている、3次元の「立体的な表」(テンソル)として扱われます。私たちが見る鮮やかな色は、この3色の光の強さの組み合わせで表現されているわけですね。

カラー画像のテンソル表現

カラー画像のテンソル表現 画像は「高さ・幅・チャンネル」の3次元データとして扱われる カラー画像 Rチャンネル Gチャンネル Bチャンネル (H, W, 3) の3次元テンソル 高さ (H) 幅 (W) チャンネル (3) 1ピクセルのデータ [217, 30, 30]

しかし、AIモデルにこれらの画像を学習させるには、この数値のグリッドをそのまま「食べさせる」わけにはいきません。モデルが効率よく、そして偏りなく学習できるように、いくつかの前処理(Preprocessing)、つまり「下ごしらえ」をしてあげる必要があります。

この、少し面倒に思える下ごしらえ作業を、非常に簡単かつ体系的に実行できるようにしてくれるのが、PyTorchの画像処理用ライブラリtorchvisionに含まれる、transformsという便利なツールキットです。

主な前処理の「レシピ」

実際にコードでどのように使うか、まずは典型的な前処理の「レシピ」を見てみましょう。このように、一連の処理をtransforms.Composeでパイプラインとして定義するのが一般的です。


# 必要なライブラリをインポート
from torchvision import transforms

# 画像データに対する一連の前処理を定義
data_transforms = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], 
                         std=[0.229, 0.224, 0.225])
])

このレシピの一つ一つの工程が何をしているのか、詳しく見ていきましょう。

  • transforms.Resize() / CenterCrop() AIモデルに入力する画像のサイズは、全て同じ大きさに揃える必要があります。これは、モデルの入力層の大きさが固定されているためです。Resizeで指定した大きさに変更したり、CenterCropで中央部分を切り抜いたりして、サイズを統一します。
  • transforms.ToTensor() これが非常に重要な変換です。この処理は、主に二つのことを行います。一つは、画像をPyTorchが計算で扱えるテンソル形式に変換すること。もう一つは、各ピクセルの値(通常0〜255)を、0.0〜1.0の範囲に正規化(スケーリング)することです。このスケーリングにより、後の計算が安定します。
  • transforms.Normalize() 最後の仕上げです。先ほどのToTensorで0〜1の範囲になったピクセル値を、さらに平均が0、標準偏差が1になるように標準化します。これは、第13回で学んだ表形式データに対するStandardScalerと全く同じ目的で、学習をより安定させ、高速化する効果があります。ここで使われているmeanstdの値は、ImageNetという巨大データセットの統計量から計算された「おまじない」のようなもので、転移学習を行う際には、この値を使うのが一般的です。

このように、torchvision.transformsを使うことで、画像データに対する一連の必須の前処理を、一貫した「レシピ」として定義し、簡単に適用することができます。これで、どんな画像データも、AIモデルが美味しく食べられる、理想的な「食材」に変換する準備が整いました。

14.2 畳み込みニューラルネットワーク(CNN)の理論 〜AIに「視覚」を与える魔法の仕組み〜

さて、前回、単純な全結合ニューラルネットワーク(MLP)では画像の「空間構造」が失われてしまう、という大きな問題点を見ました。では、CNNは、どうやってこの問題を解決しているのでしょうか?その答えは、人間の視覚野の仕組みにヒントを得た、畳み込み層プーリング層という、二つの賢い部品にあります。

畳み込み層 (Convolutional Layer) 〜「特徴スキャナ」で画像を探る〜

CNNの核心は、カーネル(またはフィルタ)と呼ばれる、数x数ピクセルの小さな「特徴スキャナ」にあります。このスキャナは、特定のお宝(パターン)だけを探し出す専門家だと考えてください。例えば、「縦線」を探す専門家、「赤い色」を探す専門家、「特定のザラザラした質感」を探す専門家、といった具合です。

この小さなスキャナが、入力画像の上を、左上から右下へとスライドしながら、くまなく「スキャン」していきます。そして、自分の担当する特徴(例えば「縦線」)を見つけると、その場所で強く反応(高い数値を出力)します。このスキャナが画像全体をスキャンし終えた後の「反応マップ」が、特徴マップ(Feature Map)と呼ばれるものです。

畳み込み演算のイメージ

畳み込み演算のイメージ (Convolution) 入力画像 (5×5) 12301 01230 10123 21012 32101 カーネル (3×3) 101 010 101 = 出力 (特徴マップ) 7 ?? ??? ??? 計算の詳細 (出力の左上の値「7」が求まるまで) 入力の左上3×3領域とカーネルの各要素を掛けて、全て足し合わせる (積和演算) (1×1) + (2×0) + (3×1) + (0×0) + (1×1) + (2×0) + (1×1) + (0×0) + (1×1) =   1   +   0   +   3    +   0   +   1   +   0    +   1   +   0   +   1 7

重要なのは、この「特徴スキャナ(カーネル)」のパラメータ(重み)は、学習を通じてAIが自動で獲得するということです。私たちは「縦線を検出しろ」と教えるのではなく、AIがデータから「縦線のようなパターンが、このタスクを解くのに重要らしい」と自ら学び、そのようなフィルタを形成していくのです。

プーリング層 (Pooling Layer) 〜情報を「要約」して、本質を捉える〜

畳み込み層は素晴らしい特徴マップを作ってくれますが、情報が少し詳細すぎることがあります。ピクセル単位で正確な位置が分かりすぎると、かえって、対象が少しズレただけで違うものだと誤認識してしまうかもしれません。

そこでプーリング層の出番です。この層は、特徴マップをいくつかの小さな領域に区切り、その領域の代表値(例えば、領域内の最大値(Max Pooling)や平均値(Average Pooling))だけを残して、情報をギュッと要約します。この処理には、主に以下の3つのメリットがあります。

  • 位置ズレへの頑健性: 対象が画像内で多少動いても、プーリング後の出力は変化しにくくなります。
  • 計算量の削減: 特徴マップのサイズが小さくなるので、後続の層での計算が軽くなります。
  • 本質的な特徴の抽出: 細かすぎる情報をそぎ落とし、その領域で最も重要な情報だけを強調する効果があります。

階層的な特徴学習

そして、CNNの真の力は、この「畳み込み → 活性化(ReLUなど)→ プーリング」という一連の処理を、何層にもわたって積み重ねることで発揮されます。これは、私たちの視覚野とそっくりです。

  • 初期の層: 単純なエッジや色、グラデーションといった、ごく基本的な視覚要素を検出するフィルタを学習します。
  • 中間の層: 初期の層が抽出した特徴を組み合わせ、「眼」「鼻」「口」といった、より複雑なパーツを検出するフィルタを学習します。
  • 深い層: さらにそれらを組み合わせて、「顔」「犬」「猫」、あるいは医療画像であれば「腫瘍の特異的な形状」といった、非常に高次で抽象的な概念を認識できるようになるのです。

この階層的な特徴学習こそが、CNNが画像認識で圧倒的な成功を収めた、最大の理由なんですね。

14.3〜14.5 実践!PyTorchでCNNモデルを訓練する 〜「見る」AIをゼロから育てる〜

14.3 MNIST編:AI開発における「Hello, World!」

さて、CNNを構成する基本的な部品について学んだところで、いよいよ実践です。どんなに優れた理論も、実際に手を動かしてコードにしてみなければ、本当の意味で身についたとは言えませんよね。

プログラミング学習で、誰もが最初に print("Hello, World!") と打ち込むように、画像認識の世界にも、誰もが最初に通る「登竜門」的なデータセットが存在します。それが、今回私たちが挑戦するMNIST(エムニスト)です。

MNISTデータセットとは?

MNISTは、0から9までの手書き数字を集めた、非常に有名なデータセットです。画像は28×28ピクセルの小さな白黒画像で、合計7万枚(訓練用6万枚、テスト用1万枚)が含まれています。そのシンプルさと扱いやすさから、新しいアルゴリズムの性能を試す際の、最初のベンチマークとして、長年愛され続けているんですよ。

Wikipedia

この演習のゴール

このセクションの目標は、このMNISTデータセットを使い、CNNモデルの構築から、データの読み込み、学習、そして評価まで、画像分類の基本的なパイプラインを一気通貫で実装する経験を積むことです。一つ一つのステップは、これまでの講義で学んだ知識の総復習になります。

PyTorchのtorchvisionライブラリを使えば、この有名なMNISTデータセットも、驚くほど簡単に手に入れることができます。


# 必要なライブラリをインポート
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 画像に対する前処理を定義
transform = transforms.Compose([
    transforms.ToTensor(), # 画像をテンソルに変換
    transforms.Normalize((0.5,), (0.5,)) # -1から1の範囲に正規化
])

# 訓練用データセットをダウンロード(もし手元になければ)して読み込む
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)

# データローダーを作成し、ミニバッチとして扱えるようにする
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

たったこれだけで、MNISTデータセットのダウンロードから前処理、そしてミニバッチ化までが完了します。本当に便利ですよね。この「基礎体力トレーニング」をしっかりとこなすことで、この後のより複雑な医療画像の課題に、自信を持って挑むことができるようになるはずです。

14.4 データ拡張:AIに「多様な視点」を教える、賢い水増し術

さて、MNISTのようなデータセットで訓練を始めると、モデルはすぐに訓練データに対しては高い正解率を出すようになるかもしれません。しかし、私たちが本当に欲しいのは、訓練データで満点を取ることではなく、未知の新しいデータに対しても高い性能を発揮する、般化性能の高いモデルですよね。

私たちが手書きの「7」を見るとき、それが少し傾いていたり、かすれていたり、中心からズレていたりしても、問題なく「7」だと認識できます。AIにも、こうした見た目の「ちょっとした違い」に惑わされない、頑健性(ロバスト性)を持たせたいものです。しかし、私たちが用意できる訓練データに含まれる画像のバリエーションには、どうしても限りがあります。

この、「もっと多様なデータが見たい!でも、新しいデータを集めるのは大変だ…」というジレンマを解決してくれる、非常に賢くて強力なテクニックが、データ拡張(Data Augmentation)です。

これは、手元にある訓練画像に、プログラム上でランダムな「加工」をリアルタイムに施し、擬似的にデータのバリエーションを「水増し」する手法です。1枚の元画像から、まるで無限かのように、少しずつ違うバージョンの画像を生成して、それをモデルの学習に使うのです。

データ拡張の概念図

データ拡張の概念図 元の画像 データ拡張 回転 左右反転 拡大 明るさ変更

このデータ拡張も、PyTorchのtorchvision.transformsを使えば、驚くほど簡単に実装できます。前処理の「レシピ」に、これらのランダムな加工処理を追加するだけです。


# 必要なライブラリをインポート
from torchvision import transforms

# データ拡張を含む、訓練データ用の前処理パイプライン
train_transforms = transforms.Compose([
    transforms.RandomRotation(15), # -15度から+15度の範囲でランダムに回転
    transforms.RandomHorizontalFlip(p=0.5), # 50%の確率で左右反転
    transforms.ColorJitter(brightness=0.2, contrast=0.2), # 明るさとコントラストをランダムに変更
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,)) # MNIST(白黒)の場合の正規化
])

transforms.Composeの中にRandom...で始まる変換処理を組み込むだけで、データローダーが画像を一枚取り出すたびに、その場でランダムな加工が施された、毎回「新しい」画像がモデルに供給されるようになります。

AIは、これらの「そっくりだけど、ちょっと違う」画像を学習することで、「傾き」や「明るさ」といった本質的でない特徴に惑わされず、対象物の「形」や「構造」そのものを、より深く理解するようになります。その結果、過学習が抑制され、モデルの般化性能が大きく向上するのです。特に、収集できるデータ数が限られがちな医療AIの分野では、このデータ拡張は、モデルの性能を最大限に引き出すための、極めて重要で、ほぼ必須のテクニックと言っても過言ではないでしょう。

14.5 CIFAR-10編:カラー画像という新たな挑戦 〜AIの「色覚」と「物体認識能力」を試す〜

MNISTでの手書き数字認識、お疲れ様でした!基本的な画像分類のパイプラインは、もうすっかりお手の物、といったところでしょうか。白黒の、比較的整った数字の世界で自信をつけたら、次はもう少しだけ現実世界に近い、色鮮やかで、そして少しだけ厄介な課題に挑戦してみましょう。

CIFAR-10データセットとは?

ここで登場するのが、CIFAR-10(サイファー・テン)という、これまた画像認識のベンチマークとして非常に有名なデータセットです。このデータセットには、飛行機自動車鹿カエルトラックという、合計10クラスの、32×32ピクセルの小さなカラー画像が含まれています。

CIFAR-10データセットの例

https://www.cs.toronto.edu/~kriz/cifar.html

MNISTからのステップアップ:何が新しい挑戦なのか?

一見すると、これも小さな画像を分類するだけのタスクに見えるかもしれません。しかし、MNISTと比べて、CIFAR-10にはAIにとっていくつかの新しい「壁」が用意されています。

  • 1. カラー情報(3チャンネル) MNISTは白黒(1チャンネル)でしたが、CIFAR-10はカラー(RGBの3チャンネル)です。これは、モデルが扱うべき情報の次元数が3倍になることを意味します。AIは、形だけでなく「色」という新しい特徴も考慮して、物体を認識しなければなりません。
  • 2. クラス内の多様性 (Intra-class Variation) 「7」という数字は、誰が書いても、ある程度似た形をしています。しかし、「犬」と一口に言っても、チワワもいれば、ゴールデンレトリバーもいますよね。同じクラスの中でも、見た目が非常に多様である、という現実世界に近い難しさがあります。
  • 3. 背景の複雑さ (Background Complexity) MNISTの数字は、ほとんどが白い背景に黒い文字でした。しかし、CIFAR-10の画像には、森の中にいる鹿や、海に浮かぶ船など、様々な背景が含まれています。AIは、背景という「ノイズ」の中から、本当に認識すべきオブジェクトだけを見つけ出す能力が問われます。

幸い、このCIFAR-10も、torchvisionを使えばMNISTとほとんど同じように、簡単に準備することができます。


# 必要なライブラリをインポート
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# CIFAR-10用の前処理 (カラー画像なので3チャンネル用の正規化)
transform = transforms.Compose([
    transforms.ToTensor(),
    # 3チャンネル(RGB)それぞれの平均と標準偏差を指定します。
    transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))
])

# 訓練用データセットをダウンロードして読み込む
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)

# データローダーを作成
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

このCIFAR-10というデータセットに取り組むことで、私たちは、より実践的な画像分類問題への応用力を養い、モデルのアーキテクチャやデータ拡張の工夫が、性能にどう影響するかを、より深く体感していくことになります。

14.6 CNNのブラックボックスを覗く:フィルタと特徴マップの可視化 〜AIの「眼」が、一体何を見ているのか?〜

CNNが、画像の中から驚くほど正確にパターンを見つけ出す力を持っていることは、もうお分かりいただけたかと思います。しかし、ここで一つの大きな疑問が生まれます。「一体、AIはどうやってそれを見分けているんだろう?」と。

CNNの判断プロセスは、しばしば「ブラックボックス」と批判されます。特に、人の生命に関わる医療AIの分野では、「なぜAIがこの画像を陽性と判断したのか?」という問いに答えられない、つまり解釈性(Interpretability)説明可能性(Explainability)が低いモデルは、臨床現場で信頼を得て、安全に利用することが非常に難しいのです。万が一、AIが想定外の部分(例えば、画像に写り込んだノイズやアーチファクト)を見て判断していたとしたら、大変なことになりますよね。

幸い、このブラックボックスに小さな「窓」を開け、CNNの内部を覗き見るための、いくつかの基本的な手法があります。今回はその代表として、学習済みのCNNが獲得したフィルタと、画像が各層を通過した後の特徴マップを可視化する方法を見ていきましょう。

フィルタの可視化:AIはどんな「模様」に反応するのか?

学習済みのCNNの各層にある「フィルタ(カーネル)」は、特定のパターンに反応するように、その重みが調整されていましたね。このフィルタの重みそのものを画像として表示することで、そのフィルタが「どんな模様を探しているのか」を視覚的に理解することができます。

そして、これを層ごとに見ていくと、非常に面白いことが分かります。

  • 初期の層 (Shallow Layers): ネットワークの入口に近い層のフィルタは、ほとんどの場合、非常にシンプルです。特定方向の線(エッジ)、特定の色のグラデーション、あるいは点々のような模様など、画像の基本的な「部品」を検出するようになっています。
  • 深い層 (Deep Layers): 一方、層が深くなるにつれて、フィルタはより複雑で、意味のあるパターンに反応するようになります。初期の層が検出したエッジや色を組み合わせて、「目の形」「タイヤの模様」「細胞核のテクスチャ」といった、より具体的なオブジェクトのパーツを検出するようになっていくのです。

学習済みフィルタの可視化イメージ

学習済みフィルタの可視化イメージ 初期層のフィルタ(単純な特徴を検出) 斜線 横線 特定の色 (層が進むにつれて) 深い層のフィルタ(複雑な特徴を検出) 目の模様 車輪の模様 複雑な質感

特徴マップの可視化:AIは画像の「どこ」に注目しているのか?

フィルタが「どんな模様を探すか」を見るのに対し、特徴マップの可視化は、「特定の画像が入力されたときに、その模様が画像のどこにあるか」を見るための手法です。ある一枚の画像(例えば、病理組織像)を学習済みのモデルに入力し、途中の層の出力(特徴マップ)を画像として表示してみます。

これは、専門医が画像を見る際に、無意識に特定の領域に注目する、その「視線」を可視化するようなものです。

特徴マップの可視化イメージ

特徴マップの可視化イメージ 入力画像 (病理組織像) CNNの層を通過 特徴マップ (細胞核に反応するフィルタ) 細胞核の領域で 高い値 (活性化) を示す

この特徴マップを見ることで、「なるほど、このモデルは、細胞核の形状や大きさを、良性・悪性の判断における重要な根拠にしているんだな」といった、非常に価値のある洞察が得られるかもしれません。もし、モデルが画像の隅にある無関係なアーチファクトに強く反応していることが分かれば、それはモデルが「カンニング」をしている兆候であり、その信頼性に疑問符が付きます。

こうした可視化を通じて、私たちはAIの「思考プロセス」を少しでも理解し、モデルが正しく学習しているか、あるいは予期せぬバイアスを持っていないかを検証する手がかりを得ることができるのです。このような解釈性の高いAI(Explainable AI, XAI)の技術は、AIが医療現場で安全かつ倫理的に使われるために、今後ますます重要になっていくでしょう。

14.7 & 14.8 医療AI実践:転移学習で「巨人の肩に乗る」

さて、CNNの強力な仕組みを見てきましたが、その性能を最大限に引き出すには、通常、何万、何百万という大量の学習データが必要です。しかし、実際の医療現場ではどうでしょうか?特定の稀な疾患の画像や、アノテーションが完了した質の高いデータを、それほど大量に集めるのは、非常に困難な場合が多いですよね。

この「データは少ない、でも高性能なAIが欲しい」という、医療AI分野における最大のジレンマを解決してくれる、まさに「切り札」とも言える技術が、転移学習(Transfer Learning)です。

転移学習の考え方:AIの「知識」を再利用する

転移学習のアイデアは、非常にシンプルです。

すでに別の巨大なデータセットで賢くなったAIの「眼」(特徴抽出能力)を借りてきて、私たちの専門分野に合わせて、少しだけ調整して使おう

という、非常に賢く、効率的なアプローチです。

ここで重要なのは、ImageNetのような、100万枚以上の多種多様な画像で事前学習されたモデルは、単に「犬」や「猫」を見分ける方法を学んだだけではない、ということです。その学習の過程で、モデルの初期の層は、あらゆる画像に共通する、非常に汎用的な特徴(例えば、エッジ、色のグラデーション、テクスチャなど)を捉える能力を獲得しています。この「モノを見るための基本的な眼」は、自然画像を認識する場合でも、医療画像を認識する場合でも、非常に有用なはずですよね。私たちは、この学習済みの汎用的な知識を、ゼロから学び直す必要はないのです。

ファインチューニング:モデルを「再教育」する具体的なステップ

転移学習の具体的な手法として最も一般的なのが、ファインチューニングです。一般的な画像認識モデルは、大きく分けて二つの部分から構成されています。

  1. 特徴抽出器 (Feature Extractor): モデルの前半部分。画像からエッジ、テクスチャ、パーツといった汎用的な特徴を抽出する役割を担います。
  2. 分類器 (Classifier): モデルの最後の部分。抽出された特徴を元に、最終的なクラス(例:「犬」「猫」)を判定します。

ファインチューニングの戦略は、「優秀な特徴抽出器はそのまま再利用し、最後の分類器だけを、私たちのタスクに合わせて新しいものに交換して、そこだけを重点的に再訓練する」というものです。

転移学習(ファインチューニング)の概念図

転移学習(ファインチューニング)の概念図 1. 事前学習済みモデル (ImageNetなどで学習) 特徴抽出器 (CNNの大部分) (汎用的な眼: エッジ、形、色など) 元の分類器 (1000クラス分類) この部分は「凍結」 この部分は「捨てる」 モデルを再構成 2. ファインチューニング (私たちのタスクで学習) 特徴抽出器 (凍結して再利用) 新しい分類器 (私たちのタスク用) (例: 2クラス分類 – 疾患あり/なし) この部分だけを 「重点的に学習」させる

Pythonコード例:事前学習済みResNetのファインチューニング準備

では、このファインチューニングの準備を、PyTorchのtorchvision.modelsを使って実際にやってみましょう。今回は、医療画像分野でも非常に実績のあるResNet-50というモデルを例にとります。

graph TD
    A["開始"] --> B["1. 事前学習済みモデルを読み込む
(ImageNetで学習済みのResNet-50を利用)"]; B --> C["2. 既存の層の重みを凍結
(学習済みの特徴抽出能力を維持するため、
重みを更新しないよう設定)"]; C --> D["3. 最終層(分類器)を交換
(新しいタスクに合わせて出力層を入れ替える)"]; D --> E["4. 学習対象を確認
(結果、交換した最終層のみが学習される状態になる)"]; E --> F["終了"];

# --- 1. 必要なライブラリをインポート ---
import torch
import torch.nn as nn
import torchvision.models as models

# --- 2. 事前学習済みのResNet-50モデルを読み込む ---
# weights=... で、ImageNetで学習済みの重みを読み込みます。
# これが「巨人の肩に乗る」瞬間です!
print("--- 事前学習済みResNet-50を読み込み中... ---")
model = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)

# --- 3. 多くの層の重みを凍結する ---
# 転移学習では、事前学習で得られた特徴抽出器の能力を活かすため、
# ほとんどの層の重みは更新しない(凍結する)のが一般的です。
# ここでは、全てのパラメータの勾配計算を一旦オフにします。
for param in model.parameters():
    param.requires_grad = False # 勾配計算をオフにすることで、このパラメータは学習されなくなります。

# --- 4. 最終層(分類器)を私たちのタスクに合わせて交換する ---
# ResNet-50の最後の全結合層の名前は 'fc' です。
# 元のモデルの最終層への入力特徴数を取得します (この場合は2048)。
num_ftrs = model.fc.in_features

# 私たちのタスクのクラス数を定義します(例: 疾患あり/なし の2クラス)。
num_classes = 2

# 元の出力層(1000クラス分類)を、私たちのタスク用の
# 新しい線形層に置き換えます。
# 【重要】この新しい層の重みは、デフォルトで requires_grad=True となっており、
# この層だけが、これから学習の対象となります。
model.fc = nn.Linear(num_ftrs, num_classes)

# --- 5. 学習対象のパラメータを確認 ---
print("\n--- 学習対象となるパラメータ ---")
for name, param in model.named_parameters():
    if param.requires_grad:
        print(name)

# === ここから下が上記のprint文による実際の出力の例 ===
# --- 学習対象となるパラメータ ---
# fc.weight
# fc.bias

たったこれだけです!出力を見ると、学習対象が新しく交換した最後の層(fc.weightfc.bias)だけになっているのが分かりますね。これで、ImageNetの膨大な知識を継承しつつ、私たちの医療画像分類タスクに適応する準備が整った、新しいモデルが手に入りました。

このアプローチにより、データが限られがちな医療分野でも、ゼロから学習させるよりも遥かに短時間で、かつ高精度なモデルを構築することが可能になります。実際、皮膚がんの分類(3)や、糖尿病網膜症の診断など、多くの医療AI研究におけるブレークスルーが、この転移学習によって達成されています。

14.9 画像認識のその先へ:物体検出とセグメンテーションへの道 〜「どこに」「どんな形で」まで理解する、AIの高度な視覚〜

さて、ここまで私たちは、画像全体を見て「この画像は、肺炎である」とか「これは猫の写真だ」といったように、一枚の画像に一つのラベルを割り当てる画像分類(Image Classification)タスクに取り組んできました。これは非常に強力なタスクですが、AIの「視覚」の可能性は、これだけにとどまりません。

実際の臨床現場では、「肺炎の疑いがある」だけでなく、「肺炎の影は、画像のどこにあるのか?」、あるいは「腫瘍の正確な輪郭はどうなっているのか?」といった、より詳細な情報が必要になる場面が多いですよね。AIの眼が、私たち人間の専門医の眼に近づくためには、こうした、より高度なタスクをこなす能力が求められます。

画像認識の3つの主要タスク

画像認識の世界には、大きく分けて以下の3つの代表的なタスクがあります。分類からセグメンテーションへと進むにつれて、タスクの難易度と、得られる情報の解像度が上がっていきます。

画像認識の主要タスクの比較

画像認識の主要タスクの比較 1. 画像分類 (Classification) 「猫」 「何があるか?」 2. 物体検出 (Object Detection) 「どこに、何があるか?」 3. セグメンテーション (Segmentation) 「どのピクセルが、何に属するか?」
  1. 画像分類 (Image Classification) – これまで学んだこと 画像全体に対して、一つのカテゴリラベルを割り当てるタスクです。「この胸部X線は、正常か、肺炎か」を判断します。
  2. 物体検出 (Object Detection) – 「位置」と「種類」の特定 画像の中に存在する、特定の物体の「位置」を矩形のバウンディングボックスで囲み、同時にその物体の「種類」を分類するタスクです。例えば、「CT画像の中から、肺結節の位置を四角で囲って示す」といった応用が考えられます。複数のオブジェクトが画像内にあっても、それぞれを検知できます。
  3. セグメンテーション (Segmentation) – 「領域」の精密な塗り分け これは、さらに一歩進んで、画像のピクセル単位で、それがどのクラスに属するかを分類するタスクです。これにより、オブジェクトの正確な形状や輪郭を、塗り絵のように描き出すことができます。例えば、「MRI画像から、腫瘍の領域だけを正確に塗り分ける」ことで、その体積を自動で計測したり、放射線治療の計画に利用したり、といった高度な応用が可能になります。

CNNは全ての基礎となる

では、これらの高度なタスクは、全く新しい技術で実現されているのでしょうか?実は、そうではありません。

物体検出やセグメンテーションを行うモデル(例えば、YOLOU-Netといった有名なモデル)の多くは、その心臓部に、私たちがこれまで学んできたCNNベースの特徴抽出器を組み込んでいます。CNNが画像から抽出した、豊かで階層的な特徴マップを元にして、「どこに物体があるか」「どのピクセルがどのクラスか」といった、より複雑な情報を予測しているのです。

つまり、今回学んだCNNの知識は、これらの発展的なタスクを理解するための、非常に重要な基礎となっている、というわけですね。この講座では、まず画像認識の最も基本的なタスクである「分類」に焦点を当ててきましたが、皆さんが獲得した知識が、さらに広大な画像解析の世界へと繋がっていることを、ぜひ心に留めておいてください。

まとめと次のステップへ

今回は、AIの「眼」を作るCNNの世界を駆け足で巡りました。

  • 画像は数値のテンソルであり、torchvisionで簡単に前処理できること。
  • CNNは畳み込みプーリングで、画像の空間的特徴を効率的に学習すること。
  • 転移学習が、データが限られる医療AI分野で極めて強力な武器であること。

画像という「空間的な」データの世界を探求した次は、また別の種類のデータに目を向けます。心電図の波形や、電子カルテのテキストのように、「時間的な」順序が重要なデータはどう扱えば良いのでしょうか?

次回の第15回では、こうした系列データを専門に扱う再帰型ニューラルネットワーク(RNN)の世界へと旅立ちます。

参考文献

  1. LeCun Y, Bottou L, Bengio Y, Haffner P. Gradient-based learning applied to document recognition. Proc IEEE. 1998;86(11):2278-2324.
  2. Krizhevsky A, Sutskever I, Hinton GE. ImageNet classification with deep convolutional neural networks. In: Advances in neural information processing systems 25. 2012.
  3. Esteva A, Kuprel B, Novoa RA, Ko J, Swetter SM, Blau HM, et al. Dermatologist-level classification of skin cancer with deep neural networks. Nature. 2017;542(7639):115-118.

ご利用規約(免責事項)

当サイト(以下「本サイト」といいます)をご利用になる前に、本ご利用規約(以下「本規約」といいます)をよくお読みください。本サイトを利用された時点で、利用者は本規約の全ての条項に同意したものとみなします。

第1条(目的と情報の性質)

  1. 本サイトは、医療分野におけるAI技術に関する一般的な情報提供および技術的な学習機会の提供を唯一の目的とします。
  2. 本サイトで提供されるすべてのコンテンツ(文章、図表、コード、データセットの紹介等を含みますが、これらに限定されません)は、一般的な学習参考用であり、いかなる場合も医学的な助言、診断、治療、またはこれらに準ずる行為(以下「医行為等」といいます)を提供するものではありません。
  3. 本サイトのコンテンツは、特定の製品、技術、または治療法の有効性、安全性を保証、推奨、または広告・販売促進するものではありません。紹介する技術には研究開発段階のものが含まれており、その臨床応用には、さらなる研究と国内外の規制当局による正式な承認が別途必要です。
  4. 本サイトは、情報提供を目的としたものであり、特定の治療法を推奨するものではありません。健康に関するご懸念やご相談は、必ず専門の医療機関にご相談ください。

第2条(法令等の遵守)
利用者は、本サイトの利用にあたり、医師法、医薬品、医療機器等の品質、有効性及び安全性の確保等に関する法律(薬機法)、個人情報の保護に関する法律、医療法、医療広告ガイドライン、その他関連する国内外の全ての法令、条例、規則、および各省庁・学会等が定める最新のガイドライン等を、自らの責任において遵守するものとします。これらの適用判断についても、利用者が自ら関係各所に確認するものとし、本サイトは一切の責任を負いません。

第3条(医療行為における責任)

  1. 本サイトで紹介するAI技術・手法は、あくまで研究段階の技術的解説であり、実際の臨床現場での診断・治療を代替、補助、または推奨するものでは一切ありません。
  2. 医行為等に関する最終的な判断、決定、およびそれに伴う一切の責任は、必ず法律上その資格を認められた医療専門家(医師、歯科医師等)が負うものとします。AIによる出力を、資格を有する専門家による独立した検証および判断を経ずに利用することを固く禁じます。
  3. 本サイトの情報に基づくいかなる行為によって利用者または第三者に損害が生じた場合も、本サイト運営者は一切の責任を負いません。実際の臨床判断に際しては、必ず担当の医療専門家にご相談ください。本サイトの利用によって、利用者と本サイト運営者の間に、医師と患者の関係、またはその他いかなる専門的な関係も成立するものではありません。

第4条(情報の正確性・完全性・有用性)

  1. 本サイトは、掲載する情報(数値、事例、ソースコード、ライブラリのバージョン等)の正確性、完全性、網羅性、有用性、特定目的への適合性、その他一切の事項について、何ら保証するものではありません。
  2. 掲載情報は執筆時点のものであり、予告なく変更または削除されることがあります。また、技術の進展、ライブラリの更新等により、情報は古くなる可能性があります。利用者は、必ず自身で公式ドキュメント等の最新情報を確認し、自らの責任で情報を利用するものとします。

第5条(AI生成コンテンツに関する注意事項)
本サイトのコンテンツには、AIによる提案を基に作成された部分が含まれる場合がありますが、公開にあたっては人間による監修・編集を経ています。利用者が生成AI等を用いる際は、ハルシネーション(事実に基づかない情報の生成)やバイアスのリスクが内在することを十分に理解し、その出力を鵜呑みにすることなく、必ず専門家による検証を行うものとします。

第6条(知的財産権)

  1. 本サイトを構成するすべてのコンテンツに関する著作権、商標権、その他一切の知的財産権は、本サイト運営者または正当な権利を有する第三者に帰属します。
  2. 本サイトのコンテンツを引用、転載、複製、改変、その他の二次利用を行う場合は、著作権法その他関連法規を遵守し、必ず出典を明記するとともに、権利者の許諾を得るなど、適切な手続きを自らの責任で行うものとします。

第7条(プライバシー・倫理)
本サイトで紹介または言及されるデータセット等を利用する場合、利用者は当該データセットに付随するライセンス条件および研究倫理指針を厳格に遵守し、個人情報の匿名化や同意取得の確認など、適用される法規制に基づき必要とされるすべての措置を、自らの責任において講じるものとします。

第8条(利用環境)
本サイトで紹介するソースコードやライブラリは、執筆時点で特定のバージョンおよび実行環境(OS、ハードウェア、依存パッケージ等)を前提としています。利用者の環境における動作を保証するものではなく、互換性の問題等に起因するいかなる不利益・損害についても、本サイト運営者は責任を負いません。

第9条(免責事項)

  1. 本サイト運営者は、利用者が本サイトを利用したこと、または利用できなかったことによって生じる一切の損害(直接損害、間接損害、付随的損害、特別損害、懲罰的損害、逸失利益、データの消失、プログラムの毀損等を含みますが、これらに限定されません)について、その原因の如何を問わず、一切の法的責任を負わないものとします。
  2. 本サイトの利用は、学習および研究目的に限定されるものとし、それ以外の目的での利用はご遠慮ください。
  3. 本サイトの利用に関連して、利用者と第三者との間で紛争が生じた場合、利用者は自らの費用と責任においてこれを解決するものとし、本サイト運営者に一切の迷惑または損害を与えないものとします。
  4. 本サイト運営者は、いつでも予告なく本サイトの運営を中断、中止、または内容を変更できるものとし、これによって利用者に生じたいかなる損害についても責任を負いません。

第10条(規約の変更)
本サイト運営者は、必要と判断した場合、利用者の承諾を得ることなく、いつでも本規約を変更することができます。変更後の規約は、本サイト上に掲載された時点で効力を生じるものとし、利用者は変更後の規約に拘束されるものとします。

第11条(準拠法および合意管轄)
本規約の解釈にあたっては、日本法を準拠法とします。本サイトの利用および本規約に関連して生じる一切の紛争については、東京地方裁判所を第一審の専属的合意管轄裁判所とします。


For J³, may joy follow you.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

医師・医学博士・AI研究者・連続起業家
元厚生労働省幹部・ハーバード大学理学修士・ケンブリッジ大学MBA・コロンビア大学行政修士(経済)
岡山大学医学部卒業後、内科・地域医療に従事。厚生労働省で複数室長(医療情報・救急災害・国際展開等)を歴任し、内閣官房・内閣府・文部科学省でも医療政策に携わる。
退官後は、日本大手IT企業や英国VCで新規事業開発・投資を担当し、複数の医療スタートアップを創業。現在は医療AI・デジタル医療機器の開発に取り組むとともに、東京都港区で内科クリニックを開業。
複数大学で教授として教育・研究活動に従事し、医療関係者向け医療AIラボ「Medical AI Nexus」、医療メディア「The Health Choice | 健康の選択」を主宰。
ケンブリッジ大学Associate・社会医学系指導医・専門医・The Royal Society of Medicine Fellow

目次