初心者向けの深局孊習ニュヌラルネットワヌクの埮調敎

はじめに


ディヌプラヌニングテクノロゞヌをすばやく理解できるように蚭蚈されたシリヌズの3番目のそしお最埌の蚘事を玹介したす。 MNIST手曞き数字の分類ずCIFAR-10小さな画像の10クラスぞの分類飛行機、車、鳥、猫、鹿、犬、カ゚ルの適切なパフォヌマンスを埗るために、基本原則から重芁な機胜に移行したす、銬、船、トラック。


前回、 畳み蟌みニュヌラルネットワヌクモデルを芋お、ドロップアりトず呌ばれる単玔だが効果的な正則化方法を䜿甚しお、Keras深局孊習ネットワヌクフレヌムワヌクを䜿甚しお78.6の粟床を迅速に達成できるこずを瀺したした。

これで、最も興味深いタスクにディヌプラヌニングを適甚するために必芁な基本スキルが埗られたした䟋倖は非線圢時系列を凊理するタスクであり、この考慮事項はこのガむドの範囲を超えおおり、どのリカレントニュヌラルネットワヌク RNNが通垞望たしい゜リュヌションです。このガむドの最埌の郚分には、非垞に重芁ですが、そのような蚘事では芋萜ずされがちなのは、基本的なモデルよりも䞀般化するようにモデルを教えるためのモデルの埮調敎の秘andです あなたが始めたした。

マニュアルのこの郚分は、サむクルの最初ず2番目の蚘事に粟通しおいるこずを前提ずしおいたす。

ハむパヌパラメヌタヌのセットアップずベヌスモデル


通垞、ニュヌラルネットワヌクの開発プロセスは、このような問題を解決するために既に正垞に䜿甚されおいるアヌキテクチャを盎接䜿甚するか、以前は良い結果をもたらしたハむパヌパラメヌタヌを䜿甚しお、単玔なネットワヌクの開発から始たりたす。 最終的には、適切な開始点ずなるパフォヌマンスレベルを達成し、その埌、すべおの固定パラメヌタヌを倉曎し、ネットワヌクから最倧のパフォヌマンスを抜出できるようになるこずを願っおいたす。 このプロセスは、トレヌニングを開始する前にむンストヌルする必芁があるネットワヌクコンポヌネントの倉曎を䌎うため、䞀般にハむパヌパラメヌタヌのチュヌニングず呌ばれたす。

ここで説明する方法は、グラフィックプロセッサがない堎合にCIPAR-10をすばやくプロトタむピングするのが比范的難しいため、CIFAR-10でより具䜓的なメリットを提䟛する可胜性がありたすが、MNISTでのパフォヌマンスの改善に焊点を圓おたす。 もちろん、リ゜ヌスが蚱せば、CIFARでこれらのメ゜ッドを詊しお、暙準のCNNアプロヌチず比范しおどれだけのメリットがあるかを自分で確かめるこずをお勧めしたす。

出発点は、以䞋に瀺す元のCNNです。 䞀郚のコヌドフラグメントが理解できないず思われる堎合は、このシリヌズの前の2぀のパヌトにすべおの基本原則を説明するこずをお勧めしたす。

ベヌスモデルコヌド
from keras.datasets import mnist # subroutines for fetching the MNIST dataset from keras.models import Model # basic class for specifying and training a neural network from keras.layers import Input, Dense, Flatten, Convolution2D, MaxPooling2D, Dropout from keras.utils import np_utils # utilities for one-hot encoding of ground truth values batch_size = 128 # in each iteration, we consider 128 training examples at once num_epochs = 12 # we iterate twelve times over the entire training set kernel_size = 3 # we will use 3x3 kernels throughout pool_size = 2 # we will use 2x2 pooling throughout conv_depth = 32 # use 32 kernels in both convolutional layers drop_prob_1 = 0.25 # dropout after pooling with probability 0.25 drop_prob_2 = 0.5 # dropout in the FC layer with probability 0.5 hidden_size = 128 # there will be 128 neurons in both hidden layers num_train = 60000 # there are 60000 training examples in MNIST num_test = 10000 # there are 10000 test examples in MNIST height, width, depth = 28, 28, 1 # MNIST images are 28x28 and greyscale num_classes = 10 # there are 10 classes (1 per digit) (X_train, y_train), (X_test, y_test) = mnist.load_data() # fetch MNIST data X_train = X_train.reshape(X_train.shape[0], depth, height, width) X_test = X_test.reshape(X_test.shape[0], depth, height, width) X_train = X_train.astype('float32') X_test = X_test.astype('float32') X_train /= 255 # Normalise data to [0, 1] range X_test /= 255 # Normalise data to [0, 1] range Y_train = np_utils.to_categorical(y_train, num_classes) # One-hot encode the labels Y_test = np_utils.to_categorical(y_test, num_classes) # One-hot encode the labels inp = Input(shape=(depth, height, width)) # NB Keras expects channel dimension first # Conv [32] -> Conv [32] -> Pool (with dropout on the pooling layer) conv_1 = Convolution2D(conv_depth, kernel_size, kernel_size, border_mode='same', activation='relu')(inp) conv_2 = Convolution2D(conv_depth, kernel_size, kernel_size, border_mode='same', activation='relu')(conv_1) pool_1 = MaxPooling2D(pool_size=(pool_size, pool_size))(conv_2) drop_1 = Dropout(drop_prob_1)(pool_1) flat = Flatten()(drop_1) hidden = Dense(hidden_size, activation='relu')(flat) # Hidden ReLU layer drop = Dropout(drop_prob_2)(hidden) out = Dense(num_classes, activation='softmax')(drop) # Output softmax layer model = Model(input=inp, output=out) # To define a model, just specify its input and output layers model.compile(loss='categorical_crossentropy', # using the cross-entropy loss function optimizer='adam', # using the Adam optimiser metrics=['accuracy']) # reporting the accuracy model.fit(X_train, Y_train, # Train the model using the training set... batch_size=batch_size, nb_epoch=num_epochs, verbose=1, validation_split=0.1) # ...holding out 10% of the data for validation model.evaluate(X_test, Y_test, verbose=1) # Evaluate the trained model on the test set! 


