预训练网络

预训练网络有两种方法:特征提取和微调模型

1、特征提取

以VGG16为例

VGG16模型结构为

Layer (type) Output Shape Param # 
=================================================================
input_1 (InputLayer) (None, 150, 150, 3) 0 
_________________________________________________________________
block1_conv1 (Conv2D) (None, 150, 150, 64) 1792 
_________________________________________________________________
block1_conv2 (Conv2D) (None, 150, 150, 64) 36928 
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 75, 75, 64) 0 
_________________________________________________________________
block2_conv1 (Conv2D) (None, 75, 75, 128) 73856 
_________________________________________________________________
block2_conv2 (Conv2D) (None, 75, 75, 128) 147584 
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 37, 37, 128) 0 
_________________________________________________________________
block3_conv1 (Conv2D) (None, 37, 37, 256) 295168 
_________________________________________________________________
block3_conv2 (Conv2D) (None, 37, 37, 256) 590080 
_________________________________________________________________
block3_conv3 (Conv2D) (None, 37, 37, 256) 590080 
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 18, 18, 256) 0 
_________________________________________________________________
block4_conv1 (Conv2D) (None, 18, 18, 512) 1180160 
_________________________________________________________________
block4_conv2 (Conv2D) (None, 18, 18, 512) 2359808 
_________________________________________________________________
block4_conv3 (Conv2D) (None, 18, 18, 512) 2359808 
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 9, 9, 512) 0 
_________________________________________________________________
block5_conv1 (Conv2D) (None, 9, 9, 512) 2359808 
_________________________________________________________________
block5_conv2 (Conv2D) (None, 9, 9, 512) 2359808 
_________________________________________________________________
block5_conv3 (Conv2D) (None, 9, 9, 512) 2359808 
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 4, 4, 512) 0 
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
from keras.applications import VGG16
conv_base = VGG16(weights='imagenet',
     include_top=False,
     input_shape=(150, 150, 3))
#weights 指定模型初始化的权重检查点
#include_top 指定模型最后是否包含密集连接分类器
#input_shape 是输入到网络中的图像张量的形状

从VGG16模型可以看到,模型最后的特征图形状为 (4, 4, 512),在这个特征上添加一个密集连接分类器,有两种方法:(1)在你的数据集上运行卷积基,将输出保存成硬盘中的 Numpy 数组,然后用这个数据作 为输入,输入到独立的密集连接分类器中,不可以使用数据增强(2)改变已有的VGG16模型,给模型中添加Dense层,输入数据端到端运行整个模型,可以使用数据增强

第一种方法代码:保存数据在 VGG16 中的输出,然后将这些输出作为输入用于新模型。

import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
base_dir = '/Users/fchollet/Downloads/cats_and_dogs_small'
train_dir = os.path.join(base_dir, 'train') 
validation_dir = os.path.join(base_dir, 'validation') 
test_dir = os.path.join(base_dir, 'test')
datagen = ImageDataGenerator(rescale=1./255) 
batch_size = 20
def extract_features(directory, sample_count):
    features = np.zeros(shape=(sample_count, 4, 4, 512)) 
    labels = np.zeros(shape=(sample_count))
    generator = datagen.flow_from_directory(
    directory, 
    target_size=(150, 150), 
    batch_size=batch_size, 
    class_mode='binary')
    i = 0
    for inputs_batch, labels_batch in generator:
    features_batch = conv_base.predict(inputs_batch)
    features[i * batch_size : (i + 1) * batch_size] = features_batch 
    labels[i * batch_size : (i + 1) * batch_size] = labels_batch
    i += 1
    if i * batch_size >= sample_count:
    break 
    return features, labels
train_features, train_labels = extract_features(train_dir, 2000) 
validation_features, validation_labels = extract_features(validation_dir, 1000) 
test_features, test_labels = extract_features(test_dir, 1000)

#提取出的形状为(samples, 4, 4, 512),需要展平输入到密集连接分类器
train_features = np.reshape(train_features, (2000, 4 * 4 * 512))
validation_features = np.reshape(validation_features, (1000, 4 * 4 * 512))
test_features = np.reshape(test_features, (1000, 4 * 4 * 512))


from keras import models
from keras import layers
from keras import optimizers
model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_dim=4 * 4 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer=optimizers.RMSprop(lr=2e-5),
   loss='binary_crossentropy',
   metrics=['acc'])
history = model.fit(train_features, train_labels,
   epochs=30,
   batch_size=20,
   validation_data=(validation_features, validation_labels))

第二种方法示例代码

from keras import models
from keras import layers
model = models.Sequential()
model.add(model_base)          #已有的VGG16模型
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

#在编译和训练模型之前,需要要“冻结”卷积基。冻结一个或多个层是指在训练过程中保持其权重不变
#冻结网络的方法是将其 trainable 属性设为 False
model_base.trainable = False

from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
#数据增强
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_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')
model.compile(loss='binary_crossentropy',
    optimizer=optimizers.RMSprop(lr=2e-5),
    metrics=['acc'])
history = model.fit_generator(
    train_generator,
    steps_per_epoch=100,
    epochs=30,
    validation_data=validation_generator,
    validation_steps=50)

2、微调模型

       对于用于特征提取的冻结的模型基,微调是指将其顶部的几层“解冻”,并将这解冻的几层和新增加的部分联合训练。

步骤:(1) 在已经训练好的基网络(base network)上添加自定义网络。(2) 冻结基网络。(3) 训练所添加的部分。(4) 解冻基网络的一些层。(5) 联合训练解冻的这些层和添加的部分

#在第二种方法实例的基础上进行微调,微调model_base最后3个卷积层,'block5_conv1'
model_base.trainable = True
set_trainable = False
for layer in model_base.layers:
    if layer.name == 'block5_conv1':
        set_trainable = True
    if set_trainable:
        layer.trainable = True
    else:
        layer.trainable = False

model.compile(loss='binary_crossentropy',
     optimizer=optimizers.RMSprop(lr=1e-5),
     metrics=['acc'])
history = model.fit_generator(
     train_generator,
     steps_per_epoch=100,
     epochs=100,
     validation_data=validation_generator,
     validation_steps=50)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值