人工智能-迁移学习

概念

这里的Transfer Learning是人工智能里的概念,迁移于教育学知识里的学习迁移概念:
学习迁移也叫训练迁移,即一种学习对另一种学习的影响,也就是已获得的知识、技能、学习方法或学习态度对学习新知识、新技能的和解决新问题所产生的一种影响,或者说将学得的经验有变化地运用于另一情景。
那么,按照这种思路,深度卷积神经网络在大型数据集上做训练,所学习的经验–权重,是不是也可以迁移到另外一个数据集上使用呢?这种迁移学习有什么好处?
当计算机视觉研究人员没有足够多的训练数据,或者足够长时间,或足够好的硬件运算能力,训练一个庞大的CNN网络来生成新任务的时候;当训练数据集的类别和曾经完成过的分类网络部分重合或相差不大的时候,从头开始训练整个CNN网络是即费事也费时的。这时,迁移学习就缓解了大部分应用上的压力。学生的举一反三,触类旁通的技能也将体现在深度卷积神经网络的学习上。
迁移学习常见的策略是采用在大型数据集上预训练好的网络,然后通过微调这个网络的输出,或者某些层的参数来适应新任务。

迁移学习实例

这里采用在imageNet上预训练好的Vgg16,来调整适应新任务。在像 ImageNet 这样的大型数据集上预先训练的 VGG16 网络,训练的计算量是相当大,因此这个预训练网络是有意义的。
vgg16
实现步骤:
一、运用keals自动下载vgg16预先训练好的权重,当然,它是有1000个分类的输出;
二、将vgg16省去输出层,冻结前15层的权重,定义为base_model;
三、定义自定义输出网络层,由全连接层和softmax层组成,用自己的数据训练网络。
四、组合base_model和自定义输出层,用训练数据调节自定义网络权重,达到适应新任务的目的。

关键实现

对应步骤实现方法:
一、 from keras import application →base_model = application.VGG16(weight=”imagenet”,
Include_top = False,input_shape=(img_width,img_height,3))
二、 for layer in base_model.layers[:15]:
Layer.trainable = False
三、 自定义顶层分类

# 自定义输出层网络
    top_model = base_model.output  # 自定义顶层的输入为vgg16的第15层输出
    top_model = Flatten(name="flatten")(top_model)
    top_model = Dense(256, activation='relu')(top_model)
    top_model = Dropout(0.5)(top_model)
    top_model = Dense(OUT_CATEGORIES, activation='sigmoid')(top_model)

四、 组建最后的应用网络

model = Model(inputs=base_model.input,
              outputs =top_model(base_model.output))
model.compile(loss="binary_crossentropy",
              optimizer=optimizers.SGD(lr=0.0001,momentum=0.9),
              metrics=["accuracy"])
model.fit_generator(train_generator,
                    steps_per_epoch=nb_train_samples // batch_size,
                    epochs=epochs,
                    validation_data=validation_generator,
                    validation_steps=nb_validation_samples // batch_size,
                    verbose=2, workers=12)

结果

model

Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 48, 48, 3)         0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 48, 48, 64)        1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 48, 48, 64)        36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 24, 24, 64)        0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 24, 24, 128)       73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 24, 24, 128)       147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 12, 12, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 12, 12, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 12, 12, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 12, 12, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 6, 6, 256)         0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 6, 6, 512)         1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 6, 6, 512)         2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 6, 6, 512)         2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 3, 3, 512)         0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 3, 3, 512)         2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 3, 3, 512)         2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 3, 3, 512)         2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 1, 1, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 512)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               131328    
_________________________________________________________________
dropout_1 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 257       
=================================================================
Total params: 14,846,273
Trainable params: 7,211,009
Non-trainable params: 7,635,264
_________________________________________________________________
Epoch 1/50
2020-02-05 13:31:34.347151: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_100.dll
2020-02-05 13:31:35.888561: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudnn64_7.dll
2020-02-05 13:31:41.224111: W tensorflow/stream_executor/cuda/redzone_allocator.cc:312] Internal: Invoking ptxas not supported on Windows
Relying on driver to perform ptx compilation. This message will be only logged once.
 - 121s - loss: 0.5155 - accuracy: 0.7390 - val_loss: 0.9262 - val_accuracy: 0.7966
Epoch 2/50
 - 41s - loss: 0.4264 - accuracy: 0.8028 - val_loss: 0.4442 - val_accuracy: 0.8274
Epoch 3/50
 - 41s - loss: 0.3950 - accuracy: 0.8182 - val_loss: 0.1512 - val_accuracy: 0.8217
Epoch 4/50
 - 41s - loss: 0.3747 - accuracy: 0.8325 - val_loss: 0.3008 - val_accuracy: 0.8425
Epoch 5/50
 - 41s - loss: 0.3629 - accuracy: 0.8391 - val_loss: 0.4700 - val_accuracy: 0.8453
Epoch 6/50
 - 41s - loss: 0.3474 - accuracy: 0.8445 - val_loss: 0.2652 - val_accuracy: 0.8349