トレヌニング䞀芧
 Train on 54000 samples, validate on 6000 samples Epoch 1/12 54000/54000 [==============================] - 4s - loss: 0.3010 - acc: 0.9073 - val_loss: 0.0612 - val_acc: 0.9825 Epoch 2/12 54000/54000 [==============================] - 4s - loss: 0.1010 - acc: 0.9698 - val_loss: 0.0400 - val_acc: 0.9893 Epoch 3/12 54000/54000 [==============================] - 4s - loss: 0.0753 - acc: 0.9775 - val_loss: 0.0376 - val_acc: 0.9903 Epoch 4/12 54000/54000 [==============================] - 4s - loss: 0.0629 - acc: 0.9809 - val_loss: 0.0321 - val_acc: 0.9913 Epoch 5/12 54000/54000 [==============================] - 4s - loss: 0.0520 - acc: 0.9837 - val_loss: 0.0346 - val_acc: 0.9902 Epoch 6/12 54000/54000 [==============================] - 4s - loss: 0.0466 - acc: 0.9850 - val_loss: 0.0361 - val_acc: 0.9912 Epoch 7/12 54000/54000 [==============================] - 4s - loss: 0.0405 - acc: 0.9871 - val_loss: 0.0330 - val_acc: 0.9917 Epoch 8/12 54000/54000 [==============================] - 4s - loss: 0.0386 - acc: 0.9879 - val_loss: 0.0326 - val_acc: 0.9908 Epoch 9/12 54000/54000 [==============================] - 4s - loss: 0.0349 - acc: 0.9894 - val_loss: 0.0369 - val_acc: 0.9908 Epoch 10/12 54000/54000 [==============================] - 4s - loss: 0.0315 - acc: 0.9901 - val_loss: 0.0277 - val_acc: 0.9923 Epoch 11/12 54000/54000 [==============================] - 4s - loss: 0.0287 - acc: 0.9906 - val_loss: 0.0346 - val_acc: 0.9922 Epoch 12/12 54000/54000 [==============================] - 4s - loss: 0.0273 - acc: 0.9909 - val_loss: 0.0264 - val_acc: 0.9930 9888/10000 [============================>.] - ETA: 0s [0.026324689089493085, 0.99119999999999997] 


ご芧のずおり、このモデルはテストセットで99.12の粟床を達成しおいたす。 これは、前半で説明したMLPの結果よりわずかに優れおいたすが、ただ成長の䜙地がありたす

このガむドでは、このような「基本的な」ニュヌラルネットワヌクをCNNアヌキテクチャから逞脱するこずなく改善する方法を共有し、埗られるパフォヌマンスゲむンを評䟡したす。

L_2 -正芏化


前の蚘事で、機械孊習の䞻な問題の1぀は、トレヌニングコストの最小化を远求するモデルが䞀般化する胜力を倱った堎合の過剰適合の問題であるず述べたした。


既に述べたように、再トレヌニングをチェックし続ける簡単な方法、 ドロップアりトメ゜ッドがありたす。

しかし、私たちのネットワヌクに適甚できる他のレギュラむザヌがありたす。 おそらく最も人気のあるものは L_2 -正芏化枛量、英語、枛量ずも呌ばれたす。ドロップアりトよりも盎接的な正則化アプロヌチを䜿甚したす。 通垞、再トレヌニングの䞻な原因は、モデルの耇雑さパラメヌタヌの数の点でです。これは、問題を解決するには十分ではなく、トレヌニングセットを利甚できたせん。 ある意味では、レギュララむザヌのタスクは、モデルの耇雑さを軜枛し、パラメヌタヌの数を保持するこずです。 L_2 -正芏化は、最高倀の重みにペナルティを課し 、それらを最小化するこずにより実行されたす L_2 パラメヌタヌλを䜿甚する-normは、トレヌニングセットの損倱を最小化するこずに関しお、ノルムを最小化する優先床を衚す正則化係数です。 ぀たり、各重みωに぀いお、目的関数に远加したす。 \ mathcal {L}\ vec {\ hat {y}}、\ vec {y} 期間 {\ lambda \ over 2} || \ vec {w} || ^ 2 = {\ lambda \ over 2} \ sum_ {i = 1} ^ Ww_i ^ 2 係数œは、パラメヌタωに察するこの項の募配が2λωではなくλωに等しくなるように䜿甚されたす-誀差逆䌝播法を適甚する䟿宜䞊。

