CaffeのSolver設定とネットワーク構造の詳細

Solverの役割と最適化アルゴリズム

深層学習モデルの学習過程では、損失関数を最小化する最適なパラメータを見つける必要があります。CaffeのSolverは、この最適化プロセスを担当します。Solverは、指定された最適化アルゴリズムに基づいてネットワークの重みを更新します。Caffeは以下の6種類の最適化アルゴリズムをサポートしています。

  • Stochastic Gradient Descent (SGD)
  • AdaDelta
  • AdaGrad
  • Adam
  • Nesterov’s Accelerated Gradient
  • RMSprop

これらのアルゴリズムは、Solver設定ファイル(solver.prototxt)内の`type`パラメータで選択します。

Solver設定ファイルの主要なパラメータ

Solverの動作は、`solver.prototxt`ファイルで詳細に制御できます。主なパラメータは以下の通りです。

net: "examples/mnist/lenet_train_test.prototxt"  # 学習するネットワークの定義ファイル
test_iter: 100  # 1回のテストで実行するイテレーション数
test_interval: 500  # テストを実行する間隔(イテレーション数)
base_lr: 0.01  # 基礎学習率
momentum: 0.9  # モーメンタム
type: SGD  # 使用する最適化アルゴリズム
weight_decay: 0.0005  # 重み減衰(L2正則化)
lr_policy: "inv"  # 学習率の調整戦略
gamma: 0.0001  # 学習率調整戦略のパラメータ
power: 0.75  # 学習率調整戦略のパラメータ
display: 100  # 画面にログを表示する間隔
max_iter: 3000  # 最大イテレーション数
snapshot: 500  # スナップショットを保存する間隔
snapshot_prefix: "examples/mnist/lenet"  # スナップショットファイルのプレフィックス
solver_mode: CPU  # 実行モード(GPUまたはCPU)

学習率ポリシー (lr_policy)

`lr_policy`は、学習率をどのように変化させるかを定義します。主な戦略は以下の通りです。

  • fixed: 学習率を`base_lr`で固定します。
  • step: 一定のステップサイズごとに学習率を`gamma`倍します。`stepsize`パラメータが必要です。
  • exp: 各イテレーションで学習率を`gamma`の指数関数的に減少させます。
  • inv: イテレーション数に基づいて学習率を逆比例的に減少させます。`power`パラメータが必要です。
  • multistep: 指定されたイテレーション数で学習率を`gamma`倍します。`stepvalue`パラメータが必要です。
  • poly: 多項式関数に基づいて学習率を減少させます。
  • sigmoid: シグモイド関数に基づいて学習率を減少させます。

Pythonを使用したSolver設定ファイルの生成

以下は、Pythonスクリプトを使用してSolver設定ファイルを生成する例です。この例では、SGDオプティマイザとステップ学習率ポリシーを設定しています。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import caffe.proto.caffe_pb2 as caffe_pb2

# SolverParameterオブジェクトの作成
solver_config = caffe_pb2.SolverParameter()

# ネットワークとテストネットワークの設定
solver_config.train_net = "path/to/train.prototxt"
solver_config.test_net.extend(["path/to/val.prototxt"])

# 学習とテストのパラメータ
solver_config.test_interval = 500
solver_config.test_iter.extend([100])
solver_config.max_iter = 100000

# 最適化アルゴリズムのパラメータ
solver_config.base_lr = 0.001
solver_config.momentum = 0.9
solver_config.weight_decay = 5e-4
solver_config.lr_policy = "step"
solver_config.stepsize = 26067
solver_config.gamma = 0.1

# ログとスナップショットの設定
solver_config.display = 1000
solver_config.snapshot = 10000
solver_config.snapshot_prefix = "path/to/snapshot"

# 実行モードの設定
solver_config.type = "SGD"
solver_config.solver_mode = caffe_pb2.SolverParameter.GPU

# 設定ファイルの書き出し
output_path = "solver_config.prototxt"
with open(output_path, 'w') as f:
    f.write(str(solver_config))

ネットワーク層の詳細

ネットワークの構造は、`prototxt`ファイルで定義されます。主な層タイプとそのパラメータを説明します。

1. データ層 (Data Layer)

データ層は、学習データとラベルを読み込みます。様々なバックエンド(LMDB, HDF5, 画像ファイルなど)をサポートしています。

