Kerasクイックハンド——学習ノート(二)VGG 16ネットワークによるフォント認識


VGG 16ネットワークによるフォント認識
次に遷移学習のアイデアを用いて,VGG 16をテンプレートとしてモデルを構築し,手書きフォントの認識を訓練する.VGG 16モデルはK.SimonyanとA.Zissermanに基づいて書かれたVery Deep Convolutional Networks for Large-Scale Image Recognition,arXiv:1409.1556である.
1、データのインポート
from keras.applications.vgg16 import VGG16  # VGG16  
from keras.layers import Input, Flatten, Dense, Dropout  #              ,        ,     ,      
from keras.models import Model       
from keras.optimizers import SGD  #   SGD    
from keras.datasets import mnist  #      
import cv2  #   opencv,          ,       Channel  。            VGG16        。
import h5py as h5py  #         
import numpy as np  #      !

2、移行ネットワークの作成
1、重みを含まないVGG_を作成する16ネットワークの移行
model_vgg = VGG16(include_top=False, weights='imagenet', input_shape=(224, 224, 3))
model = Flatten(name = 'flatten')(model_vgg.output)
model = Dense(10, activation = "softmax")(model)
model_vgg_mnist = Model(model_vgg.input, model, name='vgg16')

VGG_16()でinclude_top=FalseはVGG 16の最上位層(出力層)の除去を表し、weights='imagenet'はピクチャネットワークを使用する重みを表し、input_shape=(224,224,3)は入力されたピクチャ次元が224 x 224、レイヤが3(RBG)model=Flatten(name='flatten)(model_vgg.output)はmodel_vggモデルの出力レイヤにflatten(全展開)レイヤを追加し、このレイヤをflattenと命名し、結合したモデルをモデルモデルモデル=dense(10,activation="softmax"(model)に返すと、モデルに出力レイヤを追加し、分類数は10個となり、アクティブ化関数はsoftmax model_vgg_mnist=Model(model_vgg.input,model,name='vgg 16’)は、vgg 16と命名された新しいモデルを作成することを意味し、kerasの開発ドキュメントでModel(input=X,output=Y)がmodelであると推測されるvggのinput層を入力層,modelを出力層として新しいネットワークを構築する
ここに見えるのは、すべての1496万個のネットワークウェイト(VGG 16ネットワーク重みに我々が構築した重みを加える)すべて訓練が必要である.これは我々がネットワーク構造を移行したからであるが、VGG 16ネットワーク重みを移行していないからである.移行ネットワーク重みの利点は、ネットワーク重みが再訓練されなくても、最上階に構築された部分を訓練するだけでよいことにある.悪いところは、新しいデータが訓練された重みを適用するとは限らない.訓練された重みのためである重みは他のデータトレーニングに基づいており、データ分布と私たちが関心を持っている問題は全く異なる可能性があります.ここではImageNetにVGGを導入したが,具体的なモデルはVGG 16のフレームワーク上で加工する必要がある.また,ローカルマシンではモデルとデータ全体をメモリに入れて訓練できない可能性が高く,Kill:9のメモリが足りないというエラーが発生した.トレーニングを行う場合は、サンプルを少なくするか、サンプルのロットを例えば32に減らすことをお勧めします.条件があればAWSのEC 2 GPU Instance g 2を使うことができます.2xlarge/g2.8 xlargeでトレーニングを行います.対比として,VGG 16ネットワークの構造と重みを同時に移動することを特徴とする別のモデルを構築した.ここで重要なのは、再訓練を必要としない重みを「冷凍」することです.ここではtrainable=falseというオプションを使用します.なお、ここでは入力次元を(224224,3)と定義しているので、読者がデータジェネレータ反復オブジェクトを使用しない限り、大きなメモリが必要となる.メモリが小さい場合、次元を(11212122,3)に下げることで、32 GBメモリのマシンでもスムーズに動作できる.2、重みを含む移行ネットワークの作成
ishape=224
model_vgg = VGG16(include_top=False, weights='imagenet', input_shape=(ishape, ishape, 3))
for layer in model_vgg.layers:
    layer.trainable = False
model = Flatten()(model_vgg.output)
model = Dense(10, activation="softmax")(model)
model_vgg_mnist_pretrain = Model(model_vgg.input, model, name='vgg_16_pretrain')
model_vgg_mnist_pretrain.summary()

実行結果は次のとおりです.
·····
block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 25088)             0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                250890    
=================================================================
Total params: 14,965,578
Trainable params: 250,890
Non-trainable params: 14,714,688
_________________________________________________________________

私たちは25万個のパラメータを訓練するだけで、前より60倍も少ない!
3、ニューラルネットワークの構築
(1)損失関数の入力
sgd = SGD(lr = 0.05, decay = 1e-5)
model_vgg_mnist_pretrain.compile(loss='categorical_crossentropy', optimizer=sgd, metrics = ['accuracy'])

(2)データプリプロセッシングVGG 16ネットワークの入力層に対する要求のため,OpenCVで画像を32から×32が224になる×224(cv 2.resizeのコマンド)は、白黒画像をRGB画像(cv 2.COLOR_GRAY 2 BGR)に変換し、Keras入力のためにトレーニングデータをテンソル形式に変換する.
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
X_train = [cv2.cvtColor(cv2.resize(i, (ishape, ishape)), cv2.COLOR_GRAY2BGR) for i in X_train[:20000]]
X_train = np.concatenate([arr[np.newaxis] for arr in X_train]).astype("float32")

X_test = [cv2.cvtColor(cv2.resize(i, (ishape, ishape)), cv2.COLOR_GRAY2BGR) for i in X_test[:2000]]
X_test = np.concatenate([arr[np.newaxis] for arr in X_test]).astype("float32")

print("       ",X_train.shape)
print("       ",X_test.shape)

トレーニングセットはもともと6 wありましたが、筆者のメモリ不足でテストセット数を10000に変更し、テストセットデータ量を1000に変更しました
X_train /= 255
X_test /= 255
np.where(X_train[0] != 0)

def tran_y(y):
    y_ohe = np.zeros(10)
    y_ohe[y] = 1
    return y_ohe

Y_train_ohe = np.array([tran_y(Y_train[i]) for i in range(len(Y_train[:20000]))])
Y_test_ohe = np.array([tran_y(Y_test[i]) for i in range(len(Y_test[:2000]))])

モデルの実行
model_vgg_mnist_pretrain.fit(X_train, Y_train_ohe, validation_data = (X_test, Y_test_ohe), epochs = 200, batch_size = 128

メモリ不足!後で補充します!