適切なλを遞択するこずが非垞に重芁であるこずに泚意しおください。 係数が小さすぎる堎合、正則化の圱響は無芖でき、倧きすぎる堎合、モデルはすべおの重みをリセットしたす。 ここでは、λ= 0.0001を䜿甚したす。 この正芏化メ゜ッドをモデルに远加するには、むンポヌトがもう1぀必芁です。その埌、正芏化を適甚する各レむダヌにW_regularizerパラメヌタヌを远加するだけで十分です。

 from keras.regularizers import l2 # L2-regularisation # ... l2_lambda = 0.0001 # ... # This is how to add L2-regularisation to any Keras layer with weights (eg Convolution2D/Dense) conv_1 = Convolution2D(conv_depth, kernel_size, kernel_size, border_mode='same', W_regularizer=l2(l2_lambda), activation='relu')(inp) 

ネットワヌクの初期化


前の蚘事で芋萜ずした点の1぀は、モデルを構成するレむダヌの重みの初期倀を遞択する原理です。 明らかに、この質問は非垞に重芁です。すべおの重みを0に蚭定するこずは、孊習の重倧な障害になりたす。最初はどの重みもアクティブにならないためです。 間隔±1の倀に重みを割り圓おるこずも、通垞は最適なオプションではありたせん-実際、時にはタスクずモデルの耇雑さに応じおモデルの正しい初期化に䟝存する堎合があり、最高のパフォヌマンスを達成するか、たったく収束したせん。 タスクにそのような極端なものが含たれおいない堎合でも、重みを初期化する適切な方法は、損倱関数を考慮しおモデルパラメヌタヌを事前蚭定するため、モデルの孊習胜力に倧きく圱響したす。

最も興味深い2぀の方法を次に瀺したす。

Xavier初期化メ゜ッド堎合によっおはGlorotのメ゜ッド。 この方法の䞻なアむデアは、 線圢掻性化関数の゚ラヌの前方および埌方䌝搬䞭にレむダヌを通過する信号の通過を単玔化するこずですこの方法は、シグモむド関数でも䞍飜和領域が線圢特性を持぀ため、うたく機胜したす。 重みを蚈算するずき、この方法は、分散が等しい確率分垃均䞀たたは正芏に䟝存したす。 \ mathrm {Var}W= {2 \ over {n_ {in} + n_ {out}}} どこで n_ {in} そしお n_ {out} -前のレむダヌず次のレむダヌのニュヌロンの数。

初期化メ゜ッドGeHeは、Zawierメ゜ッドのバリ゚ヌションであり、 ReLUアクティベヌション関数により適しおいたす。この関数が定矩の半分の領域でれロを返すずいう事実を補正したす。 ぀たり、この堎合 \ mathrm {Var}W= {2 \ over {n_ {in}}}

Zawierの初期化に必芁な分散を取埗するために、重みず入力倀が盞関せず 、 期埅倀がれロであるず仮定しお、線圢ニュヌロンの出力倀の分散バむアス成分なしがどうなるかを考えたす 。

\ mathrm {Var}\ sum_ {i = 1} ^ {n_ {in}} w_ix_i= \ sum_ {i = 1} ^ {n_ {in}} \ mathrm {Var}w_ix_i= \ sum_ {i = 1} ^ {n_ {in}} \ mathrm {Var}W\ mathrm {Var}X= n_ {in} \ mathrm {Var}W\ mathrm {Var}X



したがっお、レむダヌを通過した埌の入力デヌタの分散を維持するには、分散が \ mathrm {Var}W= {1 \ over {n_ {in}}} 。 ゚ラヌを䌝播しお取埗するずきに同じ匕数を適甚できたす \ mathrm {Var}W= {1 \ over {n_ {out}}} 。 通垞、これらの芁件の䞡方を満たすこずはできないため、重みの分散を平均ずしお遞択したす。 \ mathrm {Var}W= {2 \ over {n_ {in} + n_ {out}}} それは、実際には、通垞はうたく機胜したす。

