ディープラーニングをPythonで始めるなら、まずは定番のTensorFlowとPyTorchを小さく動かして仕組みを体験するのが近道です。
本記事では、環境構築からGPU確認、画像分類の最小例、学習・評価・推論・保存までを初心者の方でも着実に進められる順序で丁寧に解説します。
ディープラーニング入門
ディープラーニングとは
直観的なイメージ
ディープラーニングは、多層のニューラルネットワークがデータから自動的に特徴を学習し、分類や回帰などのタスクを解く手法です。
画像ではエッジや質感、形状などを層を重ねながら抽象化して捉えます。
特徴量設計を人が細かく作らなくても、データと学習アルゴリズムが適切なら高い性能を発揮します。
用語の最小セット
まずは次の語だけ押さえておくと理解が進みます。
epoch
(学習データを何周するか)、batch size
(一度に学習へ渡すサンプル数)、loss
(損失。どれだけ間違えているか)、optimizer
(損失を小さくするための更新則)、overfitting
(過学習。訓練には強いが汎化が弱い状態)です。
TensorFlowとPyTorchの違い
概観比較
両者はできることの多くが重なりますが、設計思想や書き味に違いがあります。
どちらを選んでも学びは活きます。
観点 | TensorFlow | PyTorch |
---|---|---|
設計哲学 | 産業利用を意識したエコシステムが広い。tf.keras で高レベルに記述しやすい | 直感的なPythonライクな記述。研究・プロトタイピングで人気 |
実装スタイル | model.compile とfit 中心で宣言的に書ける | 低レベルの訓練ループを自分で書きやすく柔軟 |
可視化 | TensorBoard が標準的 | torch.utils.tensorboard やwandb など自由 |
デプロイ | TF Serving やTF Lite が充実 | TorchScript やTorchServe が選択肢 |
どちらを選ぶべきか
まずはどちらか一方で小さく成功体験を積み、必要に応じてもう一方も触るのが近道です。
Kerasの高レベルAPIで素早く成果を出したいならTensorFlow、トレーニングループを理解しながら柔軟に書きたいならPyTorchが向いています。
学習の流れ
全体のステップ
ディープラーニングの基本的な流れは、(1)データ準備、(2)モデル定義、(3)損失と最適化の設定、(4)学習(訓練ループ)、(5)評価、(6)推論と保存、の順です。
この流れはフレームワークが変わっても普遍です。
最初の目標設定
本記事では、手書き数字データ(MNIST)を使った画像分類の最小例をTensorFlowとPyTorchの両方で実装し、学習から保存・推論まで一気通貫で体験します。
環境構築とインストール
Pythonの準備
仮想環境の作成(venv)
プロジェクトごとに依存を分離するため仮想環境を使います。
以下は共通的な手順です。
# 1) プロジェクト用ディレクトリを作成
mkdir dl-intro && cd dl-intro
# 2) 仮想環境を作成と有効化 (Windows)
python -m venv .venv
.venv\Scripts\activate
# macOS/Linux
# python3 -m venv .venv
# source .venv/bin/activate
# 3) パッケージ管理ツールを最新化
python -m pip install --upgrade pip setuptools wheel
パッケージの更新
ビルド不要のホイール配布を利用するため、pip
やsetuptools
を最新化しておくとトラブルが少なくなります。
TensorFlowのインストール
CPU版のインストール
まずはCPU版で問題なく動くことを確認するとスムーズです。
pip install --upgrade tensorflow
GPU版のインストール
GPU対応は環境依存が大きいです。
新しめのTensorFlowではextras
でCUDA/CuDNN付きのインストールが可能です。
# 例: 近年のTensorFlowでCUDA/CuDNNを同時に入れる
pip install "tensorflow[and-cuda]"
Windows では tensorflow[and-cuda]
の依存パッケージ nvidia-nccl-cu12
のホイールが提供されていないため、pip が解決に失敗します。
NCCL は Linux 向けの通信ライブラリで、Windows 版は公開されていません。そのためWindowsを使用する場合はWSL2 + Ubuntuの環境下で開発してください。
うまくいかないときはまずCPU版で動作確認し、GPUは段階的に導入します。
PyTorchのインストール
CPU版のインストール
PyTorchは配布チャネルが分かれています。
CPU版は次のように入れます。
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
GPU版のインストール
使用するCUDAバージョンに応じたインデックスURLを選びます。
以下はCUDA 12.1向けの例です。
# CUDA 12.6 向けの例
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
PyTorch は Windows ネイティブで GPU (CUDA) 対応版を導入できます。
TensorFlow と違って、PyTorch は Windows 用の CUDA ホイールを公式で配布しています。なので以下のようなコマンドで問題ありません:
なお、古いホイールはインストールできない場合があります。
PyTorch公式にて、現時点で正しくインストールできるコマンドが更新されているはずなので、そちらを参考にしてください。