# LMDBソースを使用する例
layer {
  name: "cifar_train"
  type: "Data"
  top: "data"
  top: "label"
  include { phase: TRAIN }
  transform_param {
    scale: 0.00390625
    mirror: true
    crop_size: 227
  }
  data_param {
    source: "path/to/cifar10_train_lmdb"
    batch_size: 64
    backend: LMDB
  }
}

# HDF5ソースを使用する例
layer {
  name: "hdf5_data"
  type: "HDF5Data"
  top: "data"
  top: "label"
  hdf5_data_param {
    source: "path/to/train_data.h5"
    batch_size: 32
  }
}

2. 畳み込み層 (Convolution Layer)

畳み込み層は、入力データに畳み込み演算を適用して特徴マップを生成します。

layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param { lr_mult: 1 }  # 重みの学習率係数
  param { lr_mult: 2 }  # バイアスの学習率係数
  convolution_param {
    num_output: 32  # 出力チャネル数(フィルタ数)
    kernel_size: 3  # フィルタのサイズ
    stride: 1      # ストライド
    pad: 1        # パディング
    weight_filler { type: "xavier" }  # 重みの初期化方法
    bias_filler { type: "constant" }  # バイアスの初期化方法
  }
}

3. プーリング層 (Pooling Layer)

プーリング層は、空間的な次元を縮小し、計算コストを削減し、位置の変化に対するロバスト性を高めます。

layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX  # プーリング方法(MAXまたはAVE)
    kernel_size: 2  # プーリングウィンドウのサイズ
    stride: 2       # ストライド
  }
}

4. 活性化層 (ReLU Layer)

ReLU層は、非線形性を導入し、ネットワークが複雑なパターンを学習できるようにします。

layer {
  name: "relu1"
  type: "ReLU"
  bottom: "pool1"
  top: "pool1"
}

5. 全結合層 (InnerProduct Layer)

全結合層は、入力をフラットにして線形変換を適用し、分類などのタスクの出力を生成します。

layer {
  name: "fc1"
  type: "InnerProduct"
  bottom: "pool2"
  top: "fc1"
  param { lr_mult: 1 }
  param { lr_mult: 2 }
  inner_product_param {
    num_output: 256  # 出力ユニット数
    weight_filler { type: "xavier" }
    bias_filler { type: "constant" }
  }
}

# テスト時の精度評価層
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "fc2"
  bottom: "label"
  top: "accuracy"
  include { phase: TEST }
}

Python Layer APIを使用したネットワーク定義

Caffeは、Python APIを提供しており、ネットワーク構造をプログラムで定義できます。以下は、LeNetアーキテクチャを生成する例です。

import sys
caffe_root = '/path/to/caffe/'
sys.path.insert(0, caffe_root + 'python')
from caffe import layers as L
from caffe import params as P
import caffe

def create_lenet_network(lmdb_path, batch_size):
    # ネットワーク仕様の作成
    net_spec = caffe.NetSpec()
    
    # データ層の定義
    net_spec.data, net_spec.label = L.Data(batch_size=batch_size, backend=P.Data.LMDB,
                                        source=lmdb_path, transform_param=dict(scale=1./255), ntop=2)
    
    # 畳み込み層とプーリング層の定義
    net_spec.conv1 = L.Convolution(net_spec.data, kernel_size=5, num_output=20, weight_filler=dict(type='xavier'))
    net_spec.pool1 = L.Pooling(net_spec.conv1, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    net_spec.conv2 = L.Convolution(net_spec.pool1, kernel_size=5, num_output=50, weight_filler=dict(type='xavier'))
    net_spec.pool2 = L.Pooling(net_spec.conv2, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    
    # 全結合層と活性化層の定義
    net_spec.fc1 = L.InnerProduct(net_spec.pool2, num_output=500, weight_filler=dict(type='xavier'))
    net_spec.relu1 = L.ReLU(net_spec.fc1, in_place=True)
    net_spec.fc2 = L.InnerProduct(net_spec.relu1, num_output=10, weight_filler=dict(type='xavier'))
    
    # 損失層の定義
    net_spec.loss = L.SoftmaxWithLoss(net_spec.fc2, net_spec.label)
    
    return net_spec.to_proto()

# 訓練用ネットワークの生成と保存
with open('lenet_train.prototxt', 'w') as f:
    f.write(str(create_lenet_network('path/to/mnist_train_lmdb', 64)))

# テスト用ネットワークの生成と保存
with open('lenet_test.prototxt', 'w') as f:
    f.write(str(create_lenet_network('path/to/mnist_test_lmdb', 100)))

タグ: Caffe protobuf 深層学習 solver ネットワーク定義

6月17日 18:00 投稿