---
title: 研究のための開発スキル
tags: 
author: [Shoma Shimizu](https://image.docswell.com/user/shoma-shimizu)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/G789Z924JD.jpg?width=480
description: 主に機械学習やブラックボックス最適化などの分野の研究に取り組む学生に向けて，研究に役立つ開発スキルをまとめた資料です．
published: November 14, 25
canonical: https://image.docswell.com/s/shoma-shimizu/K13NNR-2025-11-14-151942
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/G789Z924JD.jpg)

研究のための開発スキル
横浜国立大学総合学術高等研究院
白川研究室 IMS客員助教
清水彰馬
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/L7LWDW2VER.jpg)

前置き
◆この資料は横浜国立大学白川研究室の学生向けに
2025年10月末時点での情報をもとに作成された資料に
一部修正を加えたものです
◆想定している読者
• 授業等を通してプログラミングの基礎や Python の基本的な文法を理解している
• 機械学習やブラックボックス最適化の研究をしている学生
• 他の分野でも情報系かコンピュータを使った実験を伴う分野であれば参考になるかも
◆この資料では扱わなかった内容
• モデルのデプロイや運用に関する内容
• Docker や Kubernetes などコンテナに関する内容
• 機械学習やブラックボックス最適化そのものに関する内容
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4EM9P98N7W.jpg)

Outline
◆資料について
◆プロジェクト管理
◆コーディング技法
◆MLOps
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/PERG1G5479.jpg)

資料について
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/P7XXYXKZ7X.jpg)

研究における開発スキルの意義
開発スキルは研究の価値を高めるために役立つ！
再現性
実験結果の再現性を高め実装公開や引き継ぎをスムーズに進める
信頼性
実装や実験設定の誤りを排し信頼に足る実験結果を得る
生産性
作業を効率的に進めて少しでも研究成果を増やす
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/37KW3W5V7D.jpg)

再現性
再現に必要なコードや実行環境を適切に管理
• ソースコードを実行可能な状態で保持
• 実験結果を得たときと同じ実行環境を簡単に用意できるようにする
実験設定の管理と再現手順の明確化
• 必要な実験設定を網羅して分かりやすいかたちで保持
• 明快な手順で誰でも同じ結果が得られるようにする
実験に関わる記録を残して論文化していない部分も再現可能に
• 予備実験の結果や考察を確認できるようにしておく
• 手法や実験設定の考案に関する議論を残しておく
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/LJ31G11QE5.jpg)

信頼性
実装を公開して実験結果の正当性の根拠を増やす
• 他人にも理解しやすい整理されたコードを書く
• 実験に関わるソースコード以外のファイルも適切に管理
バグを潰して正しい実験結果を得る
• 様々なツールを駆使して早期にバグを検出
• バグが生じにくい方法でのコーディング
方針の誤りなどを早期に発見できる土壌を作る
• 実験や問題の設定を適切に管理していつでも議論できるようにしておく
• 細部まで把握しやすいように実装する
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/8JDX1XXW7G.jpg)

生産性
タスクを整理したり並行して進めることで効率アップ
• 忘れないようにタスクをリスト化
• ツールを駆使して複数のタスクをスムーズに進める
手作業になっている煩雑なタスクを自動化・効率化
• 実験設定やログの管理を効率的に行う
• プログラムの動作確認を自動で行う
整理されたコードで素早く実験を行う
• バグを早期に取り尽くして素早く本番の実験に辿り着く
• 拡張性の高いコードで実験設定の変更に素早く対応
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/VEPPQPPXE8.jpg)

実装の公開について
◆主要な国際会議では実装の公開が推奨されていることが多い
• 実装が公開されていないと再現性や信頼性が低くなるため
論文のインパクトを大きくしたいなら公開した方が良い
• 実装の公開を推奨している国際会議や論文誌の例
• NeurIPS, ICLR, TMLR, GECCO
• 査読時の評価項目に含まれている場合もある
• ICML 2025 Author Instructions:
Authors are encouraged to submit code to foster reproducibility. Reproducibility of results and
easy availability of code will be taken into account in the decision-making process.
◆公開するつもりで普段から実装していればクオリティも上がるかも
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/27V252237Q.jpg)

資料の意図
研究作業を進める上での引き出しを作る・選択肢を増やす
◆具体的なツールの名前や使い方よりはそれぞれの概念の概要を理解する
• その上で現時点で有力と考えているツールの軽い紹介もする
◆必要なときに必要なツールを選べるようになる
• ツールには流行り廃りがあり新しいものもどんどん出てくる
• ツールの必要性・有用性を認識しツール選びの取っ掛かりにする
◆開発スキルについて普段から意識できるようになる
• スキルは急には身に付かないしいきなり完璧には使えない
• 今後使ってみたり試してみたりして少しずつ身に付けていってほしい
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/5JGR6RRY7L.jpg)

プロジェクト管理
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/47QV4VV6EP.jpg)

プロジェクト管理
◆ソースコード管理
• 再現に必要なコードの保持
• 複数プロジェクトの同時進行
• 複数マシンでの作業
[1] https://github.com/pallets/flask
◆タスク管理
• 議論の可視化
• 引き継ぎや共有に便利
• 作業効率アップ
[2] https://github.com/pallets/flask/issues
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/KE4MQMMM71.jpg)

ソースコード管理
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/L718P88YJG.jpg)

ソースコードの管理
バージョン管理
• ソースコードの変更履歴の管理
• 複数人・複数マシンでの編集時に
発生する競合の解決
パッケージ管理
• 依存ライブラリの管理
• 仮想環境や Python のバージョンも
管理できるものも存在
[3] https://www.atlassian.com/ja/git/tutorials/comparing-workflows/gitflow-workflow
[4] https://docs.astral.sh/uv/concepts/projects/dependencies/#project-dependencies
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/G7WZ2ZZ172.jpg)

ソースコードの管理
バージョン管理
• ソースコードの変更履歴の管理
• 複数人・複数マシンでの編集時に
発生する競合の解決
パッケージ管理
• 依存ライブラリの管理
• 仮想環境や Python のバージョンも
管理できるものも存在
[3] https://www.atlassian.com/ja/git/tutorials/comparing-workflows/gitflow-workflow
[4] https://docs.astral.sh/uv/concepts/projects/dependencies/#project-dependencies
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/4JZ1D11XE3.jpg)

バージョン管理システム (VCS)
変更履歴の管理
変更履歴を保持することで
様々な機能を提供
• 変更内容の確認
• 過去の状態の復元
AAAA
XXXX
CCCC
DDDD
AAAA
BBBB
CCCC
DDDD
2行目を更新
4行目を削除
複数人での並行作業
複数人・複数マシンでの同時並行
作業を可能にするとともに
それらの変更を矛盾なくマージ
Git, Subversion, Perforce, etc.
AAAA
XXXX
CCCC
DDDD
変更を統合
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/YE6L1LLP7V.jpg)

研究におけるバージョン管理の意義
◆実装時・研究室内
• 複数のマシンでの作業
• 複数プロジェクトの
同時進行
• 実験結果とソースコードの
バージョンの紐づけ
• 実装箇所の明示
• デバッグ
複数マシンでの作業
複数プロジェクトの同時進行
実験結果とソースコードの
バージョンの紐づけ
実装箇所の明示
◆実装の公開
• 論文に使用した
バージョンの明示
• 公開後メンテナンスする
場合の修正箇所の明示
[5] https://github.com/astralsh/uv/commit/c826f2b042c78af0b58e1a27c43b8
a5603a0f2b3
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/GE51411PJ4.jpg)

Git を用いたバージョン管理
Git: 主要な VCS の一つ
ローカルとリモートで分散して管理
リポジトリ：変更を管理する場所
• リモートリポジトリ：
専用のサーバに配置される
複数人での共有も可能
• ローカルリポジトリ：
個人が手元で作業するための場所
• push: ローカルの変更をリモートに送信
• pull: リモートの変更をローカルに取得
GitHub, GitLab, Bitbucket, Codeberg, etc.
pull
リモートリポジトリ
push
pull
push
ローカル
リポジトリ
ローカル
リポジトリ
commit
commit
コミット：変更を記録する単位
• 前回からの差分が記録される
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/9721V11ZER.jpg)

