前のセクションでは、我々は、単に画像の特徴を抽出し、入力、小さな訓練された分類器として、これらの機能を使用して、事前に訓練されたネットワークVGG畳み込みグループを使用します。
この利点は、シンプルで、粗方法、特徴抽出畳み込み部分トレーニングなしです。しかし、欠点は1つが他のモデルは機能は、必ずしもそのタスクに適していない抽出された特定のタスクのために訓練を受けている人がいるということで、2番目は、画像強調ツー・エンドの訓練を使用することができません。
したがって、より一般的な方法は、モデルのトリム+の微調整訓練事前にあり、利点は彼らのニーズに応じて、ネットワークおよび特定のタスクのカスタムネットワーク統合を事前に訓練することができ、加えても、最後に画像向上アプローチを使用することができます研修の終わり。次のように依然としてVGG16例えば、プロセスです。
- ネットワークは、グループ(ベースネットワーク)カスタムネットワークを追加することを訓練してきました。
- フリーズベースのネットワーク、トレーニングカスタムネットワーク。
- ベースのネットワーク、共同訓練のカスタムネットワーク層と解凍をアンフリーズします。
層融解共同訓練する前に、カスタムネットワーク、通常は最初のトレーニングカスタムネットワーク、そうでない場合は、カスタムネットワークの重みのランダム初期化が融解層に大きな誤差信号となり、層の融解損傷以前に学習した表現そのトレーニングようコストが高くなります。
最初のステップ:事前研修モデルが変更されます
##################第一步:在已经训练好的卷积基上添加自定义网络######################
import numpy as np
from keras.applications.vgg16 import VGG16
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
#搭建模型
conv_base = VGG16(include_top=False, input_shape=(150,150,3)) #模型也可以看作一个层
model = Sequential()
model.add(conv_base)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
#model.summary()
ステップ2:フリーズ畳み込みに基づく、カスタムトレーニングネットワーク
######################第二步:冻结卷积基,训练自定义网络##########################
#冻结卷积基,确保结果符合预期。或者用assert len(model.trainable_weights) == 30来验证
print("冻结之前可训练的张量个数:", len(model.trainable_weights)) #结果为30
conv_base.trainable = False
print("冻结之后可训练的张量个数:", len(model.trainable_weights)) #结果为4
#注:只有后两层Dense可以训练,每层一个权重张量和一个偏置张量,所以有4个
#利用图像生成器进行图像增强
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
test_datagen = ImageDataGenerator(rescale=1./255) #验证、测试的图像生成器不能用图像增强
train_dir = r'D:\KaggleDatasets\MyDatasets\dogs-vs-cats-small\train'
validation_dir = r'D:\KaggleDatasets\MyDatasets\dogs-vs-cats-small\validation'
train_generator = train_datagen.flow_from_directory(train_dir,
target_size=(150,150),
batch_size=20,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(validation_dir,
target_size=(150,150),
batch_size=20,
class_mode='binary')
#模型编译和训练,注意修改trainable属性之后需要重新编译,否则修改无效
from keras import optimizers
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
H = model.fit_generator(train_generator,
steps_per_epoch=2000/20,
epochs=30,
validation_data=validation_generator,
validation_steps=1000/20)
30トレーニングエポック後、その結果を図に示します。(上記視覚コード結果)
第三段階:アンフリーズ畳み込み群(第5ブロック)、共同訓練
典型的には、凍結融解操作は、訓練可能な属性モデルまたは層を使用keras。三つのことに注意してください。
- model.trainableは、レイヤ属性、定義が無効である層グローバル属性を分離する属性をlayer.trainable、グローバルです。
- この属性を定義した後、モデルの必要性を有効にするには再コンパイルします。
- conv_baseモデルであるが、それはモデルに基づいて全体の例の層として使用され、従って、層内の所望の深さは、操作をconv_base場合conv_base.layersのmodel.layersを横断するときに、必要が横断する、一つの層としてconv_baseう。
期待に沿って訓練可能な属性を確保するために、通常、コードの一部を使用することができる以下、確認します。(これは理解を容易にするために、主に、コードは、選択的この実行中に無視されてもよいです。)
#可视化各层序号及名称
for i, layer in enumerate(model.layers):
print(i, layer.name)
for i, layer in enumerate(conv_base.layers):
print(i, layer.name)
#由于之前操作错误,导致模型全部层都被冻结,所以这个模块先把所有层解冻
for layer in conv_base.layers: #先解冻卷积基中所有层的张量
layer.trainable = True
for layer in model.layers: #解冻model中所有层张量
layer.trainable = True
#查看各层的trainable属性
for layer in model.layers:
print(layer.name, layer.trainable)
for layer in conv_base.layers:
print(layer.name, layer.trainable)
#model.trainable = True #注意:设定单独层的trainable属性后,全局trainable属性无效
print(len(conv_base.trainable_weights)) #26
print(len(model.trainable_weights)) #30
第二段階の後、2つの高密度トレーニング可能な後に冷凍畳み込みがベース。そして、第三の工程を開始し、5番目のブロック、共同訓練の融解層、およびカスタムネットワークを解凍しました。
######################第三步:解冻部分卷积基,联合训练##########################
#冻结VGG16中前四个block,解冻第五个block
flag = False #标记是否到达第五个block
for layer in conv_base.layers: #注意不是遍历model.layers
if layer.name == 'block5_conv1': #若到达第五个block,则标记之
flag = True
if flag == False: #若标记为False,则冻结,否则设置为可训练
layer.trainable = False
else:
layer.trainable = True
print(len(model.trainable_weights)) #应为10
#重新编译并训练。血泪教训,一定要重新编译,不然trainable属性就白忙活了!
from keras import optimizers
#注:吐血,官网文档参数learning_rate,这里竟然不认,只能用lr
model.compile(loss='binary_crossentropy',
optimizer=optimizers.Adam(lr=1e-5), metrics=['accuracy'])
H2 = model.fit_generator(train_generator,
steps_per_epoch=2000/20,
epochs=100,
validation_data=validation_generator,
validation_steps=1000/20)
100エポックの後、次のような結果。精度は約94%に増加していることを確認見ることができます。
参考:
本:Pythonの深い学習