これらの2぀の方法は、出䌚うほずんどの䟋に適しおいたすただし、 盎亀初期化方法も、特にリカレントネットワヌクに関しおは研究に倀したす。 レむダヌの初期化メ゜ッドを指定するこずは難しくありたせん。以䞋で説明するように、 initパラメヌタヌを指定するだけです。 すべおのReLUレむダヌにGeの均䞀な初期化 glorot_uniform を䜿甚し、出力glorot_uniformにGevierの均䞀な初期化 glorot_uniform を䜿甚したす本質的に、ロゞスティック関数を耇数の類䌌デヌタに䞀般化するためです。

 # Add He initialisation to a layer conv_1 = Convolution2D(conv_depth, kernel_size, kernel_size, border_mode='same', init='he_uniform', W_regularizer=l2(l2_lambda), activation='relu')(inp) # Add Xavier initialisation to a layer out = Dense(num_classes, init='glorot_uniform', W_regularizer=l2(l2_lambda), activation='softmax')(drop) 

バッチ正芏化


バッチ正芏化は、2015幎初頭にIoffeずSzegedyによっお提案されたディヌプラヌニングの高速化方法で、arXivで既に560回匕甚されおいたす この方法は、ニュヌラルネットワヌクの効果的な孊習を劚げる次の問題を解決したす。信号がネットワヌクを䌝播するずき、入力で信号を正芏化し、内偎の局を通過しおも、平均ず分散の䞡方によっお倧きく歪む可胜性がありたすこの珟象は内郚共分散シフトず呌ばれたす 、異なるレベルの募配間の深刻な䞍䞀臎に満ちおいたす。 したがっお、より匷力な正則化を䜿甚する必芁があり、それによっお孊習のペヌスが遅くなりたす。

バッチ正芏化は、この問題に察する非垞に簡単な解決策を提䟛したす。期埅倀ず単䜍分散がれロになるように入力デヌタを正芏化したす。 各レむダヌに入る前に正芏化が実行されたす。 ぀たり、トレヌニング䞭はbatch_size䟋を正芏化し、テスト䞭は事前にテストデヌタを衚瀺できないため、トレヌニングセット党䜓に基づいお取埗した統蚈を正芏化したす。 ぀たり、特定のバッチパッケヌゞの期埅倀ず分散を蚈算したす \ mathcal {B} = x_1、...、x_m 次のように

\ mu _ {\ mathcal {B}} = {1 \ over m} \ sum_ {i = 1} ^ mx_i


\ sigma ^ 2 _ {\ mathcal {B}} = {1 \ over m} \ sum_ {i = 1} ^ mx_i-\ mu _ {\ mathcal {B}}^ 2


これらの統蚈的特性を䜿甚しお、バッチ党䜓でれロの期埅倀ず単䜍分散を持぀ようにアクティベヌション関数を倉換したす。

\ hat {x_i} = {x_i- \ mu _ {\ mathcal {B}} \ over \ sqrt {\ sigma _ {\ mathcal {B}} ^ 2+ \ epsilon}}


ここで、ε> 0は、0で陀算するこずを防ぐパラメヌタヌですバッチの暙準偏差が非垞に小さい堎合、たたはれロに等しい堎合でも。 最埌に、最終的なアクティベヌション関数yを取埗するために、正芏化䞭に䞀般化する胜力が倱われないこずを確認する必芁がありたす。元のデヌタにスケヌリングおよびシフト操䜜を適甚したため、正芏化された倀の任意のスケヌリングおよびシフトを蚱可しお最終関数を取埗できたすアクティベヌション

y_i = \ガンマ\ハット{x_i} + \ベヌタ


ここで、βずγは、システムをトレヌニングできるバッチ正芏化のパラメヌタヌですトレヌニングデヌタの募配降䞋法によっお最適化できたす。 この䞀般化は、パッチの正芏化がニュヌラルネットワヌクの入力に盎接適甚するのに圹立぀こずも意味したす。

この方法は、深い畳み蟌みネットワヌクに適甚されるず、ほずんどの堎合、目暙を達成したす-孊習を高速化したす。 さらに、優れたレギュララむザヌである可胜性があり 、トレヌニングのペヌス、パワヌを遞択できたす L_2 -レギュレヌタずドロップアりト堎合によっおは完党に䞍芁です。 ここでの正則化は、特定の䟋のネットワヌクの結果がもはや決定論的ではないずいう事実の結果でありこの結果が埗られたバッチ党䜓に䟝存したす、䞀般化を単玔化したす。

そしお最埌に、メ゜ッドの著者はニュヌロンの掻性化機胜の前に正芏化を正垞に適甚するこずを掚奚しおいたすが、最近の研究では、それがより有甚でない堎合、少なくずも掻性化埌に䜿甚するこずも有益であるこずが瀺されおいたす。これはこのガむドの䞀郚ずしお行いたす。

BatchNormalization 、ネットワヌクにバッチ正芏化を远加するのは非垞に簡単です BatchNormalizationレむダヌがそれを担圓し、いく぀かのパラメヌタを枡したす。最も重芁なパラメヌタはaxis デヌタのどの軞に沿っお統蚈特性が蚈算されたす。 特に、畳み蟌み局で䜜業しおいるずきは、個々のチャネルに沿っお正芏化する方が適切です。したがっお、select axis=1です。

 from keras.layers.normalization import BatchNormalization # batch normalisation # ... inp_norm = BatchNormalization(axis=1)(inp) # apply BN to the input (NB need to rename here) # conv_1 = Convolution2D(...)(inp_norm) conv_1 = BatchNormalization(axis=1)(conv_1) # apply BN to the first conv layer 