Epoch 7/50
 - 41s - loss: 0.3368 - accuracy: 0.8517 - val_loss: 0.3980 - val_accuracy: 0.8396
Epoch 8/50
 - 41s - loss: 0.3261 - accuracy: 0.8570 - val_loss: 0.2793 - val_accuracy: 0.8453
Epoch 9/50
 - 41s - loss: 0.3149 - accuracy: 0.8644 - val_loss: 0.3659 - val_accuracy: 0.8500
Epoch 10/50
 - 41s - loss: 0.3091 - accuracy: 0.8675 - val_loss: 0.2380 - val_accuracy: 0.8566
Epoch 11/50
 - 41s - loss: 0.2973 - accuracy: 0.8710 - val_loss: 0.0881 - val_accuracy: 0.8509
Epoch 12/50
 - 41s - loss: 0.2865 - accuracy: 0.8779 - val_loss: 0.4210 - val_accuracy: 0.8491
Epoch 13/50
 - 41s - loss: 0.2801 - accuracy: 0.8814 - val_loss: 0.2393 - val_accuracy: 0.8443
Epoch 14/50
 - 41s - loss: 0.2720 - accuracy: 0.8851 - val_loss: 0.4887 - val_accuracy: 0.8330
Epoch 15/50
 - 41s - loss: 0.2587 - accuracy: 0.8911 - val_loss: 0.3147 - val_accuracy: 0.8557
Epoch 16/50
 - 41s - loss: 0.2508 - accuracy: 0.8968 - val_loss: 0.4540 - val_accuracy: 0.8415
Epoch 17/50
 - 41s - loss: 0.2433 - accuracy: 0.8988 - val_loss: 0.2023 - val_accuracy: 0.8500
Epoch 18/50
 - 41s - loss: 0.2296 - accuracy: 0.9048 - val_loss: 0.0292 - val_accuracy: 0.8443
Epoch 19/50
 - 41s - loss: 0.2235 - accuracy: 0.9073 - val_loss: 0.4392 - val_accuracy: 0.8462
Epoch 20/50
 - 41s - loss: 0.2112 - accuracy: 0.9139 - val_loss: 0.5417 - val_accuracy: 0.8462
Epoch 21/50
 - 41s - loss: 0.2014 - accuracy: 0.9191 - val_loss: 0.0715 - val_accuracy: 0.8189
Epoch 22/50
 - 41s - loss: 0.1931 - accuracy: 0.9251 - val_loss: 0.6333 - val_accuracy: 0.8500
Epoch 23/50
 - 41s - loss: 0.1774 - accuracy: 0.9303 - val_loss: 0.7511 - val_accuracy: 0.8472
Epoch 24/50
 - 41s - loss: 0.1645 - accuracy: 0.9352 - val_loss: 0.7335 - val_accuracy: 0.8557
Epoch 25/50
 - 41s - loss: 0.1532 - accuracy: 0.9415 - val_loss: 0.0181 - val_accuracy: 0.8453
Epoch 26/50
 - 41s - loss: 0.1497 - accuracy: 0.9419 - val_loss: 0.1532 - val_accuracy: 0.8462
Epoch 27/50
 - 41s - loss: 0.1390 - accuracy: 0.9474 - val_loss: 0.1028 - val_accuracy: 0.8368
Epoch 28/50
 - 41s - loss: 0.1287 - accuracy: 0.9506 - val_loss: 0.2374 - val_accuracy: 0.8415
Epoch 29/50
 - 41s - loss: 0.1164 - accuracy: 0.9579 - val_loss: 0.7878 - val_accuracy: 0.8340
Epoch 30/50
 - 41s - loss: 0.1054 - accuracy: 0.9600 - val_loss: 0.3963 - val_accuracy: 0.8538
Epoch 31/50
 - 41s - loss: 0.0945 - accuracy: 0.9655 - val_loss: 0.7956 - val_accuracy: 0.8236
Epoch 32/50
 - 41s - loss: 0.0879 - accuracy: 0.9687 - val_loss: 0.0872 - val_accuracy: 0.8519
Epoch 33/50
 - 41s - loss: 0.0753 - accuracy: 0.9740 - val_loss: 0.9650 - val_accuracy: 0.8481
Epoch 34/50
 - 41s - loss: 0.0714 - accuracy: 0.9749 - val_loss: 0.1681 - val_accuracy: 0.8491
Epoch 35/50
 - 41s - loss: 0.0697 - accuracy: 0.9743 - val_loss: 0.2581 - val_accuracy: 0.8415
Epoch 36/50
 - 41s - loss: 0.0613 - accuracy: 0.9787 - val_loss: 0.3740 - val_accuracy: 0.8509
Epoch 37/50
 - 41s - loss: 0.0570 - accuracy: 0.9796 - val_loss: 0.7630 - val_accuracy: 0.8509
Epoch 38/50
 - 41s - loss: 0.0453 - accuracy: 0.9843 - val_loss: 0.8476 - val_accuracy: 0.8585
Epoch 39/50
 - 41s - loss: 0.0481 - accuracy: 0.9825 - val_loss: 0.9259 - val_accuracy: 0.8557
