概要
学習済みモデル(Pretrained Model)とは、大量のデータを使って事前に学習・訓練されたニューラルネットワークのパラメータ(重み)を持つモデルのことです。ゼロから学習する代わりに、既存の学習済みモデルを使うことで、開発期間の短縮・学習コストの削減・少ないデータでの高い精度実現が可能になります。
学習済みモデルを活用する手法は主に三つあります。
| 手法 | 内容 | 用途 |
|---|---|---|
| そのまま使用(Inference Only) | 学習済みモデルをそのまま推論に使用 | 汎用タスク |
| 転移学習(Transfer Learning) | 一部のレイヤーを新タスク向けに追加学習 | 特定ドメイン向け |
| ファインチューニング(Fine-tuning) | 全体または一部を少量データで再学習 | 特化タスク向け |
組み込みシステムにおける学習済みモデルの活用は、エッジAI実用化の重要な加速要因となっています。大規模な学習インフラなしに、スマートフォン・IoTデバイス・組み込みボードに高度なAI機能を搭載できます。
歴史・背景
学習済みモデルの概念と普及には以下のような経緯があります。
2012年以前: 機械学習モデルは各プロジェクトでゼロから学習するのが一般的で、学習済みモデルの共有・再利用という文化はほとんどありませんでした。
主要な発展:
| 年 | 出来事 |
|---|---|
| 2012年 | AlexNet(ImageNet学習済み)が公開、転移学習の有効性が実証 |
| 2014年 | VGGNet・GoogLeNetの学習済み重みが公開されオープンソース化が加速 |
| 2016年 | TensorFlow Hubが学習済みモデルの共有プラットフォームとして登場 |
| 2018年 | BERT(自然言語処理向け学習済みモデル)が登場、NLPに革命 |
| 2019年 | Hugging Face ModelHub が急成長、数千モデルが集積 |
| 2020年 | GPT-3・Vision Transformerが大規模学習済みモデルの時代を開く |
| 2021年 | CLIP・DALL-Eなどマルチモーダル学習済みモデルが登場 |
| 2022年 | Stable Diffusion等オープンな生成AIモデルが広く普及 |
| 2023年以降 | LLaMA・Mistralなどオープンソース大規模言語モデルの普及 |
技術仕様
学習済みモデルの構成要素
学習済みモデルのファイル構成(例)
├── model_weights.h5 # Kerasの場合(重みファイル)
├── model.json # アーキテクチャ定義
├── model.onnx # ONNXフォーマット(クロスプラットフォーム)
├── model.tflite # TFLite(モバイル・エッジ向け)
├── config.json # ハイパーパラメータ設定
├── vocab.txt # 語彙ファイル(NLPの場合)
└── preprocessor_config.json # 前処理設定
ImageNet学習済みモデルの特性
最も広く使われる事前学習データセットはImageNetです。ImageNetで学習したモデルは1000クラスの分類が可能で、特徴抽出器として転移学習に活用されます。
| モデル | Top-1精度 | モデルサイズ | 推論時間(CPU) | エッジ適性 |
|---|---|---|---|---|
| ResNet-50 | 76.1% | 98MB | 120ms | △ |
| MobileNetV2 | 71.8% | 14MB | 25ms | ○ |
| EfficientNet-B0 | 77.1% | 20MB | 35ms | ○ |
| MobileNetV3-Small | 67.4% | 9.6MB | 15ms | ◎ |
| EfficientNet-Lite0 | 75.1% | 15MB | 20ms | ◎ |
| SqueezeNet1.1 | 58.2% | 5MB | 10ms | ◎(MCU向け) |
転移学習のアーキテクチャ
ImageNet学習済みモデル(バックボーン)
┌──────────────────────────────────────┐
│ Conv Block 1 (低レベル特徴: エッジ等) │ ← 凍結(重みを変更しない)
│ Conv Block 2 │ ← 凍結
│ Conv Block 3 │ ← 凍結 or 微調整
│ Conv Block 4 (高レベル特徴: 物体形状)│ ← 微調整
│ Conv Block 5 │ ← 微調整
│ Global Average Pooling │
└──────────────────────────────────────┘
↓ 特徴量ベクトル(1280次元等)
┌──────────────────────────────────────┐
│ カスタム分類ヘッド(新規追加) │ ← 学習する
│ Dense(256) → ReLU → Dropout │
│ Dense(num_classes) → Softmax │
└──────────────────────────────────────┘
↓
カスタムタスクの予測結果
動作原理
転移学習の実装(TensorFlow/Keras)
import tensorflow as tf
# 学習済みMobileNetV2をバックボーンとして使用
base_model = tf.keras.applications.MobileNetV2(
input_shape=(224, 224, 3),
include_top=False, # 分類ヘッドを除く
weights='imagenet' # ImageNet学習済み重みを使用
)
# バックボーンの重みを凍結
base_model.trainable = False
# カスタム分類ヘッドを追加
model = tf.keras.Sequential([
base_model,
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(num_classes, activation='softmax')
])
# Phase 1: ヘッドのみ学習(高いLR)
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss='categorical_crossentropy',
metrics=['accuracy']
)
model.fit(train_dataset, epochs=10, validation_data=val_dataset)
# Phase 2: バックボーン上位層もファインチューニング(低いLR)
base_model.trainable = True
fine_tune_at = 100 # この層以降を学習可能に
for layer in base_model.layers[:fine_tune_at]:
layer.trainable = False
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5),
loss='categorical_crossentropy',
metrics=['accuracy']
)
model.fit(train_dataset, epochs=20, validation_data=val_dataset)
PyTorchでの転移学習
import torch
import torch.nn as nn
import torchvision.models as models
# ImageNet学習済みEfficientNetをロード
model = models.efficientnet_b0(
weights=models.EfficientNet_B0_Weights.IMAGENET1K_V1
)
# バックボーンの重みを凍結
for param in model.features.parameters():
param.requires_grad = False
# 分類ヘッドをカスタムタスク向けに変更
num_features = model.classifier[1].in_features
model.classifier = nn.Sequential(
nn.Dropout(p=0.2),
nn.Linear(num_features, num_classes)
)
# 最適化(ヘッドのパラメータのみ更新)
optimizer = torch.optim.Adam(
model.classifier.parameters(),
lr=1e-3
)
# 学習ループ
for epoch in range(num_epochs):
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
エッジデバイス向けモデルのダウンロードと変換
# TFLite Micro用: Hugging FaceからモデルをDLしてTFLiteに変換
from transformers import AutoFeatureExtractor, TFAutoModelForImageClassification
import tensorflow as tf
# Hugging Faceからモデルをロード
model_name = "google/mobilenet_v2_1.0_224"
feature_extractor = AutoFeatureExtractor.from_pretrained(model_name)
model = TFAutoModelForImageClassification.from_pretrained(model_name)
# TFLiteに変換(INT8量子化込み)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
# 保存
with open('mobilenet_v2_int8.tflite', 'wb') as f:
f.write(tflite_model)
print(f"モデルサイズ: {len(tflite_model)/1024:.1f}KB")
用途・ユースケース
少量データからの高速モデル開発
工場の新製品向け外観検査システムを例に挙げます。新製品のデータは少量(数十〜数百枚)しか収集できない場合でも、ImageNet学習済みモデルの転移学習を使えば高精度な検査モデルを構築できます。
ゼロから学習: 数万枚のデータが必要、学習時間数十時間
転移学習: 100枚程度のデータで可能、学習時間数分〜数時間
精度: ほぼ同等(90%以上)
エッジデバイスでの特徴量抽出
学習済みモデルのバックボーンを特徴量抽出器として固定し、新しいヘッドをエッジで使うアーキテクチャも有効です。
クラウド(学習時):
大規模学習済みモデル → 転移学習 → 軽量モデル(量子化済み)
↓
エッジデバイス(推論時):
センサー/カメラ入力 → 軽量TFLiteモデル → 結果出力
ドメイン別の主要学習済みモデル
| ドメイン | 代表的モデル | 特徴 |
|---|---|---|
| 画像分類 | MobileNetV3, EfficientNet | 軽量・高精度 |
| 物体検出 | YOLOv8n, SSD MobileNet | エッジ向け |
| 音声認識 | Whisper-tiny, wav2vec2 | 多言語対応 |
| 自然言語 | BERT-tiny, DistilBERT | 圧縮版NLPモデル |
| 姿勢推定 | MoveNet-Lightning | Google開発、超高速 |
| 深度推定 | MiDaS-small | 単眼深度推定 |
実装・開発のポイント
モデル選定のチェックリスト
エッジデバイス向け学習済みモデルを選ぶ際の判断基準をまとめます。
| 確認項目 | 内容 |
|---|---|
| ライセンス | 商用利用可能か(Apache 2.0、MIT、研究目的のみ等) |
| モデルサイズ | デバイスのフラッシュ容量に収まるか |
| RAM要件 | テンソルアリーナがデバイスのRAMに収まるか |
| 量子化対応 | INT8量子化で精度が維持されるか |
| ハードウェア対応 | ターゲットデバイスのNPU/DSPで動作可能か |
| 推論速度 | リアルタイム要件を満たすか |
| 入力形式 | 前処理コストが許容範囲か |
モデルのライセンス確認
学習済みモデルには様々なライセンスが存在します。商用製品への組み込みには特に注意が必要です。
ライセンス種別と利用可能性:
Apache 2.0 → 商用利用OK、帰属表示必要
MIT License → 商用利用OK、自由度高い
CC-BY 4.0 → 帰属表示必要
CC-BY-NC 4.0 → 非商用のみ(商用製品に使用不可)
研究目的のみ → 商用製品への組み込み不可
独自ライセンス → 要確認
カスタムデータでの評価
def evaluate_pretrained_model(model_path, test_images, test_labels,
input_size=(224, 224)):
"""学習済みモデルをカスタムデータで評価"""
import tflite_runtime.interpreter as tflite
import numpy as np
interpreter = tflite.Interpreter(model_path=model_path)
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
correct = 0
inference_times = []
for image, label in zip(test_images, test_labels):
# 前処理
resized = cv2.resize(image, input_size)
normalized = resized.astype(np.float32) / 127.5 - 1.0
input_data = normalized[np.newaxis]
# 推論
import time
start = time.perf_counter()
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
elapsed = time.perf_counter() - start
inference_times.append(elapsed * 1000) # ms
# 結果
output = interpreter.get_tensor(output_details[0]['index'])
pred = np.argmax(output[0])
if pred == label:
correct += 1
accuracy = correct / len(test_labels)
avg_time = np.mean(inference_times)
print(f"精度: {accuracy*100:.2f}%, 平均推論時間: {avg_time:.1f}ms")
return accuracy, avg_time
他技術との比較
| アプローチ | 必要データ量 | 学習コスト | 精度 | 柔軟性 |
|---|---|---|---|---|
| ゼロから学習 | 大量(万〜億) | 非常に高い | 高い | 最高 |
| 転移学習 | 少量(百〜千) | 低い | 高い | 高い |
| ファインチューニング | 中量(千〜万) | 中程度 | 最高(ドメイン特化) | 高い |
| そのまま使用 | 不要 | なし | 汎用タスクのみ | 低い |
学習済みモデルはエッジAI開発を大幅に民主化する技術です。量子化・プルーニング・TensorFlow Lite・ONNXなどと組み合わせることで、限られたリソースのマイコンや組み込みボードにも高精度AIを搭載できます。データセットの選択とともに、学習済みモデルの選定は組み込みAIプロジェクトの成否を左右する重要な設計判断となります。