トレヌニングセットの拡匵デヌタ拡匵


䞊蚘の方法は䞻にモデル自䜓の埮調敎に関するものですが、特に画像認識タスクに関しおは、 デヌタ調敎オプションを怜蚎するのに圹立ちたす。

ほが同じサむズで、きれいに配眮された手曞きの数字を認識するようにニュヌラルネットワヌクをトレヌニングしたず想像しおください。 ここで、誰かがこのネットワヌクに異なるサむズず傟斜のわずかにシフトした数のテストを䞎えるずどうなるかを想像しおみたしょう。適切なクラスに察する自信が急激に䜎䞋したす。 理想的には、そのような歪みに耐えられるようにネットワヌクをトレヌニングできるず䟿利ですが、モデルはトレヌニングセットの䜕らかの統蚈分析を実行しお掚定する䞀方で、提䟛したサンプルに基づいおのみトレヌニングできたす。

幞いなこずに、この問題の解決策は単玔ですが、特に画像認識タスクでは効果的です。トレヌニング䞭に歪んだバヌゞョンでトレヌニングデヌタを人工的に拡匵したす。 これは次のこずを意味したす。モデルの入力の䟋を蚭定する前に、必芁ず思われるすべおの倉換を適甚し、ネットワヌクがデヌタに䞎える圱響を盎接芳察し、これらに察しお「うたく動䜜する」ように教えたす䟋。 たずえば、MNISTセットからシフト、スケヌリング、ワヌプ、チルトされた数字の䟋を次に瀺したす。



Kerasは、孊習セットを拡匵するための玠晎らしいむンタヌフェヌスであるImageDataGeneratorクラスを提䟛したす。 クラスを初期化しお、画像にどのような倉換を適甚するかを䌝えおから、ゞェネレヌタヌを介しおトレヌニングデヌタを実行し、 fitメ゜ッドを呌び出し、次にflowメ゜ッドを呌び出しお、補充するバッチの継続的に展開するむテレヌタヌを取埗したす。 このむテレヌタを䜿甚しおモデルをトレヌニングする特別なmodel.fit_generatorメ゜ッドもあり、コヌドが倧幅に簡玠化されたす。 小さな欠点がありたすこれはvalidation_splitパラメヌタヌを倱う方法です。぀たり、デヌタの怜蚌サブセットを自分で分離する必芁がありたすが、これには4行のコヌドしか必芁ありたせん。

ここでは、ランダムな氎平および垂盎シフトを䜿甚したす。 ImageDataGeneratorは、ランダムな回転、スケヌリング、ワヌピング、ミラヌリングを実行する機胜も提䟛したす。 実際には、このように拡倧された手曞きの数字に出䌚う可胜性は䜎いため、これらの倉換はすべお、おそらく鏡像を陀いお、詊しおみる䟡倀がありたす。

 from keras.preprocessing.image import ImageDataGenerator # data augmentation # ... after model.compile(...) # Explicitly split the training and validation sets X_val = X_train[54000:] Y_val = Y_train[54000:] X_train = X_train[:54000] Y_train = Y_train[:54000] datagen = ImageDataGenerator( width_shift_range=0.1, # randomly shift images horizontally (fraction of total width) height_shift_range=0.1) # randomly shift images vertically (fraction of total height) datagen.fit(X_train) # fit the model on the batches generated by datagen.flow()---most parameters similar to model.fit model.fit_generator(datagen.flow(X_train, Y_train, batch_size=batch_size), samples_per_epoch=X_train.shape[0], nb_epoch=num_epochs, validation_data=(X_val, Y_val), verbose=1) 

アンサンブル


ニュヌラルネットワヌクを䜿甚しおデヌタを3぀以䞊のクラスに分散するずきに芋られる興味深い機胜の1぀は、異なる初期孊習条件の䞋で、1぀のクラスにより簡単に割り圓おられる䞀方で、他のクラスが混乱するこずです。 MNISTを䟋ずしお䜿甚するず、単䞀のニュヌラルネットワヌクでトリプルず5を完党に区別できるこずがわかりたすが、7からナニットを正しく分離する方法は孊習したせんが、逆は別のネットワヌクから分割する堎合です。

この䞍䞀臎は、統蚈アンサンブルの方法を䜿甚しお凊理できたす。1぀のネットワヌクを配眮し、異なる初期倀でそのコピヌを耇数構築し、同じ入力デヌタで平均結果を蚈算したす。 ここでは、3぀の個別のモデルを構築したす。 それらの違いは、Kerasに組み蟌たれた図圢匏で簡単に衚すこずができたす。

コアネットワヌク

アンサンブル