Git: コミットの流れ
◆ワーキングツリー上で
ファイルを編集
◆編集した内容をインデックスに
登録（ステージする）
◆インデックスに登録されている
内容を変更として確定
インデックスを挟むことで
不要な変更を含めず
適度な量にまとめることが可能
Local
Working Tree
add
Index (Staging Area)
commit
pull
Remote Repository
push
Repository
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/DJYZ3ZZNEM.jpg)

Git: メッセージとコミットの粒度
コミットメッセージ
◆変更内容を説明するメッセージを記入可能
• git commit –m “&lt;message&gt;”
◆メッセージの書き方
• 変更内容が一行で具体的に想像できるようにする
• 例：Semantic Commit Messages
• GitHub 等では issue の番号を記入して関連付けが可能
コミットの粒度
◆一つのコミットは一つの変更に対応させる
• メッセージを書くとき「◯◯の追加と××の修正」など長くなるのは良くない
◆なるべくこまめにコミット
• コミットが小さすぎるのも良くないが大きすぎるよりはマシ
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/V7N3V33V78.jpg)

Git: 不要なファイルの除外
◆Git での管理から除外する方が望ましいファイルもある
• ツールのキャッシュファイルや中間生成物
• バイナリファイルなど差分が確認しにくいもの
• サイズが大きいファイル
• etc.
◆除外方法
• .gitignore ファイルで除外するファイルを指定できる
• Python プロジェクト向けテンプレート
• テンプレートにないもので除外すると良いもの
• データセット
• 実験結果
• ログファイルや可視化のために作成した図
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/YJ99699VJ3.jpg)

Git: ブランチ
progress-report
履歴を分岐させ複数の状態を
同時に保持できる機能
main
使い所の例
• 別の作業を同時に進行するとき
• 進捗報告と実験用コードの実装等
experiment
• 動く状態のコードを保持したまま
追加の実装を進めたいとき
• 複数マシンでの同期等
主なコマンド
git branch : ブランチの一覧を表示
implement
git switch –c &lt;branch&gt; : ブランチを作成 &amp; 切り替え
git switch &lt;branch&gt; : ブランチを切り替え
git branch –d &lt;branch&gt; : ブランチを削除
git merge &lt;branch&gt; : 指定したブランチを現在のブランチに統合
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/GJ89Z994ED.jpg)

Git: その他の主なコマンド
◆git restore &lt;path&gt;
• 変更したファイルを復元
• git restore --staged &lt;path&gt; : 指定したファイルをインデックスから削除
◆git stash
• ワーキングツリー上の変更を一時的に退避
• git stash pop : 退避しておいた変更を再度適用 (LIFO)
• git stash list : 退避された変更の一覧を表示
◆git fetch
• リモートリポジトリの状態を取得
◆git commit --amend
• 最新のコミットを修正する
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/LJLWDWWV7R.jpg)

Git: デバッグに役立つかもしれないコマンド
◆git blame &lt;path&gt;
• 指定したファイルの変更履歴を
行単位で確認できる
• バグが混入したコミットの特定など
• GitHub 上でも使える
◆git bisect
• バグが発生したコミットを
二分探索で特定する
• 問題がある状態 (good) と
問題がない状態 (bad) を
簡単に判定できるときに使える
[6]
https://github.com/pytorch/pytorch/blame/3cfbf98ea9d937d23f3700168b22706c95730
8ce/torch/nn/functional.py
• 自動テストと組み合わせて使うほか
手動でも可能
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/47M9P99NJW.jpg)

ソースコードの管理
バージョン管理
• ソースコードの変更履歴の管理
• 複数人・複数マシンでの編集時に
発生する競合の解決
パッケージ管理
• 依存ライブラリの管理
• 仮想環境や Python のバージョンも
管理できるものも存在
[3] https://www.atlassian.com/ja/git/tutorials/comparing-workflows/gitflow-workflow
[4] https://docs.astral.sh/uv/concepts/projects/dependencies/#project-dependencies
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/P7RG1GG4J9.jpg)

パッケージ管理と仮想環境
パッケージ管理
外部ライブラリのバージョンと依存関係を管理
ライブラリのバージョンが変わると実験結果も変わる
再現性確保に必須
仮想環境
システムから隔離された一時的な実行環境※
個々の仮想環境には異なるバージョンのライブラリが
インストール可能
再現性の向上に貢献する要素
numpy v1.26.0
numpy v2.3.0
torch v2.8.0
optuna v4.5.0
numpy v2.1.0
torch v2.6.0
optuna v4.2.1
• 他のプロジェクトからの適切な分離
• 同じバージョンのライブラリが簡単にインストール可能
※ここでは Python の実行環境のみが対象
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/PJXXYXXZJX.jpg)

uv を用いたパッケージ管理
uv: パッケージ管理 + 仮想環境管理 + Python のバージョン管理
• 他の多くのツールと異なり uv 単体で上記三つの全てが可能
• 他のツールよりも10~100倍高速
◆主なコマンド
• uv init &lt;project_name&gt; : 新規プロジェクトの作成
• uv python install &lt;version&gt; : Python のインストール
• uv python pin &lt;version&gt; : 使用する Python のバージョンを指定
• uv add &lt;package_name&gt; : 依存関係の追加（仮想環境へライブラリをインストール）
• uv remove &lt;package_name&gt; : 依存関係の削除（仮想環境からライブラリをアンインストール）
• uv run &lt;command&gt; : 仮想環境内でコマンドを実行
• uv run python main.py など
• 依存関係はコマンド実行時に必要に応じて自動でインストールされる
• uv sync : 依存関係のインストール
• 通常明示的に実行する必要はない
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/3JKW3WWVJD.jpg)

uv のプロジェクト構造
uv init でプロジェクトの雛形が自動生成される
仮想環境の実体
Python のバージョン指定
プロジェクトのメタ情報
依存関係もここに記載
&lt;project_name&gt;
├── .venv
│ ├── bin
│ ├── lib
│ └── pyvenv.cfg
├── .python-version
├── README.md
├── main.py
├── pyproject.toml
└── uv.lock
依存関係解決後のライブラリのバージョン
プロジェクトの構造には色々なパターンが存在
src/ を挟むか，tests/ をどこに置くかなど
実装を追加
&lt;project_name&gt;
├── .venv
│ ├── bin
│ ├── lib
│ └── pyvenv.cfg
├── &lt;project_name&gt;
│ ├── main.py
│ └── module1.py
├── tests
│ ├── conftest.py
│ └── test_module1.py
├── .python-version
├── README.md
├── pyproject.toml
└── uv.lock
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/LE31G1WQ75.jpg)

パッケージ管理の他の選択肢
◆pip (+ venv + pyenv)
• venv で仮想環境を作り pip でパッケージをインストールするやり方
• pyenv で Python のバージョンを管理できる
◆Poetry (+ pyenv)
• Poetry では仮想環境とパッケージ管理が可能
• Python のバージョン管理は別途 pyenv 等が必要
◆Pixi
• パッケージ管理，仮想環境管理，Python のバージョン管理の全てが可能
• Python 以外の言語のパッケージも扱える
• conda-forge と PyPI の両方に対応
その他：Hatch, pdm, Pipenv, conda など
※ rye は開発停止して uv に移行しました
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/8EDX1XKWJG.jpg)

タスク管理
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/V7PPQPKX78.jpg)

進捗を可視化・記録しよう
進捗の可視化
◆タスクが整理され進行度合いが把握しやすくなる
◆他の人が確認でき議論の促進につながる
◆研究室内のゼミ等で流用できる？
進捗の記録
◆後から見返して思い出せる
◆引き継いだ人が論文等になっていない細かい部分を確認できる
◆上手くいかなかった部分とその理由を残しておける
cf. 実験ノート
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/2JV252V3JQ.jpg)

課題管理システム (ITS)
課題のリストを管理するシステム
◆課題の情報
• タイトル，作成者，作成日時，担当者
• 詳細
• ステータス
◆機能
[7] https://redmine.jp/overview/
• 課題同士の関連付け
• 進捗度合いの可視化
• スケジュールや締切の設定
• 作業の取り組み状況を分析した図表の作成
• カンバン方式でタスク一覧を表示
[8]
https://www.atlassian.com/ja/software/jira/tem
plates/project-management-templates
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/5EGR6RLYJL.jpg)