Epoch 40/50
 - 41s - loss: 0.0468 - accuracy: 0.9840 - val_loss: 0.5572 - val_accuracy: 0.8349
Epoch 41/50
 - 41s - loss: 0.0370 - accuracy: 0.9877 - val_loss: 1.0903 - val_accuracy: 0.8538
Epoch 42/50
 - 41s - loss: 0.0280 - accuracy: 0.9912 - val_loss: 0.7311 - val_accuracy: 0.8519
Epoch 43/50
 - 41s - loss: 0.0285 - accuracy: 0.9905 - val_loss: 1.2955 - val_accuracy: 0.8377
Epoch 44/50
 - 41s - loss: 0.0303 - accuracy: 0.9902 - val_loss: 1.2621 - val_accuracy: 0.8538
Epoch 45/50
 - 41s - loss: 0.0274 - accuracy: 0.9905 - val_loss: 1.3450 - val_accuracy: 0.8425
Epoch 46/50
 - 41s - loss: 0.0253 - accuracy: 0.9918 - val_loss: 0.5590 - val_accuracy: 0.8491
Epoch 47/50
 - 41s - loss: 0.0168 - accuracy: 0.9954 - val_loss: 0.2676 - val_accuracy: 0.8453
Epoch 48/50
 - 41s - loss: 0.0135 - accuracy: 0.9966 - val_loss: 0.5692 - val_accuracy: 0.8519
Epoch 49/50
 - 41s - loss: 0.0191 - accuracy: 0.9940 - val_loss: 0.7781 - val_accuracy: 0.8585
Epoch 50/50
 - 41s - loss: 0.0129 - accuracy: 0.9965 - val_loss: 0.2398 - val_accuracy: 0.8509

Process finished with exit code 0

代码实现

#!/usr/bin/python
# -*- coding = utf-8 -*-
# author: beauthy
# date: 20200205
# version: 1.0.0
'''采用在 ImageNet 上预训练好的网络,然后通过微调整个网络来适应新任务。'''
'''vgg16有权重参数的层分别是conv1-conv5和fc1-fc3,
其他层,5个max_pool层,2个dropout层,和一个softmax层'''
from keras import applications,optimizers
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential,Model
from keras.layers import Dropout,Flatten,Dense

img_width, img_height = 48, 48
batch_size = 16
epochs = 50
train_data_dir = 'data/dogs_vs_cats/train'
validation_data_dir = 'data/dogs_vs_cats/test1'
# 增强训练集
train_datagen = ImageDataGenerator(
    rescale=1./255,
    horizontal_flip=True
)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_data_dir,
                                                    target_size=(img_height,img_width),
                                                    batch_size=batch_size,
                                                    class_mode='binary')
validation_generator = test_datagen.flow_from_directory(validation_data_dir,
                                                        target_size=(img_height,img_width),
                                                        batch_size=batch_size,
                                                        class_mode='binary',
                                                        shuffle=False)

# 输出类别
OUT_CATEGORIES = 1
nb_train_samples = 25000
nb_validation_samples = 1076

def transfer_learning():
    # 下载vgg16模型,导入预定义的权重
    base_model = applications.VGG16(weights="imagenet",
                                include_top=False,
                                input_shape=(img_width,img_height,3))
    base_model.summary()
    # 冻结预训练的vgg16网络的一定数量的较低层。此处冻结前15层
    for layer in base_model.layers[:15]:
        layer.trainable=False
    # 自定义输出层网络
    top_model = base_model.output  # 自定义顶层的输入为vgg16的第15层输出
    top_model = Flatten(name="flatten")(top_model)
    top_model = Dense(256, activation='relu')(top_model)
    top_model = Dropout(0.5)(top_model)
    top_model = Dense(OUT_CATEGORIES, activation='sigmoid')(top_model)
    # 组建最后的应用网络
    model = Model(inputs=base_model.input, outputs=top_model)
    # compile the model
    model.compile(loss="binary_crossentropy",
                  optimizer=optimizers.SGD(lr=0.0001, momentum=0.9),
                  metrics=["accuracy"])
    model.fit_generator(train_generator,
                        steps_per_epoch=nb_train_samples // batch_size,
                        epochs=epochs,
                        validation_data=validation_generator,
                        validation_steps=nb_validation_samples // batch_size,
                        verbose=2,
                        workers=12)
    # 评估
    score = model.evaluate_generator(validation_generator, nb_validation_samples / batch_size)
    scores = model.predict_generator(validation_generator, nb_validation_samples / batch_size)


if __name__ == "__main__":
    transfer_learning()

最后:附上训练数据,下载于kaggle的dogs-vs-cats.zip,学习中下载不到数据,可以联系邮箱[email protected]
数据解压后需要将训练用的train目录和测试目录test下的cat和dog图片,分别存放在两个目录下。否则生成器中找不到类型和数据,会报错:Found 0 images belonging to 0 classes. Found 0 images belonging to 0 classes。

猜你喜欢

转载自blog.csdn.net/beauthy/article/details/105115697