繰り返しになりたすが、Kerasでは、最小限のコヌドを远加するだけで蚈画を実装できたす。最埌のmergeレむダヌで結果を組み合わせお、モデルのコンポヌネントをルヌプで構築する方法をたずめたす。

 from keras.layers import merge # for merging predictions in an ensemble # ... ens_models = 3 # we will train three separate models on the data # ... inp_norm = BatchNormalization(axis=1)(inp) # Apply BN to the input (NB need to rename here) outs = [] # the list of ensemble outputs for i in range(ens_models): # conv_1 = Convolution2D(...)(inp_norm) # ... outs.append(Dense(num_classes, init='glorot_uniform', W_regularizer=l2(l2_lambda), activation='softmax')(drop)) # Output softmax layer out = merge(outs, mode='ave') # average the predictions to obtain the final output 

早期停止


ここで、ハむパヌパラメヌタの最適化のより広い分野ぞの導入ずしお、別の方法を説明したす。 これたで、トレヌニングの進捗状況を監芖するためだけに怜蚌枈みのデヌタセットを䜿甚したしたが、これは間違いなく合理的ではありたせんこのデヌタは建蚭的な目的には䜿甚されないため。 実際、怜蚌セットは、ネットワヌクハむパヌパラメヌタヌ深さ、ニュヌロン/栞の数、正則化パラメヌタヌなどを評䟡するための基瀎ずしお䜿甚できたす。 ネットワヌクがハむパヌパラメヌタヌのさたざたな組み合わせで駆動され、怜蚌セットでのパフォヌマンスに基づいお決定が行われるこずを想像しおください。 最終的にハむパヌパラメヌタを決定する前に、テストセットに぀いお䜕も知る必芁がないこずに泚意しおください。 そうしないず、テストセットの兆候が孊習プロセスに無意識に流れ蟌んでしたいたす。 この原則は、機械孊習の黄金埋ずも呌ばれ、倚くの初期のアプロヌチで違反されおいたす。

おそらく、怜蚌セットを䜿甚する最も簡単な方法は、 早期停止ず呌ばれる手順を䜿甚しお「 時代 」サむクルの数を蚭定するこずです。特定の時代パラメヌタの忍耐で損倱が枛少し始めない堎合は、孊習プロセスを停止したす。 デヌタセットは比范的小さく、すぐに飜和するため、忍耐力を5゚ポックに蚭定し、゚ポックの最倧数を50に増やしたすこの数に達するこずはほずんどありたせん。

早期停止メカニズムは、 コヌルバック関数のEarlyStoppingクラスを通じおKerasに実装されおいたす。 コヌルバック関数は、 fitたたはfit_generator枡されるcallbacksパラメヌタヌを䜿甚しお、各トレヌニング゚ポック埌にfit_generator 。 い぀ものように、すべおが非垞にコンパクトです。プログラムは1行のコヌドで成長したす。

 from keras.callbacks import EarlyStopping # ... num_epochs = 50 # we iterate at most fifty times over the entire training set # ... # fit the model on the batches generated by datagen.flow()---most parameters similar to model.fit model.fit_generator(datagen.flow(X_train, Y_train, batch_size=batch_size), samples_per_epoch=X_train.shape[0], nb_epoch=num_epochs, validation_data=(X_val, Y_val), verbose=1, callbacks=[EarlyStopping(monitor='val_loss', patience=5)]) # adding early stopping 

コヌドを芋せおください


䞊蚘の6぀の最適化手法を適甚するず、ニュヌラルネットワヌクのコヌドは次のようになりたす。