チケット駆動開発 (TiDD)
開発における全ての作業はチケットを起票してから行われるという開発方式
• チケット：作業項目や課題などを一単位として切り出したもの
◆原則：チケットなしのコミットや作業は不可
• プログラムの変更内容や作業内容が全てチケットとして可視化される
• チケットに議論の履歴が残るためプログラムの変更の意図などが把握しやすい
◆大まかな流れ
• タスクを分割して書き出しチケットとして発行
• （チケットをイテレーション単位にまとめる）
• タスクを選んで取り組む
• 完了したらチケットをクローズ
• 他のタスクに取り組む
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/4JQV4VY67P.jpg)

GitHub の機能を使ったタスク管理
Issue
Milestones
[9] https://github.com/ray-project/ray/issues
[10] https://github.com/ray-project/ray/milestones
Projects
Pull Request
[11] https://github.com/orgs/ray-project/projects/79/views/4
[12] https://github.com/ray-project/ray/pulls
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/K74MQMWMJ1.jpg)

Issue を使ったタスクの整理
Issue をタスクの整理と進捗のメモに使用
タスクの一覧を書き出す
チェックボックスで
細かく作業を分割
概要や関連情報などを
書くのも良い
結果や考察などを
スレッドにメモ
これらの issues はフィクションです
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/LJ18P8YYEG.jpg)

Issue の機能
Labels
属性や状態を
表すタグが
付けられる
Sub-issues
Type
子 issue を
登録して
階層化できる
種類を表す
タグが一つ
付けられる
[13] https://github.com/rust-lang/rust/issues/131425
他にも担当者の割当や Projects, Milestone などの設定も可能
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/GJWZ2ZG1J2.jpg)

Issue のテンプレート
markdown または yaml で作成したファイルをリポジトリの
/.github/ISSUE_TEMPLATE/ 以下に置くとテンプレートとして使用可能
[15] https://github.com/pytorch/pytorch/issues
[14] https://github.com/pytorch/
pytorch/tree/main/.github/ISSU
E_TEMPLATE
[15] https://github.com/pytorch/pytorch/issues
issue を新規作成する際に
テンプレート選択画面が表示される
yaml ではフォームが作れる
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/4EZ1D1LX73.jpg)

Milestone を使ったタスクの分類と追跡
複数の issues をまとめて中間目標として分類
Milestone ごとに説明や期限を追加可能
[16] https://github.com/pytorch/pytorch/milestones
Milestone の一覧
各 Milestone の進捗状況が表示される
[17] https://github.com/pytorch/pytorch/milestone/55
Milestone の説明と issue 一覧
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/Y76L1LWPJV.jpg)

Projects を使ったタスクの一覧表示
Issue をプロジェクトに登録すると
タスクの計画や進捗追跡に使える様々な機能を使用できる
[17] https://github.com/orgs/rust-lang/projects/59/views/1
◆カンバン方式
• タスクを進捗状況などに応じて
分類して一覧表示できる
• issue のステータスと連動可能
[18] https://github.com/orgs/wagtail/projects/16/views/4
◆ロードマップ
• タスクの開始時期と締め切りを
設定してガントチャートのように
表示できる
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/G75141MPE4.jpg)

Pull Request と Issue の紐付け
本文に Issue の番号を入れるとメンションできる
[20] https://github.com/Farama-Foundation/Gymnasium/issues/1417
メンションされた Issue にはメンション元が表示される
[19] https://github.com/Farama-Foundation/Gymnasium/pull/1419
[19] https://github.com/FaramaFoundation/Gymnasium/pull/1419
Development 欄で連動させることも可能
（マージすると自動的に Issue も閉じる）
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/9J21V19Z7R.jpg)

ブランチの切り方
ブランチの運用には様々な方法があるが
とりあえず取っ付きやすいやり方から始める
◆プロジェクトごとに切る
• 研究テーマ A ，研究テーマ B ，進捗報告など都度ブランチを分ける
• コードの実装など作業をする際にそこから更にブランチを切って
作業中のブランチと動く状態のブランチを分ける
◆Issue と紐付ける
• Issue に対応したブランチを都度作成する
• Issue の作業が完了したらマージしてブランチを削除
◆慣れてきたら有名なブランチ戦略を試してみる
• GitHub Flow など
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/DEYZ3Z4N7M.jpg)

（参考）Pull Request を使ったレビュー
GitHub 上でブランチをマージするための機能
マージする前にコードのレビューやテストなどができる
[21] https://github.com/Genesis-Embodied-AI/Genesis/pull/1812
コードにコメントを付けたり
改善の提案をしたりできる
[21] https://github.com/Genesis-Embodied-AI/Genesis/pull/1812
コミットの度に自動でテスト等を
実行できる
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/VJN3V3YVJ8.jpg)

詳しく知りたい
◆git
• Pro Git book
• サル先生の Git 入門
◆GitHub
• Issues のドキュメント
◆ブランチ戦略の紹介記事
◆Python のプロジェクト構造
43


# Page. 44

![Page Image](https://bcdn.docswell.com/page/YE9969PVE3.jpg)

コーディング技法
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/GE89Z9D47D.jpg)

コーディング技法
◆可読性と静的解析
• 読みやすいコードを書き，実行前にコードの問題を検出する
◆設計技法
• 拡張性の高いコードで効率的に研究を進める
◆デバッグとパフォーマンスの向上
• 素早く本番の実験に辿り着きより多くの実験を回す
45


# Page. 46

