猫狗图像分类——使用预训练网络VGG16,利用卷积基提取特征,训练分类器

猫狗图像分类——使用预训练网络VGG16,利用卷积基提取特征,训练分类器_第1张图片

# coding: utf-8
from tensorflow.keras.applications import VGG16


# ----------------------------卷积基----------------------------------------------------
"""不需要最后的密集连接分类器"""
conv_base = VGG16(weights='imagent', # 初始化权重检查点
                  include_top=False, # 指定模型最后不包含密集连接分类器。默认情况:Dense包含1000各类别(Images),这里我们只需要2各类别
                  input_shape=(150, 150, 3)) # 可选参数,网络可以处理任意的输出形状

conv_base.summary()

# ---------------------------方法1,不使用数据增强的快速特征提取,使用预训练的卷积基提取特征----------------------------------------
# 在你的数据集上运行卷积基,将输出保存成硬盘中的 Numpy 数组,然后用这个数据作 为输入,输入到独立的密集连接分类器中
# (与本书第一部分介绍的分类器类似)。这种 方法速度快,计算代价低,因为对于每个输入图像只需运行一次卷积基,而卷积基是目 前流程中计算代价最高的。但出于同样的原因,这种方法不允许你使用数据增强。
"""首先运行ImageDataGenerator实例,将图像及其标签提取为Numpy数组,利用VGG16的predict方法提取特征"""
import os
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator


base_dir = '/python 深度学习/datasets/cats_and_dogs_small'
train_dir = os.path.join(base_dir, 'VGG16_train')
validation_dir = os.path.join(base_dir, 'VGG16_validation')
test_dir = os.path.join(base_dir, 'VGG16_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, 3),
                                            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:
            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),将其输入到密集连接分类器中,首先要将其形状展开为(samples, 8192)"""

# ------------------------------数据预处理-----------------------------------------
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 tensorflow.keras import models
from tensorflow.keras import layers
from tensorflow.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_crossentrpy',
              metrics=['acc'])

history = model.fit(train_features, train_labels, epochs=30, batch_size=20, validation_data=(validation_features, validation_labels))


"""小数据集上使用数据增强效果很好,但是运行速度很慢,计算代价很高。只有在GPU的情况下尝试运行,在CPU上绝对是很难运行的,
如果没有GPU就尝试第一种方法"""

你可能感兴趣的:(深度学习框架—Keras)