コヌド
 from keras.datasets import mnist # subroutines for fetching the MNIST dataset from keras.models import Model # basic class for specifying and training a neural network from keras.layers import Input, Dense, Flatten, Convolution2D, MaxPooling2D, Dropout, merge from keras.utils import np_utils # utilities for one-hot encoding of ground truth values from keras.regularizers import l2 # L2-regularisation from keras.layers.normalization import BatchNormalization # batch normalisation from keras.preprocessing.image import ImageDataGenerator # data augmentation from keras.callbacks import EarlyStopping # early stopping batch_size = 128 # in each iteration, we consider 128 training examples at once num_epochs = 50 # we iterate at most fifty times over the entire training set kernel_size = 3 # we will use 3x3 kernels throughout pool_size = 2 # we will use 2x2 pooling throughout conv_depth = 32 # use 32 kernels in both convolutional layers drop_prob_1 = 0.25 # dropout after pooling with probability 0.25 drop_prob_2 = 0.5 # dropout in the FC layer with probability 0.5 hidden_size = 128 # there will be 128 neurons in both hidden layers l2_lambda = 0.0001 # use 0.0001 as a L2-regularisation factor ens_models = 3 # we will train three separate models on the data num_train = 60000 # there are 60000 training examples in MNIST num_test = 10000 # there are 10000 test examples in MNIST height, width, depth = 28, 28, 1 # MNIST images are 28x28 and greyscale num_classes = 10 # there are 10 classes (1 per digit) (X_train, y_train), (X_test, y_test) = mnist.load_data() # fetch MNIST data X_train = X_train.reshape(X_train.shape[0], depth, height, width) X_test = X_test.reshape(X_test.shape[0], depth, height, width) X_train = X_train.astype('float32') X_test = X_test.astype('float32') Y_train = np_utils.to_categorical(y_train, num_classes) # One-hot encode the labels Y_test = np_utils.to_categorical(y_test, num_classes) # One-hot encode the labels # Explicitly split the training and validation sets X_val = X_train[54000:] Y_val = Y_train[54000:] X_train = X_train[:54000] Y_train = Y_train[:54000] inp = Input(shape=(depth, height, width)) # NB Keras expects channel dimension first inp_norm = BatchNormalization(axis=1)(inp) # Apply BN to the input (NB need to rename here) outs = [] # the list of ensemble outputs for i in range(ens_models): # Conv [32] -> Conv [32] -> Pool (with dropout on the pooling layer), applying BN in between conv_1 = Convolution2D(conv_depth, kernel_size, kernel_size, border_mode='same', init='he_uniform', W_regularizer=l2(l2_lambda), activation='relu')(inp_norm) conv_1 = BatchNormalization(axis=1)(conv_1) conv_2 = Convolution2D(conv_depth, kernel_size, kernel_size, border_mode='same', init='he_uniform', W_regularizer=l2(l2_lambda), activation='relu')(conv_1) conv_2 = BatchNormalization(axis=1)(conv_2) pool_1 = MaxPooling2D(pool_size=(pool_size, pool_size))(conv_2) drop_1 = Dropout(drop_prob_1)(pool_1) flat = Flatten()(drop_1) hidden = Dense(hidden_size, init='he_uniform', W_regularizer=l2(l2_lambda), activation='relu')(flat) # Hidden ReLU layer hidden = BatchNormalization(axis=1)(hidden) drop = Dropout(drop_prob_2)(hidden) outs.append(Dense(num_classes, init='glorot_uniform', W_regularizer=l2(l2_lambda), activation='softmax')(drop)) # Output softmax layer out = merge(outs, mode='ave') # average the predictions to obtain the final output model = Model(input=inp, output=out) # To define a model, just specify its input and output layers model.compile(loss='categorical_crossentropy', # using the cross-entropy loss function optimizer='adam', # using the Adam optimiser metrics=['accuracy']) # reporting the accuracy datagen = ImageDataGenerator( width_shift_range=0.1, # randomly shift images horizontally (fraction of total width) height_shift_range=0.1) # randomly shift images vertically (fraction of total height) datagen.fit(X_train) # fit the model on the batches generated by datagen.flow()---most parameters similar to model.fit model.fit_generator(datagen.flow(X_train, Y_train, batch_size=batch_size), samples_per_epoch=X_train.shape[0], nb_epoch=num_epochs, validation_data=(X_val, Y_val), verbose=1, callbacks=[EarlyStopping(monitor='val_loss', patience=5)]) # adding early stopping model.evaluate(X_test, Y_test, verbose=1) # Evaluate the trained model on the test set! 


 Epoch 1/50 54000/54000 [==============================] - 30s - loss: 0.3487 - acc: 0.9031 - val_loss: 0.0579 - val_acc: 0.9863 Epoch 2/50 54000/54000 [==============================] - 30s - loss: 0.1441 - acc: 0.9634 - val_loss: 0.0424 - val_acc: 0.9890 Epoch 3/50 54000/54000 [==============================] - 30s - loss: 0.1126 - acc: 0.9716 - val_loss: 0.0405 - val_acc: 0.9887 Epoch 4/50 54000/54000 [==============================] - 30s - loss: 0.0929 - acc: 0.9757 - val_loss: 0.0390 - val_acc: 0.9890 Epoch 5/50 54000/54000 [==============================] - 30s - loss: 0.0829 - acc: 0.9788 - val_loss: 0.0329 - val_acc: 0.9920 Epoch 6/50 54000/54000 [==============================] - 30s - loss: 0.0760 - acc: 0.9807 - val_loss: 0.0315 - val_acc: 0.9917 Epoch 7/50 54000/54000 [==============================] - 30s - loss: 0.0740 - acc: 0.9824 - val_loss: 0.0310 - val_acc: 0.9917 Epoch 8/50 54000/54000 [==============================] - 30s - loss: 0.0679 - acc: 0.9826 - val_loss: 0.0297 - val_acc: 0.9927 Epoch 9/50 54000/54000 [==============================] - 30s - loss: 0.0663 - acc: 0.9834 - val_loss: 0.0300 - val_acc: 0.9908 Epoch 10/50 54000/54000 [==============================] - 30s - loss: 0.0658 - acc: 0.9833 - val_loss: 0.0281 - val_acc: 0.9923 Epoch 11/50 54000/54000 [==============================] - 30s - loss: 0.0600 - acc: 0.9844 - val_loss: 0.0272 - val_acc: 0.9930 Epoch 12/50 54000/54000 [==============================] - 30s - loss: 0.0563 - acc: 0.9857 - val_loss: 0.0250 - val_acc: 0.9923 Epoch 13/50 54000/54000 [==============================] - 30s - loss: 0.0530 - acc: 0.9862 - val_loss: 0.0266 - val_acc: 0.9925 Epoch 14/50 54000/54000 [==============================] - 31s - loss: 0.0517 - acc: 0.9865 - val_loss: 0.0263 - val_acc: 0.9923 Epoch 15/50 54000/54000 [==============================] - 30s - loss: 0.0510 - acc: 0.9867 - val_loss: 0.0261 - val_acc: 0.9940 Epoch 16/50 54000/54000 [==============================] - 30s - loss: 0.0501 - acc: 0.9871 - val_loss: 0.0238 - val_acc: 0.9937 Epoch 17/50 54000/54000 [==============================] - 30s - loss: 0.0495 - acc: 0.9870 - val_loss: 0.0246 - val_acc: 0.9923 Epoch 18/50 54000/54000 [==============================] - 31s - loss: 0.0463 - acc: 0.9877 - val_loss: 0.0271 - val_acc: 0.9933 Epoch 19/50 54000/54000 [==============================] - 30s - loss: 0.0472 - acc: 0.9877 - val_loss: 0.0239 - val_acc: 0.9935 Epoch 20/50 54000/54000 [==============================] - 30s - loss: 0.0446 - acc: 0.9885 - val_loss: 0.0226 - val_acc: 0.9942 Epoch 21/50 54000/54000 [==============================] - 30s - loss: 0.0435 - acc: 0.9890 - val_loss: 0.0218 - val_acc: 0.9947 Epoch 22/50 54000/54000 [==============================] - 30s - loss: 0.0432 - acc: 0.9889 - val_loss: 0.0244 - val_acc: 0.9928 Epoch 23/50 54000/54000 [==============================] - 30s - loss: 0.0419 - acc: 0.9893 - val_loss: 0.0245 - val_acc: 0.9943 Epoch 24/50 54000/54000 [==============================] - 30s - loss: 0.0423 - acc: 0.9890 - val_loss: 0.0231 - val_acc: 0.9933 Epoch 25/50 54000/54000 [==============================] - 30s - loss: 0.0400 - acc: 0.9894 - val_loss: 0.0213 - val_acc: 0.9938 Epoch 26/50 54000/54000 [==============================] - 30s - loss: 0.0384 - acc: 0.9899 - val_loss: 0.0226 - val_acc: 0.9943 Epoch 27/50 54000/54000 [==============================] - 30s - loss: 0.0398 - acc: 0.9899 - val_loss: 0.0217 - val_acc: 0.9945 Epoch 28/50 54000/54000 [==============================] - 30s - loss: 0.0383 - acc: 0.9902 - val_loss: 0.0223 - val_acc: 0.9940 Epoch 29/50 54000/54000 [==============================] - 31s - loss: 0.0382 - acc: 0.9898 - val_loss: 0.0229 - val_acc: 0.9942 Epoch 30/50 54000/54000 [==============================] - 31s - loss: 0.0379 - acc: 0.9900 - val_loss: 0.0225 - val_acc: 0.9950 Epoch 31/50 54000/54000 [==============================] - 30s - loss: 0.0359 - acc: 0.9906 - val_loss: 0.0228 - val_acc: 0.9943 10000/10000 [==============================] - 2s [0.017431972888592554, 0.99470000000000003] 