どのコマンドを使うべきかは公式の「Get Started」ページでOS/CUDAを選択して決めるのが確実です。
GPUの確認
TensorFlowとPyTorchのGPU検出
PythonからGPUが見えているかを確かめます。
当然ですが、GPU対応版のTensorflow、PyTorchの導入が必須です。CPU版はGPUを認識できない(CPUでしか処理できない)ので注意しましょう。
# gpu_check.py
# TensorFlow と PyTorch の GPU 検出を一括で確認します
import sys
print("Python:", sys.version)
try:
import tensorflow as tf
gpus_tf = tf.config.list_physical_devices("GPU")
print("[TensorFlow] GPUs:", gpus_tf)
except Exception as e:
print("[TensorFlow] Import/Check error:", e)
try:
import torch
print("[PyTorch] cuda.is_available:", torch.cuda.is_available())
if torch.cuda.is_available():
print("[PyTorch] device name:", torch.cuda.get_device_name(0))
print("[PyTorch] cuda version:", torch.version.cuda)
except Exception as e:
print("[PyTorch] Import/Check error:", e)
Python: 3.11.6 (main, ...)
[TensorFlow] GPUs: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
[PyTorch] cuda.is_available: True
[PyTorch] device name: NVIDIA GeForce RTX 4080 SUPER
[PyTorch] cuda version: 12.6
インストールのつまずき対策
代表的な原因と手当
インストールがうまくいかない原因の多くはPythonのバージョンとビルド済みホイールの対応不一致やCUDA/CuDNNの不整合です。
次の観点で順に切り分けます。
- Python 3.10~3.11が現状では無難です。
python --version
で確認し、必要なら環境を作り直します。 - まずはCPU版で動作確認し、次にGPU版へ移行します。
- NVIDIA GPUの場合、
nvidia-smi
でドライバの状態を確認します。 - どうしてもエラーが続く場合は
pip cache purge
でキャッシュをクリアし、再インストールします。 - Apple Siliconは
tensorflow-macos
とtensorflow-metal
の組み合わせを利用するケースがあります。OSのサポート状況に注意します。
TensorFlowの基本
テンソルとレイヤー
テンソルの作成と基本演算
TensorFlowの基本データ構造はテンソルです。
NumPy配列に似ています。
# tf_tensor_basics.py
import tensorflow as tf
# 定数テンソル
a = tf.constant([[1, 2], [3, 4]], dtype=tf.float32)
b = tf.ones((2, 2))
# 基本演算
c = a + b
d = tf.matmul(a, b)
print("a:", a.numpy())
print("b:", b.numpy())
print("c = a + b:", c.numpy())
print("d = a @ b:", d.numpy())
a: [[1. 2.]
[3. 4.]]
b: [[1. 1.]
[1. 1.]]
c = a + b: [[2. 3.]
[4. 5.]]
d = a @ b: [[3. 3.]
[7. 7.]]
レイヤーの基本
Kerasレイヤーでネットワークを簡潔に組み立てられます。
# tf_layers_basic.py
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# シンプルな全結合ネットワーク
model = keras.Sequential([
layers.Input(shape=(4,)), # 入力は4次元ベクトル
layers.Dense(8, activation="relu"), # 隠れ層
layers.Dense(3, activation="softmax") # 出力は3クラス
])
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 8) 40
dense_1 (Dense) (None, 3) 27
=================================================================
Total params: 67
Trainable params: 67
Non-trainable params: 0
_________________________________________________________________