![Page Image](https://bcdn.docswell.com/page/LELWDWMVJR.jpg)

可読性と静的解析
46


# Page. 47

![Page Image](https://bcdn.docswell.com/page/4JM9P9YNEW.jpg)

なぜ可読性が重要か
研究の再現性や信頼性の向上に繋がる
◆実装公開
• コードが読みやすければ再現実験の助けになる
• 自分の提案手法を他の人に取り入れてもらいやすくなるかも
◆研究室内での共有
• 自分や研究室メンバーにも読みやすくなりバグが見つけやすくなる
• 引き継ぐ人の苦労が減る
47


# Page. 48

![Page Image](https://bcdn.docswell.com/page/PJRG1G94E9.jpg)

コーディング規約
ソースコードの書き方を統一するガイドライン
可読性や保守性を高める目的で制定される
Python におけるコーディング規約
◆PEP8
• Python が公式に定めているコーディング規約
• インデントの文字数や変数・関数・クラスの命名規則など
◆Google Python Style Guide
• Google が定めているコーディング規約
• PEP8 との重複も多い
• Linter の使用や型ヒントの明記を推奨
48


# Page. 49

![Page Image](https://bcdn.docswell.com/page/PEXXYXQZEX.jpg)

可読性向上に役立つツール
コーディング規約に準拠できているか手動で確認するのは大変
自動で整形や解析をしてくれるツールを使う
Formatter
• コード内の改行やスペースなどを自動で整形するツール
• Ruff, Black, autopep8 など
Linter
• コードを実行前に解析し様々な問題を指摘するツール
• コーディングスタイルの問題だけでなく構文エラーやバグも検出可能
• Ruff, Flake8, pycodestyle など
静的型チェッカー
• 型ヒントをもとに変数や関数の型が正しいか検査するツール
• Pyright, mypy, Pyrefly, ty など
全てエディタと連携可能
49


# Page. 50

![Page Image](https://bcdn.docswell.com/page/3EKW3W9VED.jpg)

Ruff
Ruff の特徴
◆一つのツールで Formatter と Linter の両方の役割を果たす
◆既存のツールよりも 10-100 倍程度高速
コマンドの例
◆format
• ruff format : カレントディレクトリ下の全てのファイルを整形
• ruff format &lt;path to file or directory&gt; : 指定したパスにある全てのファイルを整形
◆lint
• ruff check : カレントディレクトリ下のファイルを解析
• ruff check --fix : 上記に加え修正可能なエラーを自動で修正
• ruff check --fix --extend-select I : 上記に加え import 文をソート
50


# Page. 51

![Page Image](https://bcdn.docswell.com/page/L731G19QJ5.jpg)

関数・クラスの説明を書く
関数やクラスの説明はコメントではなく docstring で書く
reStructuredText スタイル
Google スタイル
NumPy スタイル
def some_func(a, b):
def some_func(a, b):
def some_func(a, b):
&quot;&quot;&quot;Summary and description.
&quot;&quot;&quot;One line summary.
&quot;&quot;&quot;One line summary.
:param a: Description of a
:type a: int
:param b: Description of b
:type b: str
:returns: Description of return value
:rtype: bool
&quot;&quot;&quot;
return True
Extended description.
Extended description.
Args:
a (int): Description of a
b (str): Description of b
Parameters
---------a: int
Description of a
b: str
Description of b
Returns:
bool: Description of return value
&quot;&quot;&quot;
return True
Ruff などの Linter でスタイルのチェックが可能
• ruff check --select D
Returns
------bool
Description of return value
&quot;&quot;&quot;
return True
51


# Page. 52

![Page Image](https://bcdn.docswell.com/page/87DX1XGWEG.jpg)

Python ファイル以外のフォーマット
インデントのサイズや改行文字の種類など一部はエディタの設定で対応
EditorConfig
• ファイルのフォーマットに関するエディタの設定を記述できるツール
.editorconfig ファイルをプロジェクトルートに置いて使う
• エディタが自動で .editorconfig を読み込み
root = true
ファイル保存時などに自動で整形される
[*]
エディタごとの利用方法
• VS Code ではプラグインが必要
• EditorConfig for VS Code
• PyCharm, Vim, Helix などではプラグイン不要
.editorconfig
end_of_line = lf
insert_final_newline = true
indent_style = space
[*.{js,py}]
charset = utf-8
[*.py]
indent_size = 4
[*.yml]
indent_size = 2
52


# Page. 53

![Page Image](https://bcdn.docswell.com/page/VJPPQP3XJ8.jpg)

Python における型ヒント
型ヒント
◆Python では変数や関数の引数・戻り値などに型を明示的に記述可能
◆静的型チェックやエディタによる補完に利用され
Python 自身は型の確認などは行わず完全に無視する
def some_func(a, b):
c = 3
return f&quot;a + b + c = {a + b + c}&quot;
def some_func(a: int, b: int) -&gt; str:
c: int = 3
return f&quot;a + b + c = {a + b + c}&quot;
型の書き方
◆組み込み型や自分で定義したクラスはそのまま書ける
◆複雑な型を書くときは typing モジュールを使う
◆NumPy や PyTorch のテンソルには jaxtyping を使う
53


# Page. 54

![Page Image](https://bcdn.docswell.com/page/2EV25243EQ.jpg)

静的型チェッカー
以下の二つが主流
mypy
◆歴史が古い
◆型ヒントがない関数は無視
◆代入による変数の型の変化を
許容しない
◆動作が遅い傾向
Pyright
◆比較的新しめ
◆型ヒントがない関数は自動で推論
◆代入による変数の型の変化を
許容する
◆動作が速い傾向
多くの挙動はどちらも設定で変更可能
• 型推論の能力などに差はあるがどちらが優れているとは言い切れない
• テンソルには beartype などの実行時に動作する型チェッカーの併用を推奨
54


# Page. 55

![Page Image](https://bcdn.docswell.com/page/57GR6R1YEL.jpg)

（参考）自然言語の Linter
textlint
自然言語で書かれた文章の校正に使える Linter
スペルミスや読みにくい文章などをある程度検出できる
[22] https://textlint-ja.github.io/textlint-rule-preset-ja-technical-writing/
文章のチェックに使いたいルールをインストールして使用する
• 日本語の文章向けのルールは GitHub で複数公開されている
55


# Page. 56

![Page Image](https://bcdn.docswell.com/page/4EQV4VD6JP.jpg)

設計技法
56


# Page. 57

![Page Image](https://bcdn.docswell.com/page/KJ4MQMZME1.jpg)

整理された拡張性の高いコードを書く
綺麗に整理されたコードでバグの混入を防ぐ
◆怪しい箇所を見つけやすくなりバグを予防/早期に発見可能
◆「バグ」ではないが設定や実装がおかしくなっている部分も
早い段階で気付けるようになる
拡張性の高いコードで追加の実験に迅速に対応する
◆実験設定の変更や新しい手法の追加などが素早くできるようになる
◆査読や卒業/修了時の審査で新しい実験を求められても対応しやすくなる
整理された拡張性の高いコードは実験設定の管理も楽になる
◆実験設定やハイパーパラメータを一箇所にまとめられる
◆実装公開や引き継ぎの際の再現実験の助けになる
57


# Page. 58

![Page Image](https://bcdn.docswell.com/page/LE18P8RY7G.jpg)

クラス設計：差し替えたい箇所を考える
◆実験設定の変更などの際に差し替えたい箇所
• データセット
• モデル
• 前処理
• 損失関数・評価関数
• 最適化アルゴリズム
• ハイパーパラメータ
• etc.
差し替えたい箇所をクラスとして実装しておくと
少ない労力での差し替えが可能
class Trainer:
def __init__(
self,
model: Model,
loss: Loss,
) -&gt; None:
self.model = model
self.loss = loss
def train(self): ...
model = MLP()
loss = MSELoss()
Trainer(model, loss)
Trainer.train()
model = MLP()
loss = HuberLoss()
Trainer(model, loss)
Trainer.train()
渡す引数を変えるだけで
中身は変えずに済ませたい
58


# Page. 59

![Page Image](https://bcdn.docswell.com/page/GEWZ2Z11E2.jpg)

抽象基底クラス (Abstract Base Class)
差し替えたいコンポーネントは抽象基底クラスを用意して
インタフェースを明確にする
from abc import ABC, abstractmethod
class Loss(ABC):
@abstractmethod
def forward(self, x: float, y: float) -&gt; float:
pass
1. abc モジュールの ABC クラスを継承して
抽象基底クラスを定義
2. @abstractmethod デコレータで
抽象メソッドを明示
class MSELoss(Loss):
def forward(self, x: float, y: float) -&gt; float:
return (x - y) ** 2
class HuberLoss(Loss):
def __init__(self, delta: float = 1.0):
self.delta = delta
def forward(self, x: float, y: float) -&gt; float:
return (
(x - y) ** 2 / 2
if abs(x - y) &lt; self.delta
else self.delta * (abs(x - y) - self.delta / 2)
)
3. 子クラスで抽象メソッドを実装
子クラス同士で重複する処理があれば親クラス側で実装しておくと良い
59


# Page. 60

![Page Image](https://bcdn.docswell.com/page/47Z1D1PXJ3.jpg)

リスコフの置換原則
差し替えやすいクラスの実装のために意識すると良い原則
オブジェクト指向で用いられる SOLID 原則の一つ (L)
if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without
altering any of the desirable properties of that program (e.g. correctness).
[23] https://en.wikipedia.org/wiki/Liskov_substitution_principle
※親クラスのオブジェクトが使われている箇所を
その子クラスのオブジェクトに差し替えても問題が発生しないように設計する
model = MLP()
loss = Loss()
Trainer(model, loss)
Trainer.train()
ここを子クラス (MSELoss, HuberLoss) に置き換えても
その後のプログラムの動作に問題が生じないようにする
抽象クラスはインスタンス化できないが仮にできるものとして考える
60


# Page. 61

![Page Image](https://bcdn.docswell.com/page/YJ6L1LMPEV.jpg)

クラスのプロパティ
クラスのカプセル化に便利な機能
インスタンス変数への安全なアクセス方法を提供
class Optimizer:
def __init__(self, lr: float) -&gt; None:
self._lr = lr
@property
def lr(self) -&gt; float:
return self._lr
@lr.setter
def lr(self, v: float) -&gt; None:
if v &lt;= 0:
raise ValueError(&quot;lr must be positive&quot;)
self._lr = v
opt = Optimizer(lr=0.01)
print(opt.lr)
# -&gt; 0.01
opt.lr = 0.2
print(opt.lr)
# -&gt; 0.2
通常のインスタンス変数と同様に使える
内部では getter/setter が呼ばれている
1. @property デコレータで getter を定義
2. @メソッド名.setter デコレータで setter を定義
setter で値のチェックなどができる
61


# Page. 62

![Page Image](https://bcdn.docswell.com/page/GJ5141ZP74.jpg)

dataclass を辞書の代わりに使う
インスタンス変数を保持するだけのクラスを作る際に便利な機能
実験設定やハイパーパラメータをもたせるのに使える
dataclass を使うメリット
• 保持させるデータの構造が明確になる
• 型が明記できるので静的型チェックの対象にできる
• コンストラクタなどいくつかのメソッドが自動で実装される
• frozen=True で簡単にイミュータブルにできる
from dataclasses import dataclass
@dataclass
class ExperimentConfig:
lr: float
num_epochs: int
outdir: str = &quot;./output/&quot;
@dataclass デコレータを付ける
from dataclasses import dataclass
cfg = ExperimentConfig(
lr=0.01,
num_epochs=100,
)
普通のクラスと同様に
インスタンス化できる
@dataclass(frozen=True)
class ExperimentConfig:
lr: float
num_epochs: int
outdir: str = &quot;./output/&quot;
イミュータブルにする場合
62


# Page. 63

![Page Image](https://bcdn.docswell.com/page/LE31G19675.jpg)

Pydantic による型検証（バリデーション）
dataclass は代入された変数の型が正しいか実行時に確認しない
実行時に型の正しさを保証したい場合は Pydantic を使う
from pydantic import BaseModel
class ExperimentConfig(BaseModel):
lr: float
num_epochs: int
outdir: str = &quot;./output/&quot;
BaseModel クラスを継承する
cfg = ExperimentConfig(
lr=0.01,
num_epochs=100,
)
dataclass と同様に使える
cfg = ExperimentConfig(
lr=&quot;0.01&quot;,
num_epochs=100,
) # -&gt; ValidationError
誤った型の値を入れると
例外が送出される
from pydantic import BaseModel, field_validator
class ExperimentConfig(BaseModel):
lr: float
num_epochs: int
outdir: str = &quot;./output/&quot;
@field_validator(&quot;lr&quot;, mode=&quot;after&quot;)
@classmethod
def is_positive(cls, value: float) -&gt; float:
if value &lt;= 0:
raise ValueError(
f&quot;{value} is not positive&quot;
)
return value
値が満たすべき条件を独自に追加できる
実行時にデータの型や形式の正しさを検証することを一般にバリデーションと呼ぶ
63


# Page. 64

![Page Image](https://bcdn.docswell.com/page/8EDX1XGMJG.jpg)

依存性の注入 (Dependency Injection)
コードの柔軟性を向上させる設計パターン
あるオブジェクト A が別のオブジェクト B に依存している際
A 自身に B を生成させるのではなく外部から A に渡すようにする
依存性の注入を利用するとコードの拡張や実験設定の管理がしやすくなる
[24] https://python-dependency-injector.ets-labs.org/introduction/di_in_python.html
64


# Page. 65

![Page Image](https://bcdn.docswell.com/page/V7PPQP3Q78.jpg)

実験設定をプログラムの外から注入する
実験設定を main 関数の引数にして外から渡せるようにする
コマンドライン引数を使ったり yaml ファイルを読み込んだりすれば
プログラムを一切変更せずに実験設定を変えられる
Pydantic Settings を使えば argparse を使わずとも
コマンドライン引数で値を指定できるようになる
def main(cfg: ExperimentConfig) -&gt; None:
...
from pydantic_settings import BaseSettings, SettingsConfigDict
class ExperimentConfig(BaseSettings):
model_config = SettingsConfigDict(cli_parse_args=True)
lr: float
num_epochs: int
outdir: str = &quot;./output&quot;
BaseModel の代わりに BaseSettings クラスを継承して
SettingsConfigDict(cli_parse_args=True) を付け足す
if __name__ == &quot;__main__&quot;:
cfg = ExperimentConfig(
lr=0.01,
num_epochs=100,
outdir=&quot;./output/&quot;,
)
main(cfg)
実験設定を外から main 関数に渡す
使用した実験設定を JSON などにシリアライズしてログと一緒に保存しておくと良い
65


# Page. 66

![Page Image](https://bcdn.docswell.com/page/2JV2524PJQ.jpg)

デバッグと
パフォーマンスの向上
66


# Page. 67

![Page Image](https://bcdn.docswell.com/page/5EGR6R1QJL.jpg)

実験をたくさん回すために
早期にバグを潰して回したい実験になるべく早く辿り着く
◆ログ出力をする
◆テストを書く
◆小さい実験から始める
◆デバッガを使う
実行速度を上げて回せる実験の量を増やす
◆高速化の基本：ボトルネックの特定
◆プロファイラでボトルネックを見つける
◆高速化の様々な手段を知っておく
67


# Page. 68

![Page Image](https://bcdn.docswell.com/page/4JQV4VDW7P.jpg)

print デバッグからの脱却
様々なツールを駆使して効率的にデバッグしよう
print デバッグの問題点
◆後で print を消す必要がある
◆手作業で実行して
出力を見ないといけない
◆変数の値を網羅的に出力して
いちいち確認していたら大変
問題点の解消方法
◆logging モジュールを使って
出力のレベルをコントロール
◆自動テストで手作業の量を削減
◆エラー発生時等の変数の値を
デバッガを使って出力せず確認
68


# Page. 69

![Page Image](https://bcdn.docswell.com/page/K74MQMZ1J1.jpg)

logging モジュール
デバッグ用の情報やプログラムの実行状況など
実験の趣旨に関係ない情報の出力には logging モジュールが使える
logging モジュールの特徴
• 出力のレベルを指定できる
• デバッグ時に使う重要でない情報や
エラー発生時の重要な情報を識別できる
• 出力レベルをコマンドライン引数などで
変更できるようにしておけば
デバッグ用出力を消す必要がなくなる
• 複数の出力先に同時に出力できる
• Handler を複数指定することで
標準出力とファイルなど複数箇所に出力可能
• 設定をファイルなどで記述できる
import logging
logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
handler.setLevel(logging.INFO)
logger.setLevel(logging.INFO)
logger.addHandler(handler)
logger.info(&quot;some info&quot;)
logger.debug(&quot;for debug&quot;)
ログレベルに INFO を指定しているため
デバッグ用の “for debug” は出力されない
• 詳細はドキュメントなどを参照
69


# Page. 70

![Page Image](https://bcdn.docswell.com/page/LJ18P8R5EG.jpg)

単体テスト
関数やメソッドが正しく動作するか自動で検証する方法
出力のほか例外処理やファイル操作なども対象
単体テストの流れ
1. テストしたい関数等についてあらかじめ
テスト用のコードと入出力の組を複数用意しておく
2. テストを実行すると以下の処理が行われる
• テストツールが自動で関数を呼び出し
出力が期待されるものと一致しているか確認
• 出力の間違いやエラーがまとめて報告される
※単体テストが書きにくいと感じられる場合は
関数等を単体テストが書きやすい大きさまで分割する
入力
出力
正解
-100
-52.3
-1
0
1
23.4
0
0
-1
0
0
23.4
0
0
0
0
1
23.4
自作の ReLU 関数
70


# Page. 71

![Page Image](https://bcdn.docswell.com/page/GJWZ2Z1WJ2.jpg)

pytest
pytest: Python 用の単体テストフレームワーク
relu.py
標準ライブラリの unittest モジュールよりこちらが主流
def my_relu(x: float) -&gt; float:
return min(0, x)
pytest の基本的な使い方
test_relu.py
• テストしたいモジュールに対応したファイルを用意
• ファイル名は test_*.py または *_test.py という形式にする
• テストしたい関数ごとにテスト用の関数を用意
• 関数名は test で，クラス名は Test で始める
• テスト用の関数の中で assert 文を使って
実装した関数が期待した動作をしているか検証
• @pytest.mark.parametrize で複数の入出力をまとめてテスト可能
• CLI で pytest コマンドを実行
• テスト用のモジュール・関数は指定しなくても自動で検出される
浮動小数点数は誤差を含むので等号で比較してはいけない
import math
import pytest
from relu import my_relu
@pytest.mark.parametrize(
&quot;test_input,expected&quot;,
[(-1, 0), (0, 0), (5, 5)],
) # 一つ目と三つ目で落ちる
def test_my_relu(
test_input: float,
expected: float
) -&gt; None:
output = my_relu(test_input)
assert math.isclose(
output,
expected,
)
71


# Page. 72

![Page Image](https://bcdn.docswell.com/page/4EZ1D1P273.jpg)

pytest の使い方
fixture
テストに使う補助用の関数・クラスの定義や
ファイルの読み込み等の事前準備に使える機能
◆使い方
• @pytest.fixture デコレータを付けて関数を定義
• fixture として定義した関数の名前を
テスト用関数の引数として指定すると
fixture の戻り値が実際の引数として渡される
import pytest
@pytest.fixture
def trainer_modules() -&gt; tuple[Model, Loss]:
return MLP(), MSELoss()
def test_trainer(
trainer_modules: tuple[Model, Loss]
) -&gt; None:
model, loss = trainer_modules
trainer = Trainer(model, loss)
assert trainer.model is model
テスト対象の関数やクラスが他のオブジェクトに依存している場合
• 依存オブジェクトを生成するのではなく動作を模倣するモックを作る
• モックの作成には標準ライブラリの unittest.mock か pytest-mock モジュールを使う
• モジュールの比較はこのコメントなどを参照
72


# Page. 73

![Page Image](https://bcdn.docswell.com/page/Y76L1L46JV.jpg)

テストしにくい部分のデバッグ
機械学習や最適化では単体テストしにくい処理が頻出
◆確率的なアルゴリズムで正解の出力を用意しにくい
➢型や shape ，例外処理だけでもテストする
➢シードを固定してテストできる場合は固定する
• PyTorch の場合の固定の仕方
➢複数回実行して統計的な挙動を見る
◆学習部分のロジックなど単体テスト自体がしにくい
➢1エポックだけ，非常に簡単なデータなど小さい実験で動作確認
➢怪しい箇所ではデバッガを使って変数の状態を確認
73


# Page. 74

![Page Image](https://bcdn.docswell.com/page/G75141Q5E4.jpg)

デバッガ
コードを一行ずつ実行したり途中で一時停止/再開したりできるツール
変数の中身を確認したり書き換えたりすることも可能
◆エディタ付属のデバッガを使う
• VS Code や PyCharm には
デバッガが付属している
• 実行中の行の確認や
ブレークポイントの設定が
エディタから直接できる
◆pdb を使う
• Python 標準ライブラリに
含まれているデバッガ
• コード内で breakpoint() 関数を
呼ぶことで起動できる
[25] https://code.visualstudio.com/docs/python/debugging
74


# Page. 75

![Page Image](https://bcdn.docswell.com/page/9J21V1PG7R.jpg)

コードの実行速度の向上
高速化の基本はボトルネックの特定
• 最も時間が掛かっている処理から
高速化する
func_a()
func_b()
2倍高速化
2倍高速化
• cf. アムダールの法則
• プロファイラを使って特定する
特定後の高速化の方法
• テンソル演算に書き直す
• JIT コンパイル
• 並列化する
• 高速なライブラリに置き換える
• 高速な言語で書き直す
• 高速なデータ構造やアルゴリズムに
置き換える
func_a()
func_b()
実行時間が長い処理を高速化する方が
全体の実行時間を短くできる
75


# Page. 76

![Page Image](https://bcdn.docswell.com/page/DEYZ3Z5G7M.jpg)

プロファイラ
プログラムの実行時間やメモリの占有量などの情報を分析できるツール
プロファイラによって得意なことが異なるので使い分けが必要
• pyinstrument
• ボトルネックの特定に特化したプロファイラ
• 非同期処理等にも対応
• Line Profiler
• 行単位でのプロファイルができる
• マルチプロセスや GPU コードなどには非対応
• torch.profiler
• PyTorch 用のプロファイラ
• cProfile
• Python 標準ライブラリに含まれるプロファイラ
• 関数の呼び出し回数などを厳密に測定できる
• 非同期処理や C 言語で書かれたモジュールなどには非対応
76


# Page. 77

![Page Image](https://bcdn.docswell.com/page/VJN3V3N8J8.jpg)

高速化の方法
高速な実装が
公開されている？
高速な実装を使う
GPU に載せる
参考：Tuning Guide
テンソル演算で
書ける？
テンソルで実装する
参考：Tensor Puzzles
GPU に載る？
NumPy で
実装されている？
Numba で
JIT コンパイル
並列化できる？
並列化する
multiprocessing など
YES
NO
高速な言語/アルゴリズム/
データ構造などを検討
77


# Page. 78

![Page Image](https://bcdn.docswell.com/page/YE9969RXE3.jpg)

（参考）Continuous Integration (CI)
コードの変更を頻繁にメインラインに統合していく手法
コードの品質を保ち素早く統合することを目的として
コミットの度にビルドやテストを自動で実行する
◆GitHub Actions を使った CI
• GitHub 上のリポジトリにコミットやマージをする際に
Formatter の適用やテスト，Linter の実行が自動でできる
• GitHub Actions で Python のテストなどを行う方法
• GitHub Actions で Ruff を使う方法
78


# Page. 79

![Page Image](https://bcdn.docswell.com/page/GE89Z9W97D.jpg)

詳しく知りたい
◆SOLID 原則完全に理解した！になるための本
◆logging モジュールに関する Qiita 記事
• Pythonでprintを卒業してログ出力をいい感じにする
• ログ出力のための print と import logging はやめてほしい
◆pytest の使い方
◆リーダブルコード
79


# Page. 80

![Page Image](https://bcdn.docswell.com/page/LELWDWNMJR.jpg)

MLOps
80


# Page. 81

![Page Image](https://bcdn.docswell.com/page/4JM9P9X6EW.jpg)

MLOps とは
機械学習のワークフローを自動化・簡素化するための実践的な手法
一般的なコーディング/エンジニアリングの技術に加えて
AI 研究に特有の部分にも効率的な手法を取り入れることで
実験の効率化や再現性の向上を目指す
• 名前に ML とあるが最適化の研究でも活用可能
• 一般的にはモデルの自動デプロイや運用中の品質監視/改善も含まれるが
ここでは実験管理に関する部分のみ扱う
81


# Page. 82

![Page Image](https://bcdn.docswell.com/page/PJRG1GNNE9.jpg)

MLOps で実現したいこと
ハイパーパラメータ
最適化
実験設定の管理
実験管理
ハイパーパラメータを
最適化する
実験の設定や
ハイパーパラメータの管理
実験ログの管理と
可視化や検索
Optuna
Hydra
Ax
MLflow
Weights &amp; Biases
82


# Page. 83

![Page Image](https://bcdn.docswell.com/page/PEXXYXN8EX.jpg)

Hydra: 実験設定の管理
Hydra: 設定の管理と柔軟な変更のためのライブラリ
yaml ファイルを用いて階層的な設定を構築できる
Hydra の利点
• コマンドラインからオーバーライドできる
• 複数の実験設定での実験（グリッドサーチなど）が簡単にできる
• 出力用のディレクトリやログファイルが自動で作られる
• dataclass と組み合わせると実行時の型チェックも可能
• プラグインで HPO との連携も可能
Hydra の注意点
• ワーキングディレクトリが変わる
• Pydantic には未対応なので組み合わせにはひと手間必要
83


# Page. 84

![Page Image](https://bcdn.docswell.com/page/3EKW3WNLED.jpg)

Hydra の使用例
◆基本的な使い方
• yaml ファイルを用意
• @hydra.main デコレータを
付けて引数で設定を受け取る
◆コマンド実行例
• そのまま実行
python main.py
• loss を Huber loss に変更
python main.py loss=huber
• loss と optimizer の
全組み合わせを実行
python main.py -m loss=mse,huber
optimizer=sgd,adam
• 複数 seed の実験を回す
python main.py -m
experiment.seed=”range(0,10)”
./
├─ main.py
└─ conf/
├─ config.yaml
├─ loss/
│
├─ mse.yaml
│
└─ huber.yaml
└─ optimizer/
├─ sgd.yaml
└─ adam.yaml
from omegaconf import DictConfig
import hydra
@hydra.main(
version_base=None,
config_path=&quot;conf&quot;,
config_name=&quot;config&quot;,
)
def main(cfg: DictConfig) -&gt; None:
...
if __name__ == &quot;__main__&quot;:
main()
defaults:
- loss: mse
- optimizer: sgd
- _self_
config.yaml
experiment:
seed: 0
num_epochs: 100
name: mse
reduction: mean
loss/mse.yaml
name: huber
reduction: mean
delta: 1.0
loss/huber.yaml
name: sgd
optimizer/sgd.yaml
lr: 0.001
weight_decay: 0.0
nesterov: false
name: adam optimizer/adam.yaml
lr: 0.001
betas: [0.9, 0.999]
eps: 1.0e-8
84


# Page. 85

![Page Image](https://bcdn.docswell.com/page/L731G1V6J5.jpg)

Hydra の HPO 用プラグイン
Hydra の Sweeper Plugin を使うと Optuna, Ax, Nevergrad といった
最適化ライブラリを用いたハイパーパラメータ最適化が可能
from omegaconf import DictConfig
◆使用手順
import hydra
1. @hydra.main の関数から評価値を返すように変更
• 最大化か最小化かは設定で変えられる
2. 探索空間と最適化アルゴリズムの設定を用意
• 設定方法はドキュメントや各プラグインのサンプルを参照
3. Hydra の sweeper を optuna や ax などに変えて
Multi-run モードで実行
• python main.py -m hydra/sweeper=optuna
4. Hydra の出力ディレクトリに結果が保存される
@hydra.main(
version_base=None,
config_path=&quot;conf&quot;,
config_name=&quot;config&quot;,
)
def main(cfg: DictConfig) -&gt; float:
x, y = 1, 2
return x**2 + y**2
if __name__ == &quot;__main__&quot;:
main()
Optuna の Pruner はサポートされていないので使いたい場合は工夫が必要（参考リンク）
85


# Page. 86

![Page Image](https://bcdn.docswell.com/page/87DX1X8MEG.jpg)

実験管理（トラッキング）
実験中の各種指標の推移と使用したハイパーパラメータを記録し
それらを検索・取得する API やインタラクティブな GUI などを提供する
実験結果の管理を助けるツール
[26] https://mlflow.org/docs/latest/ml/tracking/
[27] https://docs.wandb.ai/models/track
86


# Page. 87

![Page Image](https://bcdn.docswell.com/page/VJPPQP8QJ8.jpg)

MLflow を使った実験管理
基本的な使い方
1. 実験スクリプトを with mlflow.start_run() の
中に入れる
2. ハイパーパラメータを mlflow.log_param() で，
各種指標を mlflow.log_metric() で記録する
3. 結果が保存される
• デフォルトの出力先は ./mlruns/
結果の確認
• コマンドラインから mlflow ui コマンドを
実行するとサーバが立ち上がり
ブラウザから実験結果の一覧を確認できる
import mlflow
def experiment(num_epochs: int) -&gt; None:
loss = 100
for _ in range(num_epochs):
loss -= 1
mlflow.log_metric(&quot;loss&quot;, loss)
def main(num_epochs: int) -&gt; None:
with mlflow.start_run():
mlflow.log_param(&quot;num_epochs&quot;, num_epochs)
experiment(num_epochs)
if __name__ == &quot;__main__&quot;:
main(num_epochs=100)
• デフォルトでは http://localhost:5000
87


# Page. 88

![Page Image](https://bcdn.docswell.com/page/2EV252NPEQ.jpg)

MLflow のログをプログラムで取得
基本的な流れ
import mlflow
• MlflowClient クラスの search_runs()
メソッドで実験一覧を取得
client = mlflow.tracking.MlflowClient()
experiment_id = &quot;0&quot;
runs = client.search_runs(experiment_id)
for run in runs:
print(run.data.metrics)
• ハイパーパラメータや実験日，タグなどの
条件でフィルタを掛けられる（参考リンク）
• run.data.metrics で学習の最終結果を取得できる
• 学習中の推移が必要な場合は MlflowClient の get_metric_history() メソッドを使う
右のような関数を用意して
各 run ごとに指標を取得し
DataFrame などに変換する
MLflow のクエリは重いので
繰り返し使う実験結果は
CSV などに保存しておくと
後で楽になる
import mlflow
import pandas as pd
def convert_metric_history_to_dataframe(client, run, keys, param_keys):
run_id = run.info.run_id
df = pd.DataFrame()
for key in keys:
history = client.get_metric_history(run_id=run_id, key=key)
df = pd.concat([df, pd.DataFrame({key: [m.value for m in history]})], axis=1)
df[&quot;run_id&quot;] = run_id
for param_key in param_keys:
df[param_key] = run.data.params[param_key]
return df
88


# Page. 89

![Page Image](https://bcdn.docswell.com/page/57GR6RKQEL.jpg)

MLflow と Hydra を組み合わせる際の注意点
• Hydra が自動生成するファイル（実験設定やログファイルなど）を
mlflow.log_artifact() で記録しておく
• mlflow.log_param() は
階層的な設定に非対応なので
右のような関数を用意して
再帰的に記録すると良い
from typing import Union
import mlflow
from omegaconf import DictConfig, ListConfig, OmegaConf
def log_params_from_dictconfig(params: DictConfig) -&gt; None:
def _log_recursively(parent: str, child: Union[DictConfig, ListConfig]):
if OmegaConf.is_dict(child):
for key, value in child.items():
if OmegaConf.is_dict(value) or OmegaConf.is_list(value):
_log_recursively(f&quot;{parent}.{key}&quot;, value)
else:
mlflow.log_param(f&quot;{parent}.{key}&quot;, value)
elif OmegaConf.is_list(child):
for i, value in enumerate(child):
mlflow.log_param(f&quot;{parent}.{i}&quot;, value)
for key, value in params.items():
_log_recursively(key, value)
[28] https://ymym3412.hatenablog.com/entry/2020/02/09/034644 を参考に作成
89


# Page. 90

![Page Image](https://bcdn.docswell.com/page/4EQV4VNWJP.jpg)

Weights and Biases (WandB) を使った実験管理
SaaS 型のプラットフォームであり利用にはアカウントが必要
登録後コマンドラインで wandb login コマンドを実行してから利用する
基本的な使い方
MLflow と概ね同じように使える
1. 実験スクリプトを with wandb.init() の中に入れる
ハイパーパラメータは config 引数で渡しておく
2. 各種指標を wandb.Run オブジェクトの
log() メソッドで記録する
• Run オブジェクトは wandb.run でも取得可能
3. 結果が保存される
結果の確認
• WandB のサイトにアクセスして web で確認する
ローカルでは結果を確認できないので注意
import wandb
from wandb import Run
def experiment(num_epochs: int, run: Run) -&gt; None:
loss = 100
for _ in range(num_epochs):
loss -= 1
run.log({&quot;loss&quot;: loss})
def main(num_epochs: int) -&gt; None:
with wandb.init(
project=&quot;my-experiments&quot;,
config={&quot;num_epochs&quot;: num_epochs},
) as run:
experiment(num_epochs, run)
if __name__ == &quot;__main__&quot;:
main(num_epochs=100)
90


# Page. 91

![Page Image](https://bcdn.docswell.com/page/KJ4MQMG1E1.jpg)

WandB のログをプログラムで取得
基本的な流れ
ログの取得には Public API を使う
• wandb.Api クラスの runs() メソッドで実験一覧を取得
• MLflow と同様フィルタを掛けられる（参考リンク）
• 取得した Runs オブジェクトの histories() メソッドで指標の推移の一部を取得可能
• 各 Run ごとに一定の数をサンプルしたものが返される
• 全ての結果が欲しい場合は各 Run で scan_history() メソッドを使う
• ハイパーパラメータは各 Run オブジェクトの config 属性で保持されている
• 階層的になっている場合もあるので DataFrame のカラム等に使用する場合は flatten する
import wandb
api = wandb.Api(timeout=29)
runs = api.runs(path=&quot;my-entity/my-project&quot;)
print(runs.histories())
for run in runs:
for row in run.scan_history(keys=[&quot;loss&quot;]):
print(row)
91


# Page. 92

![Page Image](https://bcdn.docswell.com/page/LE18P8D57G.jpg)

WandB を使ったハイパーパラメータ最適化
Sweeps を使えばハイパーパラメータ最適化が可能
基本的な流れ
ログに記録された指標を見て最適化
されるので戻り値の変更等は不要
1. wandb.sweep() に HPO の設定を
渡して初期化
2. wandb.agent() に sweep の ID と
実行したい関数を渡して開始
対応アルゴリズム
• 最適化アルゴリズム
• ランダムサーチ，グリッドサーチ，
ベイズ最適化
• Hyperband
import wandb
def main() -&gt; None:
with wandb.init(project=&quot;my-sweeps&quot;) as run:
loss = experiment(
lr=run.config.lr,
optimizer=run.config.optimizer,
)
run.log({&quot;loss&quot;: loss})
if __name__ == &quot;__main__&quot;:
sweep_cfg = {
&quot;method&quot;: &quot;random&quot;,
&quot;metric&quot;: {&quot;goal&quot;: &quot;minimize&quot;, &quot;name&quot;: &quot;loss&quot;},
&quot;parameters&quot;: {
&quot;lr&quot;: {&quot;max&quot;: 0.1, &quot;min&quot;: 0.0001},
&quot;optimizer&quot;: {&quot;values&quot;: [&quot;sgd&quot;, &quot;adam&quot;]},
},
}
sweep_id = wandb.sweep(sweep=sweep_cfg, project=&quot;my-sweeps&quot;)
wandb.agent(sweep_id, function=main, count=10)
92


# Page. 93

![Page Image](https://bcdn.docswell.com/page/GEWZ2ZYWE2.jpg)

MLflow と WandB の比較
MLflow
WandB
ハイパーパラメータ最適化
x
o
ローカルのみでの使用
o
x
GUI の動作
重め
軽め
可視化機能
シンプル
高機能
料金
無料
一部無料
その他の事項
• WandB は web から GUI にアクセスするので
実験の途中経過などをどこからでも確認できる
• 実験結果は確認可能なかたちで長期保存する必要があるので
WandB 単体での使用は避けた方が無難かも
93


# Page. 94

![Page Image](https://bcdn.docswell.com/page/47Z1D1X2J3.jpg)

その他の実験管理ツール
◆Neptune.ai
• SaaS 型
◆Comet
• SaaS 型
◆Trackio
• ローカルでも動作する
• Hugging Face 製
◆Sacred
• ローカルでも動作する
94


# Page. 95

![Page Image](https://bcdn.docswell.com/page/YJ6L1LP6EV.jpg)

参考：機械学習パイプライン
「データ読み込み→データ前処理→モデルの学習→モデルの評価」
といった機械学習の一連の処理の流れをまとめて行えるようにする仕組み
処理をまとめて実行する仕組みだけでなく
一連の処理を整理して実装するための枠組みやパイプラインの可視化機能なども提供
主要なツール
• Scikit-learn Pipeline
• Kedro
• Flyte
• Prefect
• ZenML
[29] https://kedro.org/#features
95


# Page. 96

![Page Image](https://bcdn.docswell.com/page/GJ5141K574.jpg)

詳しく知りたい
◆小さく始めて大きく育てるMLOps2020
◆Neptune.ai による MLOps ツール紹介記事
• 13 Best Tools for ML Experiment Tracking and Management in 2025
• Best Machine Learning Workflow and Pipeline Orchestration Tools
96


# Page. 97

![Page Image](https://bcdn.docswell.com/page/9E21V1WGJR.jpg)

出典
[1] Pallets. ”flask.” GitHub, 2025-11-10, https://github.com/pallets/flask.
[2] Pallets. ”Issues pallets/flask.” GitHub, 2025-11-10, https://github.com/pallets/flask/issues.
[3] Atlassian. “Gitflow ワークフロー.” Atlassian, 2025-11-10,
https://www.atlassian.com/ja/git/tutorials/comparing-workflows/gitflow-workflow.
[4] Astral. “Managing dependencies.” uv, 2025-11-10,
https://docs.astral.sh/uv/concepts/projects/dependencies/#project-dependencies.
[5] Astral. “Commit c826f2b.” GitHub, 2025-11-10,
https://github.com/astral-sh/uv/commit/c826f2b042c78af0b58e1a27c43b8a5603a0f2b3.
[6] PyTorch. “pytorch/torch/nn/functional.py.” GitHub, 2025-11-10,
https://github.com/pytorch/pytorch/blame/3cfbf98ea9d937d23f3700168b22706c957308ce/torch/nn/func
tional.py.
[7] ファーエンドテクノロジー株式会社. “Redmineとは.” Redmine.JP, 2025-11-10,
https://redmine.jp/overview/.
[8] Atlassian. “Jiraプロジェクト管理テンプレート.” Atlassian, 2025-11-10,
https://www.atlassian.com/ja/software/jira/templates/project-management-templates.
[9] ray-project. “Issues ray-project/ray.” GitHub, 2025-11-10, https://github.com/ray-project/ray/issues.
97


# Page. 98

![Page Image](https://bcdn.docswell.com/page/D7YZ3ZLGJM.jpg)

出典
[10] ray-project. “Milestones.” GitHub, 2025-11-10, https://github.com/ray-project/ray/milestones.
[11] ray-project. “K8s and Ray (go/k8s-ray-oss).” GitHub, 2025-11-10, https://github.com/orgs/rayproject/projects/79/views/4.
[12] ray-project. “Pull requests ray-project/ray.” GitHub, 2025-11-10, https://github.com/rayproject/ray/pulls.
[13] rust-lang. “Tracking Issue for compiletest directive handling bugs and papercuts.” GitHub, 2025-11-12,
https://github.com/rust-lang/rust/issues/131425.
[14] PyTorch. “pytorch/.github/ISSUE_TEMPLATE.” GitHub, 2025-11-12,
https://github.com/pytorch/pytorch/tree/main/.github/ISSUE_TEMPLATE.
[15] PyTorch. “Issues pytorch/pytorch.” GitHub, 2025-11-12, https://github.com/pytorch/pytorch/issues.
[16] PyTorch. “Milestones pytorch/pytorch.” GitHub, 2025-11-12,
https://github.com/pytorch/pytorch/milestones.
[17] rust-lang. “Lazy Type Aliases (LTA).” GitHub, 2025-11-12, https://github.com/orgs/rustlang/projects/59/views/1.
[18] Wagtail. “Wagtail public roadmap.” GitHub, 2025-11-12,
https://github.com/orgs/wagtail/projects/16/views/4.
98


# Page. 99

![Page Image](https://bcdn.docswell.com/page/VEN3V348E8.jpg)

出典
[19] Farama-Foundation. “[Bugfix] fixed step() function in AsyncVectorEnv from hanging forever.” GitHub,
2025-11-12, https://github.com/Farama-Foundation/Gymnasium/pull/1419.
[20] Farama-Foundation. “[Bug]AsyncVectorEnv.step_await is blocked infinitely if actions.shape[0] &lt;
num_envs.” GitHub, 2025-11-12, https://github.com/Farama-Foundation/Gymnasium/issues/1417.
[21] Genesis-Embodied-AI. “[MISC] Import math module instead of constants to avoid violating gstaichi
pure checker.” GitHub, 2025-11-12, https://github.com/Genesis-Embodied-AI/Genesis/pull/1812.
[22] textlint-ja. “textlint-rule-preset-ja-technical-writing-example.” textlint-rule-preset-ja-technical-writingexample, 2025-11-13, https://textlint-ja.github.io/textlint-rule-preset-ja-technical-writing/.
[23] Wikipedia. “Liskov substitution principle.” Wikipedia, 2025-11-13,
https://en.wikipedia.org/wiki/Liskov_substitution_principle.
[24] Roman Mogylatov. “Dependency injection and inversion of control in Python.” Dependency Injector,
2025-11-13, https://python-dependency-injector.ets-labs.org/introduction/di_in_python.html.
[25] Microsoft. “Python debugging in VS Code.” Visual Studio Code documentation, 2025-11-13,
https://code.visualstudio.com/docs/python/debugging.
[26] MLflow Project. “MLflow Tracking.” MLflow Documentation, 2025-11-13,
https://mlflow.org/docs/latest/ml/tracking/.
99


# Page. 100

![Page Image](https://bcdn.docswell.com/page/Y79969QX73.jpg)

出典
[27] Weights &amp; Biases. “Experiments overview.” Weights &amp; Biases Documentation, 2025-11-13,
https://docs.wandb.ai/models/track.
[28] ymym3412. “ハイパラ管理のすすめ -ハイパーパラメータをHydra+MLflowで管理しよう-.” やむやむ
もやむなし, 2025-11-13, https://ymym3412.hatenablog.com/entry/2020/02/09/034644.
[29] LF AI &amp; Data Foundation. “Kedro | An open-source framework for data science code.” kedro, 2025-1113, https://kedro.org/#features.
100


