SPP-net(Spatial pyramid pooling)層の解説


 

目次

1 SPP-netの概要
1.1 SPP-netとは
1.2 SPP-net定義
2. 実験
2.1 環境構築
2.2 データロード
2.3 データ前処理
2.4 SPP-netのモデル作成
2.5 モデル評価

 

1 Spatial pyramid pooling層の概要

1.1 Spatial pyramid pooling層とは

SPP-netは、可変サイズの画像を入力出来るように分類とオブジェクト検出のニューラルネットワークです。

CNNには、通常固定の入力画像サイズが必要です。これにより、入力画像のアスペクト比とスケールの両方が制限されます。現在の方法では、トリミングまたは画像のリサイズをして、入力画像を固定サイズに合わせます。

SPP-netは最後の畳み込み層の上にSPP層を追加します。 SPP層はサイズをプーリングして、固定長の出力を生成し、全結合層を出力します。

1.2 Spatial pyramid pooling定義

これは通常、全結合ニューラルネットワークレイヤーなどの一定の入力するレイヤーの前に利用します。

tfa.layers.SpatialPyramidPooling2D(
bins: Union[Iterable[int], Iterable[Iterable[int]]],
data_format=None,
*args,
**kwargs
)

入力形状:

data_format =’channels_last’の場合:形状(batch_size、height、width、channels)の4Dテンソルです。

data_format =’channels_first’の場合:形状(batch_size、channels、height、width)の4Dテンソルです。

 

論文:https://arxiv.org/pdf/1406.4729.pdf

TensorFlow: https://www.tensorflow.org/addons/api_docs/python/tfa/layers/SpatialPyramidPooling2D

Pytorch: https://pypi.org/project/pytorch-pyramid-pooling/

 

2. 実験

2.1 環境構築

Tensorflowのaddonsをインストールします。

%%bash

pip3 install git+https://github.com/tensorflow/addons

 

ライブラリのインポート

import tensorflow as tf

from tensorflow.keras.layers import Conv2D, MaxPool2D, BatchNormalization, Flatten, Dense, Activation, Dropout, Input

from tensorflow_addons.layers import SpatialPyramidPooling2D

 

from keras.datasets import cifar10

from keras.utils import np_utils

from keras.models import Model

from keras.callbacks import EarlyStopping

 

from sklearn.model_selection import KFold

from sklearn.model_selection import train_test_split

 

import matplotlib.pyplot as plt

 

2.2 データロード

# Splite train and test data

(X_train, y_train), (X_test, y_test) = cifar10.load_data()

 

# setting class names

class_names=[‘airplane’, ‘automobile’ ,’bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’]

 

データの確認

# show sample image

 

def show_img (img_no):

plt.imshow(X_train[img_no])

plt.grid(False)

plt.xticks([])

plt.yticks([])

plt.xlabel(“Label: ” + str(y_train[img_no][0])+ ” ” + class_names[y_train[img_no][0]])

plt.show()

 

show_img(1)

 

2.3 データ前処理

データを正規化します。

# Normalize

X_train=X_train/255.0

X_test=X_test/255.0

y_train = np_utils.to_categorical(y_train)

 

print(‘X_train shape:’, X_train.shape)

print(‘X_test shape:’, X_test.shape)

X_train shape: (50000, 32, 32, 3)

X_test shape: (10000, 32, 32, 3)

 

2.4 SPP-netのモデル作成

# Spatial Pyramid Pooling Network

 

input_layer = Input((None, None, 3))

x = input_layer

 

x = Conv2D(64, (3, 3), activation=’relu’, padding=’same’, name=’block1_conv1′)(x)

x = Conv2D(64, (3, 3), activation=’relu’, padding=’same’, name=’block1_conv2′)(x)

x = BatchNormalization()(x)

x = MaxPool2D((2, 2), strides=(2, 2), padding=’same’, name=’block1_maxpool’)(x)

 

x = Conv2D(128, (3, 3), activation=’relu’, padding=’same’, name=’block2_conv1′)(x)

x = Conv2D(128, (3, 3), activation=’relu’, padding=’same’, name=’block2_conv2′)(x)

x = BatchNormalization()(x)

 

x = SpatialPyramidPooling2D([1, 3, 5])(x)

 

x = Flatten(name=’flatten’)(x)

 

x = Dense(units=1024, activation=’relu’, name=’fc1′)(x)

x = Dense(units=10, activation=’softmax’, name=’predictions’)(x)

 

SPP_model = Model(inputs=input_layer, outputs=x)

SPP_model.compile(loss=’categorical_crossentropy’, metrics=[‘acc’])

 

print(SPP_model.summary())

Model: “model”

_________________________________________________________________

Layer (type)                Output Shape              Param #

=================================================================

input_1 (InputLayer)        [(None, None, None, 3)]   0

 

block1_conv1 (Conv2D)       (None, None, None, 64)    1792

 

block1_conv2 (Conv2D)       (None, None, None, 64)    36928

 

batch_normalization (BatchN  (None, None, None, 64)   256

ormalization)

 

block1_maxpool (MaxPooling2  (None, None, None, 64)   0

  1. D)

 

block2_conv1 (Conv2D)       (None, None, None, 128)   73856

 

block2_conv2 (Conv2D)       (None, None, None, 128)   147584

 

batch_normalization_1 (Batc  (None, None, None, 128)  512

hNormalization)

 

spatial_pyramid_pooling2d (  (None, 35, 128)          0

SpatialPyramidPooling2D)

 

flatten (Flatten)           (None, 4480)              0

 

fc1 (Dense)                 (None, 1024)              4588544

 

predictions (Dense)         (None, 10)                10250

 

=================================================================

Total params: 4,859,722

Trainable params: 4,859,338

Non-trainable params: 384

_________________________________________________________________

None

 

モデルを学習します。

history = SPP_model.fit(X_train, y_train, batch_size=200,

epochs=20, verbose=1,

validation_data=(X_test, y_test))

Epoch 1/20

250/250 [==============================] – 9s 31ms/step – loss: 1.3008 – acc: 0.5817 – val_loss: 4.0346 – val_acc: 0.1814

Epoch 20/20

250/250 [==============================] – 7s 29ms/step – loss: 0.0186 – acc: 0.9942 – val_loss: 1.8927 – val_acc: 0.7878

 

モデル精度を可視化ます。

# plotting the metrics

 

plt.plot(history.history[‘acc’])

plt.plot(history.history[‘val_acc’])

plt.title(‘model accuracy’)

plt.ylabel(‘accuracy’)

plt.xlabel(‘epoch’)

plt.title(“Spatial Pyramid Pooling Network”)

plt.legend([‘train’, ‘test’], loc=’lower right’)

plt.show()

2.5 モデル評価

テストのデータに対して、78% Accuracyになります。

from sklearn.metrics import accuracy_score

import numpy as np

 

y_pred_p = SPP_model.predict(X_test)

y_pred = np.argmax(y_pred_p,axis=1)

acc_score = accuracy_score(y_test, y_pred)

print(‘Accuracy on test dataset:’, acc_score)

 

Accuracy on test dataset: 0.7878

 

担当者:KW
バンコクのタイ出身 データサイエンティスト
製造、マーケティング、財務、AI研究などの様々な業界にPSI生産管理、在庫予測・最適化分析、顧客ロイヤルティ分析、センチメント分析、SaaS、PaaS、IaaS、AI at the Edge の環境構築などのスペシャリスト