データ読み込み
MNISTデータの取得と前処理
Kerasは代表的なデータセットを内蔵しています。
ここでは手書き数字のMNISTを使います。
# tf_data_mnist.py
import tensorflow as tf
from tensorflow.keras import datasets
# データのロード
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
# スケーリングとチャンネル次元の追加(28x28 -> 28x28x1)
x_train = (x_train / 255.0).astype("float32")[..., None]
x_test = (x_test / 255.0).astype("float32")[..., None]
print("x_train:", x_train.shape, x_train.dtype)
print("y_train:", y_train.shape, y_train.dtype)
print("x_test:", x_test.shape)
x_train: (60000, 28, 28, 1) float32
y_train: (60000,) uint8
x_test: (10000, 28, 28, 1)
画像分類の最小例
小さなCNNで学習
最小限のCNNを定義して学習します。
# tf_mnist_minimal_cnn.py
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, datasets
# 1) データ
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_train = (x_train / 255.0).astype("float32")[..., None]
x_test = (x_test / 255.0).astype("float32")[..., None]
# 2) モデル定義
model = keras.Sequential([
layers.Input(shape=(28, 28, 1)),
layers.Conv2D(16, 3, activation="relu"),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, activation="relu"),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(64, activation="relu"),
layers.Dense(10, activation="softmax"),
])
# 3) コンパイル(損失と最適化の設定)
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"]
)
# 4) 学習
history = model.fit(
x_train, y_train,
validation_split=0.1, # 10%を検証に使う
epochs=3,
batch_size=128,
verbose=2
)
Epoch 1/3
422/422 - 2s - 5ms/step - accuracy: 0.9131 - loss: 0.3030 - val_accuracy: 0.9765 - val_loss: 0.0859
Epoch 2/3
422/422 - 1s - 3ms/step - accuracy: 0.9762 - loss: 0.0793 - val_accuracy: 0.9813 - val_loss: 0.0656
Epoch 3/3
422/422 - 1s - 3ms/step - accuracy: 0.9827 - loss: 0.0566 - val_accuracy: 0.9860 - val_loss: 0.0513
学習と評価
テストデータでの評価
学習後に未知データで性能を確認します。
# tf_evaluate.py
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
# ここでは学習済み model を簡潔に再作成して評価のみ例示
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_test = (x_test / 255.0).astype("float32")[..., None]
# モデルは学習済みのものを想定(上のスクリプトで作った model を再利用する想定)
# ここでは簡易に同じ構造を定義し直してロードの章で重みを復元します。
print("テストデータで評価を実施します。")
テストデータで評価を実施します。
上記はプレースホルダーです。
実際の評価は次の保存・推論の節で学習済みモデルを読み込みつつ行います。
推論と保存
モデルの保存、ロード、推論
Kerasではmodel.save
で1行保存できます。
推論も簡単です。
# tf_save_infer.py
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, datasets
# 学習(最短で1エポックだけ回して保存例を示す)
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_train = (x_train / 255.0).astype("float32")[..., None]
x_test = (x_test / 255.0).astype("float32")[..., None]
model = keras.Sequential([
layers.Input(shape=(28, 28, 1)),
layers.Conv2D(16, 3, activation="relu"),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(10, activation="softmax"),
])
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(x_train, y_train, epochs=1, batch_size=256, verbose=0)
# 1) 保存
model.save("mnist_cnn.keras")
# 2) ロード
loaded = keras.models.load_model("mnist_cnn.keras")
# 3) 推論(最初のテスト画像で予測)
logits = loaded.predict(x_test[:1], verbose=0) # 1枚だけ
pred = np.argmax(logits, axis=1)[0]
print("Predicted:", pred, " / True:", int(y_test[0]))
Predicted: 7 / True: 7
Keras形式(.keras)で保存しておくと再現や共有が容易です。
必要に応じてSavedModel
やHDF5
形式も利用できます。
PyTorchの基本
テンソルと勾配
TensorとAutograd
PyTorchではテンソルが自動微分の履歴を持つため、勾配計算が自然に書けます。
# torch_autograd_basics.py
import torch
# requires_grad=True にすると勾配が追跡される
x = torch.tensor([2.0, 3.0], requires_grad=True)
W = torch.tensor([[1.0, -1.0]], requires_grad=True) # 1x2 の行列
y = W @ x # 行列ベクトル積 -> 形状(1,)
loss = (y - 1.0).pow(2).mean() # シンプルな二乗誤差
loss.backward() # 勾配計算
print("y:", y.item())
print("d(loss)/dW:", W.grad)
print("d(loss)/dx:", x.grad)
y: -1.0
d(loss)/dW: tensor([[ -8., -12.]])
d(loss)/dx: tensor([-4., 4.])
データ読み込み
torchvisionでMNISTを取得
データセットと変換はtorchvision
が便利です。
# torch_data_mnist.py
import torch
from torchvision import datasets, transforms
# テンソル化 + 0.1307, 0.3081 はMNISTの平均と標準偏差
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
train_ds = datasets.MNIST(root="./data", train=True, download=True, transform=transform)
test_ds = datasets.MNIST(root="./data", train=False, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_ds, batch_size=128, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_ds, batch_size=256)
print("train size:", len(train_ds), "/ test size:", len(test_ds))
train size: 60000 / test size: 10000
画像分類の最小例
小さなCNNモデルと学習ループ
PyTorchでは訓練ループを自分で書くので仕組みを理解しやすいです。
# torch_mnist_minimal_cnn.py
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets, transforms
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 1) データ
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
train_ds = datasets.MNIST(root="./data", train=True, download=True, transform=transform)
test_ds = datasets.MNIST(root="./data", train=False, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_ds, batch_size=128, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_ds, batch_size=256)
# 2) モデル定義
class SmallCNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 16, 3) # 1x28x28 -> 16x26x26
self.pool = nn.MaxPool2d(2) # 16x26x26 -> 16x13x13
self.conv2 = nn.Conv2d(16, 32, 3) # 32x11x11
self.fc1 = nn.Linear(32*5*5, 64)
self.fc2 = nn.Linear(64, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x))) # -> (32, 5, 5)
x = torch.flatten(x, 1)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
model = SmallCNN().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
criterion = nn.CrossEntropyLoss()
# 3) 学習ループ
def train_epoch(model, loader, optimizer, criterion):
model.train()
running_loss, correct, total = 0.0, 0, 0
for x, y in loader:
x, y = x.to(device), y.to(device)
optimizer.zero_grad()
logits = model(x)
loss = criterion(logits, y)
loss.backward()
optimizer.step()
running_loss += loss.item() * x.size(0)
pred = logits.argmax(dim=1)
correct += (pred == y).sum().item()
total += y.size(0)
return running_loss/total, correct/total
def evaluate(model, loader, criterion):
model.eval()
loss_sum, correct, total = 0.0, 0, 0
with torch.no_grad():
for x, y in loader:
x, y = x.to(device), y.to(device)
logits = model(x)
loss = criterion(logits, y)
loss_sum += loss.item() * x.size(0)
pred = logits.argmax(dim=1)
correct += (pred == y).sum().item()
total += y.size(0)
return loss_sum/total, correct/total
for epoch in range(1, 4):
tr_loss, tr_acc = train_epoch(model, train_loader, optimizer, criterion)
te_loss, te_acc = evaluate(model, test_loader, criterion)
print(f"Epoch {epoch}/3 - train loss:{tr_loss:.4f} acc:{tr_acc:.4f} - test loss:{te_loss:.4f} acc:{te_acc:.4f}")
Epoch 1/3 - train loss:0.2191 acc:0.9368 - test loss:0.0662 acc:0.9803
Epoch 2/3 - train loss:0.0698 acc:0.9785 - test loss:0.0490 acc:0.9847
Epoch 3/3 - train loss:0.0507 acc:0.9846 - test loss:0.0431 acc:0.9864
このコードは、手書き数字(MNIST)を分類する小さなCNNをPyTorchで実装したものです。
まずMNISTデータを読み込み、画像をテンソル化&正規化します。
次に畳み込み層・プーリング層で特徴を抽出し、全結合層で0〜9の数字に分類します。
学習はクロスエントロピー損失とAdam最適化を使い、訓練とテストを繰り返して精度を表示します。
学習と評価
ここでは精度(accuracy)を使いましたが、実務では混同行列や再現率・適合率・F1なども重要です。
PyTorchではtorchmetrics
やscikit-learn
の関数と組み合わせて評価の幅を広げます。
推論と保存
PyTorchではstate_dict
を保存するのが一般的です。
# torch_save_infer.py
import torch
import torch.nn as nn
from torchvision import datasets, transforms
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# モデル定義(学習時と同じ構造)
class SmallCNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 16, 3)
self.pool = nn.MaxPool2d(2)
self.conv2 = nn.Conv2d(16, 32, 3)
self.fc1 = nn.Linear(32*5*5, 64)
self.fc2 = nn.Linear(64, 10)
def forward(self, x):
import torch.nn.functional as F
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = torch.flatten(x, 1)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
# 1) モデルの初期化と重みロード
model = SmallCNN().to(device)
# ここでは事前に torch.save(model.state_dict(), "mnist_cnn.pt") してある想定
# 学習済みの重みがない場合、この行はエラーになる点に注意してください
try:
model.load_state_dict(torch.load("mnist_cnn.pt", map_location=device))
model.eval()
except FileNotFoundError:
print("mnist_cnn.pt が見つかりません。学習後に保存してから再実行してください。")
# 2) データの用意と単発推論
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
test_ds = datasets.MNIST(root="./data", train=False, download=True, transform=transform)
x, y_true = test_ds[0] # 先頭の1枚
x = x.unsqueeze(0).to(device) # (1, 1, 28, 28)
with torch.no_grad():
logits = model(x)
pred = logits.argmax(dim=1).item()
print("Predicted:", pred, "/ True:", y_true)
Predicted: 7 / True: 7
学習時のネットワーククラスと同じ構造でインスタンス化した上でstate_dict
をロードする点がKerasとの大きな違いです。
まとめ
本記事では、TensorFlowとPyTorchの基本を同じ題材(MNIST)で対比しながら体験しました。
環境構築、GPU確認、テンソルの基本、データ読み込み、最小のCNNによる学習・評価、そしてモデルの保存と推論までを一通り押さえました。
どちらのフレームワークでも、流れはデータ準備→モデル定義→損失と最適化→学習→評価→保存・推論という共通パターンです。
最初はCPUで小さく成功し、必要になってからGPU対応に進めると挫折しにくいです。
次の一歩として、データ拡張や正則化、学習率スケジューラ、TensorBoardやメトリクスの拡充などに挑戦してみてください。
小さな成功を積み重ねることが、ディープラーニング上達の最短ルートです。