深度学习框架tensorflow二实战(迁移学习)

迁移学习

用人家训练好模型的权重参数当做我们的初始化
一般全连接层需要自己训练,可以选择是否训练别人训练好的特征提取层
例如vgg,inception等这些构建好等网络结构,训练好了这些模型的这些参数,我们直接拿过来使用作为参数的初始化(之前一般使用高斯随机初始化)
不仅仅用了别人的参数,更重要的是把整个神经网络拿过来使用做我们自己的任务

我们有两种使用方法:
1.使用别的人卷积、池化这些的特征提取层,用已有的模型参数作为训练的初始化
2.直接使用别的人卷积、池化这些的特征提取层,参数也直接使用,不再训练
他们的共同点是全连接层得根据任务需求自行训练
针对数据集大小有三种不同方案:
数据集少的就冻住更多的特征提取层,把所有特征提取层使用第2种方法
数据集中的可以冻住开始一部分的特征提取层
数据集多的可以自行训练啦,即使用第1种方法

以下测试CPU可以跑动,但时间消耗巨大。

导入工具包和设置训练集、验证集路径

import os
import warnings
warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers
from tensorflow.keras import Model

base_dir = './data/cats_and_dogs'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')

train_cats_dir = os.path.join(train_dir, 'cats')
train_dogs_dir = os.path.join(train_dir, 'dogs')

validation_cats_dir = os.path.join(validation_dir, 'cats')
validation_dogs_dir = os.path.join(validation_dir, 'dogs')

导入经典模型

### 导入模型,没有参数,还得下载
from tensorflow.keras.applications.resnet import ResNet50
from tensorflow.keras.applications.resnet import ResNet101
from tensorflow.keras.applications.inception_v3 import InceptionV3

模型对应的参数文件可以自行下载,放到指定文件夹。
Windows:C:\Users\Administrator.keras\datasets
Mac:Users.keras\datasets
下载链接:Click~
没有下载也不用担心,下面的代码会自行去指定文件夹查看是否有对应的参数文件,没有也会自行下载,但速度较慢。

使用残差网络ResNet101进行测试

pre_trained_model = ResNet101(input_shape = (75, 75, 3), # 输入大小
                                include_top = False, # 不要最后的全连接层
                                weights = 'imagenet')#weights = 'None'是随机初始化,或者自己指定一个路径,或者就是使用别人训练完的模型的参数。

#设置哪些特征提取层需要训练,哪些不需要训练。
for layer in pre_trained_model.layers:
    layer.trainable = False
from tensorflow.keras.optimizers import Adam

# 为全连接层准备
x = layers.Flatten()(pre_trained_model.output)
# 加入全连接层,这个需要重头训练的
x = layers.Dense(1024, activation='relu')(x)
x = layers.Dropout(0.2)(x)
# 输出层
x = layers.Dense(1, activation='sigmoid')(x)
# 构建模型序列
model = Model(pre_trained_model.input, x)
#模型装载
model.compile(optimizer = Adam(lr=0.001),
              loss = 'binary_crossentropy',
              metrics = ['acc'])

也可以使用以下的代码去指定从原有的模型中取出前面的多少层,再加上自定义的几层来进行训练。

last_layer = pre_trained_model.get_layer("某层的名字")

数据增强

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)

test_datagen = ImageDataGenerator( rescale = 1.0/255. )

train_generator = train_datagen.flow_from_directory(train_dir,
                                                    batch_size = 20,
                                                    class_mode = 'binary',
                                                    target_size = (75, 75))

validation_generator =  test_datagen.flow_from_directory( validation_dir,
                                                          batch_size  = 20,
                                                          class_mode  = 'binary',
                                                          target_size = (75, 75))

回调

callback的作用
相当于一个监视器,在训练过程中可以设置一些自定义项,比如提前停止,改变学习率等
callbacks = [
如果连续两个epoch还没降低就停止:
tf.keras.callbacks.EarlyStopping(patience=2, monitor=‘val_loss’),
可以动态改变学习率:
tf.keras.callbacks.LearningRateScheduler
保存模型:
tf.keras.callbacks.ModelCheckpoint
自定义方法:
tf.keras.callbacks.Callback
]

#回调
class myCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs={}):  #在一次迭代结束后判断是否提前停止
        if(logs.get('acc')>0.95):
            print("\nReached 95% accuracy so cancelling training!")
            self.model.stop_training = True
callbacks = myCallback()

开始训练

history = model.fit(
            train_generator,
            validation_data = validation_generator,
            steps_per_epoch = 100,
            epochs = 100,
            validation_steps = 50,
            verbose = 2,
            callbacks=[callbacks])

效果展示

import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'b', label='Training accuracy')
plt.plot(epochs, val_acc, 'r', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'b', label='Training Loss')
plt.plot(epochs, val_loss, 'r', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

猜你喜欢

转载自blog.csdn.net/weixin_43999137/article/details/104093095
今日推荐