0
1

PythonのCaffeを使った深層学習の初心者向けチュートリアル

Posted at

はじめに

Caffeは深層学習のためのオープンソースフレームワークです。画像認識や物体検出などのタスクに広く使われています。この記事では、PythonでCaffeを使う方法を段階的に解説していきます。

第1章: Caffeのインストール

まずはCaffeをインストールしましょう。Ubuntuを使用している場合、以下のコマンドでインストールできます。

sudo apt-get update
sudo apt-get install -y python-dev python-pip
sudo pip install numpy scipy
sudo apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
sudo apt-get install -y --no-install-recommends libboost-all-dev
sudo apt-get install -y libatlas-base-dev
sudo apt-get install -y libgflags-dev libgoogle-glog-dev liblmdb-dev

git clone https://github.com/BVLC/caffe
cd caffe
cp Makefile.config.example Makefile.config
make all
make test
make runtest
make pycaffe

第2章: Caffeの基本概念

Caffeでは、ニューラルネットワークを「レイヤー」の積み重ねとして定義します。主要な概念は以下の通りです:

  • Blob: データを保持する4次元配列
  • Layer: ネットワークの基本構成要素
  • Net: レイヤーを組み合わせたネットワーク全体
  • Solver: 学習のパラメータを管理

第3章: 最初のCaffeモデル

簡単な例として、MNISTデータセットを使った手書き数字認識モデルを作成しましょう。

import caffe
import numpy as np

# ネットワークの定義
net = caffe.Net('mnist_net.prototxt', caffe.TEST)

# データの準備
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
transformer.set_raw_scale('data', 255)

# 画像の読み込みと前処理
image = caffe.io.load_image('test_image.jpg', color=False)
transformed_image = transformer.preprocess('data', image)

# 推論
net.blobs['data'].data[...] = transformed_image
output = net.forward()

# 結果の表示
print(output['prob'][0])

第4章: データの準備

Caffeで学習を行うには、データを適切な形式に変換する必要があります。LMDBやHDF5形式がよく使われます。

import caffe
import lmdb
import numpy as np
from caffe.proto import caffe_pb2

# LMDBデータベースの作成
lmdb_env = lmdb.open('mnist_train_lmdb', map_size=int(1e12))

with lmdb_env.begin(write=True) as lmdb_txn:
    for i in range(len(X_train)):
        datum = caffe_pb2.Datum()
        datum.channels = X_train[i].shape[2]
        datum.height = X_train[i].shape[0]
        datum.width = X_train[i].shape[1]
        datum.data = X_train[i].tobytes()
        datum.label = int(y_train[i])
        str_id = '{:08}'.format(i)
        lmdb_txn.put(str_id.encode('ascii'), datum.SerializeToString())

第5章: ネットワークの定義

Caffeでは、ネットワークの構造をprototxtファイルで定義します。以下は簡単な畳み込みニューラルネットワークの例です。

name: "LeNet"
layer {
  name: "data"
  type: "Input"
  top: "data"
  input_param { shape: { dim: 64 dim: 1 dim: 28 dim: 28 } }
}
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  convolution_param {
    num_output: 20
    kernel_size: 5
    stride: 1
  }
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "ip1"
  type: "InnerProduct"
  bottom: "pool1"
  top: "ip1"
  inner_product_param {
    num_output: 500
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "ip1"
  top: "ip1"
}
layer {
  name: "ip2"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  inner_product_param {
    num_output: 10
  }
}
layer {
  name: "prob"
  type: "Softmax"
  bottom: "ip2"
  top: "prob"
}

第6章: Solverの設定

Solverは学習のパラメータを管理します。以下はSolverの設定例です。

net: "train_val.prototxt"
test_iter: 100
test_interval: 500
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
lr_policy: "step"
gamma: 0.1
stepsize: 5000
display: 100
max_iter: 10000
snapshot: 5000
snapshot_prefix: "lenet"
solver_mode: GPU

第7章: 学習の実行

Pythonを使ってCaffeモデルを学習させる方法を見ていきましょう。

import caffe

solver = caffe.get_solver('solver.prototxt')
solver.solve()

# または、既存のモデルから学習を再開する場合
solver.restore('snapshot.solverstate')
solver.solve()

第8章: ファインチューニング

既存のモデルを新しいタスクに適応させるファインチューニングも、Caffeで簡単に行えます。

import caffe

# 事前学習済みモデルの読み込み
net = caffe.Net('model.prototxt', 'model.caffemodel', caffe.TRAIN)

# 最後の層の重みをリセット
net.params['fc8'][0].data[...] = 0
net.params['fc8'][1].data[...] = 0

# ソルバーの設定
solver = caffe.SGDSolver('solver.prototxt')
solver.net.copy_from('model.caffemodel')

# ファインチューニングの実行
solver.solve()

第9章: データ拡張

学習データを増やすデータ拡張は、モデルの汎化性能を向上させる重要な技術です。

import caffe
import numpy as np

