プログラミングでは、データ(材料)とそれを扱う処理(道具)が別々だと管理が大変です。オブジェクト指向では、データと処理を「クラス」という設計図でひとまとめにし、そこから「インスタンス」という具体的なモノを作ります。この考え方は、AIモデル構築の基礎となる重要な概念です。
モノを作るためのテンプレート。「患者カルテ」の設計図のように、どんなデータ(属性)を持ち、どんな機能(メソッド)を持つかを定義します。これ自体は具体的なモノではありません。
クラスという設計図に基づいて作られた、具体的なオブジェクト。田中さん、鈴木さんなど、それぞれが独立したデータを持つ実体です。一つの設計図から多数作成できます。
PyTorchでは、AIモデル自体をクラスとして設計します。モデルの構造(層の定義)やデータの流れをクラスのメソッドとして記述するため、クラスの理解がAI開発に直結します。
はじめに:データと処理を「ひとまとめ」にする新発想
皆さん、こんにちは。前回の講義では、関数という「便利な道具箱」を手に入れ、BMI計算のような定型的な処理を、いつでもどこでも呼び出せるようになりました。プログラムのコードが、再利用可能な「部品」として整理されていく感覚、少し掴めてきたのではないでしょうか?
しかし、私たちの「作業場」をよく見てみると、少しだけ不自然な点があります。それは、「患者さんのデータ(材料)」と、そのデータを扱う「BMIを計算する道具箱(関数)」が、まだ別々の場所に置かれていることです。
BMIを計算したいときは、わざわざ「田中さんの体重と身長」という材料を探し出してきて、「calculate_bmi」という道具箱に、毎回手作業で入れてあげる必要がありました。これは少し面倒ですし、もし材料の種類が増えたら、間違った材料を入れてしまうかもしれません。もっと直感的に、「この患者さん、あなた自身のBMIを計算してください」と、データのかたまりそのものにお願いできたら、コードはよりスッキリし、私たちの思考にも自然にフィットしそうだと思いませんか?
ここで、プログラミングの世界観をガラッと変える、新しい考え方を導入してみましょう。それは、「材料と、その材料専用の道具一式を、初めから一つの完璧なセットにしてしまおう」という発想です。
このように、「モノ(オブジェクト)」を中心として、データ(属性)とそのモノに関連する処理(機能)をひとまとめにしたカプセルのようなものを考える。この設計思想こそが、現代の多くのプログラミング言語で採用されているオブジェクト指向プログラミング (Object-Oriented Programming, OOP) なんです。そして、この素晴らしいカプセル(オブジェクト)を作るための「設計図」となるのが、今回学ぶクラス (Class) なのです。
このクラスという考え方をマスターすることは、実はこの講座の最終的なゴールの一つである、PyTorchでAIモデルを自由に構築するための、絶対に避けては通れない道です。なぜなら、PyTorchにおけるAIモデルは、まさにこのクラスという設計図を使って作られているからです。この講義で、AIモデルの構造を理解するための「鍵」を手に入れましょう!
1. オブジェクト指向とは? 〜「モノ」で世界を捉える考え方〜
オブジェクト指向という言葉は、なんだか難しそうに聞こえるかもしれませんが、その根本にある考え方は非常に自然です。それは、私たちの現実世界が、様々な「モノ(オブジェクト)」で構成されているのと同じように、プログラムの世界も「モノ」の集まりとして捉えよう、というものです。
例えば、医療の世界には、「患者」「医師」「薬剤」「検査機器」といった、様々な「モノ」が存在しますよね。そして、それぞれの「モノ」は、固有のデータ(属性)と、それに伴う振る舞い(機能)を持っています。
- 患者オブジェクト:
- データ(属性): 名前、年齢、性別、病歴、アレルギー情報…
- 振る舞い(機能): 症状を訴える、薬を服用する、検査を受ける…
- 薬剤オブジェクト:
- データ(属性): 名称、成分、用量、副作用情報…
- 振る舞い(機能): 特定の受容体に結合する、血中濃度が変化する…
オブジェクト指向プログラミングは、このようにデータと機能をひとまとめにした「モノ(オブジェクト)」を単位として、プログラムを組み立てていく手法なのです。
1.1 クラスとインスタンス 〜「設計図」と「実体」〜
オブジェクト指向を理解する上で、最も重要で、そして最初に掴むべきなのがクラスとインスタンスの違いです。
- クラス (Class): オブジェクトを作るための「設計図」や「テンプレート」です。
- 例えるなら…: 「患者カルテ」の、まだ何も書き込まれていない空のテンプレート用紙そのものがクラスです。「氏名:__」「年齢:__」といった項目だけが印刷されています。クラスは、あくまで設計図なので、それ自体は具体的な一人の患者さんではありません。
- インスタンス (Instance): その設計図(クラス)に基づいて作られた、具体的な「実体」です。オブジェクトとも呼ばれます。
- 例えるなら…: そのテンプレート用紙に、「氏名:田中 太郎」「年齢:65」と具体的に書き込んだものが、田中さんという一人の患者さんを表すインスタンスです。一枚の設計図(クラス)から、田中さんのカルテ、鈴木さんのカルテ…と、何人分もの具体的なインスタンス(オブジェクト)を作ることができます。
クラスとインスタンスの関係図
解説:
- 一つの「Patient」クラス(設計図)から、p1とp2という、
それぞれ異なるデータを持つ、独立した「インスタンス」が作られています。
- ただし、どちらのインスタンスも、同じ設計図から作られているので、
display_summary()という共通の機能(メソッド)を持っています。
2. Pythonでクラスを作ってみよう 〜患者カルテクラスの設計〜
では、この「クラス」と「インスタンス」の考え方を、Pythonコードで実際に形にしてみましょう。
2.1 クラスの基本構造
Pythonでは、class キーワードを使ってクラスを定義します。
class クラス名:
# 初期化メソッド (コンストラクタ)
def __init__(self, 引数1, 引数2, ...):
# ここで、インスタンスが持つデータ(属性)を初期設定します
self.属性名1 = 引数1
self.属性名2 = 引数2
# その他のメソッド (インスタンスの機能)
def メソッド名1(self, ...):
# このメソッドが行う処理
...
2.1 クラスの基本構造を解剖する
では、先ほどのPythonコード例で登場した、クラスの基本的な構造を一つ一つ解剖して、その役割をじっくり見ていきましょう。ここを理解することが、オブジェクト指向を使いこなすための第一歩です。
__init__(self, ...) メソッド:インスタンスが「生まれる」瞬間の儀式
これはコンストラクタ (Constructor) とも呼ばれる、非常に特殊で重要なメソッドです。例えるなら、「新しいカルテ用紙に、患者さんの基本情報を最初に書き込む作業」ですね。Patient("田中 太郎", 65) のように、クラスから新しいインスタンスが作られる、まさにその瞬間に、Pythonが自動的にこの__init__メソッドを呼び出します。だから「初期化メソッド」や「コンストラクタ(建設者)」なんて呼ばれたりもするんですね。
主な役割は、インスタンスが「生まれる」ときに、そのインスタンスが最低限持っておくべきデータ(属性)を引数として受け取り、インスタンス内部にセットすることです。
self: 「私自身」を指す、魔法の言葉
さて、ここで多くの初学者が「?」となるのが、__init__や他のメソッドの最初の引数に、必ずと言っていいほど登場するselfの存在だと思います。これは一体何者なのでしょうか?
selfは、一言でいうと「インスタンス自身」を指す、特別な予約語です。先ほどの例で言えば、
- 田中さんのカルテ(インスタンス)の
__init__が呼ばれているとき、selfは「田中さんのカルテそのもの」を指しています。 - 鈴木さんのカルテが作られているときは、
selfは「鈴木さんのカルテそのもの」を指します。
なぜこれが必要かというと、メソッドが「どのインスタンスのデータを扱えばいいのか」を区別するためです。self.name = name というコードは、
「私自身(self)の name という名前のデータ入れ(属性)に、引数で受け取った name の値をしまってください」
という意味になります。このselfがあるおかげで、p1とp2が、それぞれ自分の名前や年齢を混同せずにきちんと管理できるわけですね。
属性 (Attribute):「モノ」が持つデータ
属性とは、self.name や self.age のように、インスタンスが保持するデータ(変数)のことです。カルテに書き込まれた「氏名」や「年齢」の項目そのものだと思ってください。
クラスという設計図に「nameという属性を持つ」と書いておくことで、その設計図から作られる全てのインスタンスが、自分専用のnameを格納する場所を持つことになります。
メソッド (Method):「モノ」ができること(機能)
メソッドとは、クラスの中に定義された関数のことです。そのクラスから作られたインスタンスだけが使える、特別な機能と言えます。
メソッドが必ずselfを最初の引数に取るのは、「どのインスタンスの属性を使って処理を行うか」を明確にするためです。display_summary(self) というメソッドは、self.nameやself.ageといった、自分自身のデータを使ってサマリーを表示するからこそ、意味があるわけですね。
Pythonコード例:Patientクラスの定義
それでは、患者さんの情報を保持し、簡単なサマリーを表示する機能を持つPatientクラスを定義してみましょう。
graph TD
subgraph "1. クラスの定義 (設計図)"
A["class Patient
- __init__()
- display_summary()
- add_record()"]
end
A --> B(2. インスタンスを作成)
subgraph "p1 の操作 (田中さん)"
B --> C1("p1 = Patient(...)")
C1 --> D1("p1.add_record() を呼ぶ")
D1 --> E1("p1.display_summary() を呼ぶ")
E1 --> F1("== 結果 ==>
記録: 2件")
end
subgraph "p2 の操作 (鈴木さん)"
B --> C2("p2 = Patient(...)")
C2 --> E2("p2.display_summary() を呼ぶ")
E2 --> F2("== 結果 ==>
記録: 0件")
end
# --- 1. Patientクラス(設計図)を定義する ---
# classキーワードを使って、Patientという名前のクラスを作り始めます。
class Patient:
# (A) __init__メソッド: インスタンスが作られる時の初期設定
# name, age, recordsという3つのデータを引数として受け取ります。
def __init__(self, name, age, records):
"""
Patientオブジェクトが作成される際に呼び出され、初期化を行います。
"""
print(f"(INFO: {name}さんのカルテ(インスタンス)を作成します... __init__が呼ばれました)")
# 受け取った引数を、selfを使ってインスタンス自身の属性として保存します。
self.name = name # 名前を保存
self.age = age # 年齢を保存
self.records = records # 診療記録をリストとして保存
# (B) display_summaryメソッド: このクラスが持つ機能(メソッド)
# selfを引数に取ることで、インスタンス自身の属性(self.nameなど)にアクセスできます。
def display_summary(self):
"""患者さんのサマリー情報を表示するメソッド。"""
print("\n--- 患者サマリー ---")
print(f" 氏名: {self.name}")
print(f" 年齢: {self.age} 歳")
print(f" 記録件数: {len(self.records)} 件") # len()で記録リストの長さを取得
print("--------------------")
# (C) add_recordメソッド: 診療記録を追加する機能
def add_record(self, new_record):
"""新しい診療記録をリストに追加するメソッド。"""
self.records.append(new_record)
print(f"(INFO: {self.name}さんのカルテに新しい記録「{new_record}」が追加されました)")
# --- 2. クラスからインスタンス(実体)を作成し、使ってみる ---
print("--- 患者インスタンスの作成と利用 ---")
# Patientクラス(設計図)から、p1という名前の具体的なインスタンス(田中さんのカルテ)を作成します。
# この瞬間に、__init__メソッドが自動的に呼ばれます。
p1 = Patient(name="田中 太郎", age=65, records=["2025-01-10: 定期健診"])
# もう一人、別のインスタンス(鈴木さんのカルテ)も作ってみましょう。
# p1とp2は、同じ設計図から作られていますが、それぞれ独立した別のオブジェクトです。
p2 = Patient(name="鈴木 花子", age=52, records=[])
# --- 3. インスタンスのメソッドを呼び出してみる ---
# p1のadd_recordメソッドを呼び出して、新しい記録を追加します。
p1.add_record("2025-06-06: 風邪で受診")
# p1のdisplay_summaryメソッドを呼び出して、サマリーを表示します。
p1.display_summary()
# p2のdisplay_summaryメソッドも呼び出してみましょう。
# p2はp1とは別のデータを持っていることがわかります。
p2.display_summary()
# === ここから下が上記のprint文による実際の出力 ===
# --- 患者インスタンスの作成と利用 ---
# (INFO: 田中 太郎さんのカルテ(インスタンス)を作成します... __init__が呼ばれました)
# (INFO: 鈴木 花子さんのカルテ(インスタンス)を作成します... __init__が呼ばれました)
# (INFO: 田中 太郎さんのカルテに新しい記録「2025-06-06: 風邪で受診」が追加されました)
#
# --- 患者サマリー ---
# 氏名: 田中 太郎
# 年齢: 65 歳
# 記録件数: 2 件
# --------------------
#
# --- 患者サマリー ---
# 氏名: 鈴木 花子
# 年齢: 52 歳
# 記録件数: 0 件
# --------------------
3. なぜ医療AI開発でクラスが重要なのか?
「なるほど、データと処理をまとめられるのは便利そうだけど、これがなぜAI開発に欠かせないの?」と思われたかもしれませんね。その答えは、私たちがこれから使うPyTorchというライブラリの設計思想にあります。
実は、私たちがこの後PyTorchでAIモデルを構築する際、必ずこの「クラス」を使います。PyTorchのすべてのニューラルネットワークモデルは、torch.nn.Moduleという、PyTorchが予め用意してくれている親クラスを「継承」して作られる、私たちだけのカスタムクラスなんです。
PyTorchにおけるモデル構築のイメージ
PyTorchが提供するnn.Moduleは、AIモデルを作るための非常に高機能な「設計図のテンプレート」のようなものです。そのテンプレートには、モデルの学習に必要な様々な機能(パラメータの管理、勾配計算の仕組みなど)が既に組み込まれています。
私たちは、そのテンプレートを元にして、__init__で自分たちのモデルで使いたい層(線形層や畳み込み層といった部品)を定義し、forwardメソッド(データがモデル内をどう流れていくかを記述する、これまた特殊なメソッドです)を定義することで、パワフルな自分だけのAIモデルを簡単に完成させることができる、というわけです。
4. まとめと次のステップ
今回は、データ(属性)と処理(メソッド)をひとまとめにするオブジェクト指向の考え方と、その設計図となるクラス、そして具体的な実体であるインスタンスについて学びました。
この「モノ」としてデータを捉える考え方は、複雑なシステムを整理し、管理しやすくするための非常に強力なパラダイムです。特に、PyTorchでAIモデルを扱う上で、このクラスの概念は避けては通れません。
これで、Pythonの基本的な文法からデータ構造、関数、そしてクラスまで、AIモデルを構築するための基礎知識が一通り揃いました。まさに、料理で言えば、調理器具も揃い、食材の扱い方もマスターした状態です。
いよいよ次からは、これまでの知識を総動員して、PyTorchという本格的な「厨房」に入り、ディープラーニングの部品を一つ一つ学びながら、AIモデルの構築を始めていきます。最初のテーマは、PyTorchの最も基本的なデータ単位である「テンソル」です。お楽しみに!
参考文献
- Lutz M. Learning Python. 5th ed. Sebastopol, CA: O’Reilly Media; 2013. Part VI, Classes and OOP.
- Weert P, De Meuter W. The `self`-less object-oriented programming style. In: Proceedings of the 23rd European conference on object-oriented programming. 2009. p. 454-478.
- PyTorch Documentation. nn.Module. [Internet]. [cited 2025 Jun 6]. Available from: https://pytorch.org/docs/stable/generated/torch.nn.Module.html
ご利用規約(免責事項)
当サイト(以下「本サイト」といいます)をご利用になる前に、本ご利用規約(以下「本規約」といいます)をよくお読みください。本サイトを利用された時点で、利用者は本規約の全ての条項に同意したものとみなします。
第1条(目的と情報の性質)
- 本サイトは、医療分野におけるAI技術に関する一般的な情報提供および技術的な学習機会の提供を唯一の目的とします。
- 本サイトで提供されるすべてのコンテンツ(文章、図表、コード、データセットの紹介等を含みますが、これらに限定されません)は、一般的な学習参考用であり、いかなる場合も医学的な助言、診断、治療、またはこれらに準ずる行為(以下「医行為等」といいます)を提供するものではありません。
- 本サイトのコンテンツは、特定の製品、技術、または治療法の有効性、安全性を保証、推奨、または広告・販売促進するものではありません。紹介する技術には研究開発段階のものが含まれており、その臨床応用には、さらなる研究と国内外の規制当局による正式な承認が別途必要です。
- 本サイトは、情報提供を目的としたものであり、特定の治療法を推奨するものではありません。健康に関するご懸念やご相談は、必ず専門の医療機関にご相談ください。
第2条(法令等の遵守)
利用者は、本サイトの利用にあたり、医師法、医薬品、医療機器等の品質、有効性及び安全性の確保等に関する法律(薬機法)、個人情報の保護に関する法律、医療法、医療広告ガイドライン、その他関連する国内外の全ての法令、条例、規則、および各省庁・学会等が定める最新のガイドライン等を、自らの責任において遵守するものとします。これらの適用判断についても、利用者が自ら関係各所に確認するものとし、本サイトは一切の責任を負いません。
第3条(医療行為における責任)
- 本サイトで紹介するAI技術・手法は、あくまで研究段階の技術的解説であり、実際の臨床現場での診断・治療を代替、補助、または推奨するものでは一切ありません。
- 医行為等に関する最終的な判断、決定、およびそれに伴う一切の責任は、必ず法律上その資格を認められた医療専門家(医師、歯科医師等)が負うものとします。AIによる出力を、資格を有する専門家による独立した検証および判断を経ずに利用することを固く禁じます。
- 本サイトの情報に基づくいかなる行為によって利用者または第三者に損害が生じた場合も、本サイト運営者は一切の責任を負いません。実際の臨床判断に際しては、必ず担当の医療専門家にご相談ください。本サイトの利用によって、利用者と本サイト運営者の間に、医師と患者の関係、またはその他いかなる専門的な関係も成立するものではありません。
第4条(情報の正確性・完全性・有用性)
- 本サイトは、掲載する情報(数値、事例、ソースコード、ライブラリのバージョン等)の正確性、完全性、網羅性、有用性、特定目的への適合性、その他一切の事項について、何ら保証するものではありません。
- 掲載情報は執筆時点のものであり、予告なく変更または削除されることがあります。また、技術の進展、ライブラリの更新等により、情報は古くなる可能性があります。利用者は、必ず自身で公式ドキュメント等の最新情報を確認し、自らの責任で情報を利用するものとします。
第5条(AI生成コンテンツに関する注意事項)
本サイトのコンテンツには、AIによる提案を基に作成された部分が含まれる場合がありますが、公開にあたっては人間による監修・編集を経ています。利用者が生成AI等を用いる際は、ハルシネーション(事実に基づかない情報の生成)やバイアスのリスクが内在することを十分に理解し、その出力を鵜呑みにすることなく、必ず専門家による検証を行うものとします。
第6条(知的財産権)
- 本サイトを構成するすべてのコンテンツに関する著作権、商標権、その他一切の知的財産権は、本サイト運営者または正当な権利を有する第三者に帰属します。
- 本サイトのコンテンツを引用、転載、複製、改変、その他の二次利用を行う場合は、著作権法その他関連法規を遵守し、必ず出典を明記するとともに、権利者の許諾を得るなど、適切な手続きを自らの責任で行うものとします。
第7条(プライバシー・倫理)
本サイトで紹介または言及されるデータセット等を利用する場合、利用者は当該データセットに付随するライセンス条件および研究倫理指針を厳格に遵守し、個人情報の匿名化や同意取得の確認など、適用される法規制に基づき必要とされるすべての措置を、自らの責任において講じるものとします。
第8条(利用環境)
本サイトで紹介するソースコードやライブラリは、執筆時点で特定のバージョンおよび実行環境(OS、ハードウェア、依存パッケージ等)を前提としています。利用者の環境における動作を保証するものではなく、互換性の問題等に起因するいかなる不利益・損害についても、本サイト運営者は責任を負いません。
第9条(免責事項)
- 本サイト運営者は、利用者が本サイトを利用したこと、または利用できなかったことによって生じる一切の損害(直接損害、間接損害、付随的損害、特別損害、懲罰的損害、逸失利益、データの消失、プログラムの毀損等を含みますが、これらに限定されません)について、その原因の如何を問わず、一切の法的責任を負わないものとします。
- 本サイトの利用は、学習および研究目的に限定されるものとし、それ以外の目的での利用はご遠慮ください。
- 本サイトの利用に関連して、利用者と第三者との間で紛争が生じた場合、利用者は自らの費用と責任においてこれを解決するものとし、本サイト運営者に一切の迷惑または損害を与えないものとします。
- 本サイト運営者は、いつでも予告なく本サイトの運営を中断、中止、または内容を変更できるものとし、これによって利用者に生じたいかなる損害についても責任を負いません。
第10条(規約の変更)
本サイト運営者は、必要と判断した場合、利用者の承諾を得ることなく、いつでも本規約を変更することができます。変更後の規約は、本サイト上に掲載された時点で効力を生じるものとし、利用者は変更後の規約に拘束されるものとします。
第11条(準拠法および合意管轄)
本規約の解釈にあたっては、日本法を準拠法とします。本サイトの利用および本規約に関連して生じる一切の紛争については、東京地方裁判所を第一審の専属的合意管轄裁判所とします。
For J³, may joy follow you.