99.47% , 99.12%. , , MNIST, . CIFAR-10, , .

: , , , , , , , ( 99.79% MNIST).

おわりに


この蚘事では、我々は以前の蚘事で説明したニュヌラルネットワヌクの埮調敎のための6぀のレセプションを芋

L_2-regulyariatsiya
初期化
バッチ正芏化
トレヌニングセットの拡匵
Ensembleメ゜ッド
アヌリヌストップ

Kerasディヌプコンボリュヌションネットワヌクに正垞に適甚され、MNISTの粟床が倧幅に向䞊し、90行未満のコヌドで枈みたした。

これがシリヌズの最埌の蚘事でした。ここず前の2぀の郚分を読むこずができたす。

あなたの知識が、必芁なリ゜ヌスず組み合わせるこずで、ディヌプラヌニングネットワヌクで最もクヌルな゚ンゞニアになるためのむンセンティブになるこずを願っおいたす。

よろしくお願いしたす

ああ、仕事に来おくれたせんか :)
wunderfund.ioは、 高頻床アルゎリズム取匕を扱う若い財団です。 高頻床取匕は、䞖界䞭の最高のプログラマヌず数孊者による継続的な競争です。 私たちに参加するこずで、あなたはこの魅力的な戊いの䞀郚になりたす。

熱心な研究者やプログラマヌ向けに、興味深く耇雑なデヌタ分析ず䜎遅延の開発タスクを提䟛しおいたす。 柔軟なスケゞュヌルず官僚䞻矩がないため、意思決定が迅速に行われ、実斜されたす。

チヌムに参加 wunderfund.io

Source: https://habr.com/ru/post/J315476/


All Articles