def augment_data(image):
    # 回転
    angle = np.random.uniform(-10, 10)
    rotated = caffe.io.rotate_image(image, angle)
    
    # フリップ
    if np.random.random() > 0.5:
        flipped = caffe.io.flip_image(rotated)
    else:
        flipped = rotated
    
    # スケーリング
    scale = np.random.uniform(0.9, 1.1)
    scaled = caffe.io.resize_image(flipped, (int(image.shape[0]*scale), int(image.shape[1]*scale)))
    
    return scaled

# データ拡張の適用
augmented_images = [augment_data(img) for img in original_images]

第10章: 特徴抽出

学習済みモデルを使って、画像から特徴を抽出する方法を見ていきましょう。

import caffe
import numpy as np

# モデルの読み込み
net = caffe.Net('deploy.prototxt', 'model.caffemodel', caffe.TEST)

# 画像の前処理
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
transformer.set_mean('data', np.load('mean.npy').mean(1).mean(1))
transformer.set_raw_scale('data', 255)
transformer.set_channel_swap('data', (2,1,0))

# 画像の読み込みと変換
image = caffe.io.load_image('image.jpg')
transformed_image = transformer.preprocess('data', image)

# 特徴抽出
net.blobs['data'].data[...] = transformed_image
output = net.forward()
features = net.blobs['fc7'].data[0]

print(features)

第11章: 可視化

学習の進捗や結果を可視化することは、モデルの理解と改善に役立ちます。

import caffe
import numpy as np
import matplotlib.pyplot as plt

# 学習曲線の可視化
train_loss = np.load('train_loss.npy')
test_accuracy = np.load('test_accuracy.npy')

plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.plot(train_loss)
plt.title('Training Loss')
plt.subplot(1, 2, 2)
plt.plot(test_accuracy)
plt.title('Test Accuracy')
plt.show()

# フィルタの可視化
net = caffe.Net('deploy.prototxt', 'model.caffemodel', caffe.TEST)
filters = net.params['conv1'][0].data
n_filters, n_channels, height, width = filters.shape
fig = plt.figure(figsize=(n_filters, n_channels))
for i in range(n_filters):
    for j in range(n_channels):
        ax = fig.add_subplot(n_channels, n_filters, i*n_channels + j + 1)
        ax.imshow(filters[i, j], cmap='gray')
        ax.axis('off')
plt.show()

第12章: モデルの評価

学習したモデルの性能を評価する方法を見ていきましょう。

import caffe
import numpy as np
from sklearn.metrics import accuracy_score, confusion_matrix

# モデルの読み込み
net = caffe.Net('deploy.prototxt', 'model.caffemodel', caffe.TEST)

# テストデータの準備
X_test, y_test = load_test_data()  # テストデータを読み込む関数

# 予測
predictions = []
for image in X_test:
    net.blobs['data'].data[...] = image
    output = net.forward()
    pred = output['prob'].argmax()
    predictions.append(pred)

# 精度の計算
accuracy = accuracy_score(y_test, predictions)
print(f'Accuracy: {accuracy}')

# 混同行列の作成
cm = confusion_matrix(y_test, predictions)
print('Confusion Matrix:')
print(cm)

第13章: モデルの保存と読み込み

学習したモデルを保存し、後で再利用する方法を説明します。

import caffe

# モデルの保存
net = caffe.Net('train_val.prototxt', 'model.caffemodel', caffe.TRAIN)
net.save('new_model.caffemodel')

# モデルの読み込み
net = caffe.Net('deploy.prototxt', 'new_model.caffemodel', caffe.TEST)

第14章: GPUの利用

Caffeは、GPUを使用して計算を高速化できます。

import caffe

# GPUモードの設定
caffe.set_mode_gpu()
caffe.set_device(0)  # GPUデバイス番号

# 以降、通常通りCaffeを使用
net = caffe.Net('deploy.prototxt', 'model.caffemodel', caffe.TEST)

第15章: デプロイメント

学習したモデルを実際のアプリケーションで使用する方法を見ていきます。

import caffe
import numpy as np
from flask import Flask, request, jsonify

app = Flask(__name__)

# モデルの読み込み
net = caffe.Net('deploy.prototxt', 'model.caffemodel', caffe.TEST)

@app.route('/predict', methods=['POST'])
def predict():
    # 画像データの受け取り
    image_data = request.files['image'].read()
    image = caffe.io.load_image(image_data)
    
    # 前処理
    transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
    transformer.set_transpose('data', (2,0,1))
    transformer.set_raw_scale('data', 255)
    transformed_image = transformer.preprocess('data', image)
    
    # 推論
    net.blobs['data'].data[...] = transformed_image
    output = net.forward()
    
    # 結果の返送
    result = {'class': int(output['prob'].argmax()), 'probability': float(output['prob'].max())}
    return jsonify(result)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

以上で、PythonでのCaffe使用方法について、15章にわたって詳しく解説しました。各章で基本的な概念から応用まで幅広くカバーしていますので、Caffeを使った深層学習の実践に役立つことでしょう。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1