VGG16 keras框架 猫狗识别【使用预训练的卷积神经网络】

VGG16 keras框架 猫狗识别【使用预训练的卷积神经网络】

一.前言

想要将深度学习应用在小型数据集,一种高效的方法是使用预训练的网络。

预训练的网络是之前保存好的网络,之前大型数据集(通常是大规模图像分类任务)上训练好。如果这个原始数据集足够大且足够通用,那么预训练的网络学到的特征的空间层次结构,可以有效的作为视觉世界的通用模型,因此这些模型可以用于各种不同的计算机视觉问题。

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

二.特征提取

特征提取是使用之前网络学习到的表示来从新样本中提取出有趣的特征。然后将这些特征进入一个新的分类器,从头开始训练。
用于图像分类的卷积神经网络包含两部分,首先是一系列的池化层和卷积层,最后是一个密集连接分类器。
在这里插入图片描述

为什么要用仅仅使用卷积基呢?我们能否也重复使用密集连接分类器?一般来说,应该避免这么做。原因在于卷积基学到的表示可能更加通用。卷积神经网络的特征图表示通用概念在图像中是否存在,无论面对什么样的计算机视觉问题,这种特征图都可能是有用的。但是,分类器学到的表示必然是针对模型训练的类别,其中仅包含某个类别出现在某张图像中的概率信息。

VGG16等模型内置于Keras中。可以通过模块导入的方式进行导入。下面是Keras.applications中的一部分图像分类模型(都是在ImageNet数据集中训练得到的)

  • Xception
  • Inception V3
  • ResNet50
  • VGG16
  • VGG19
  • MobileNet

本篇博客将教你迁移已经训练好的VGG16模型。

三.实现步骤

3.1 将VGG16实例化

from keras.applications import  VGG16
conv_base = VGG16(weights='imagenet',
                  include_top=False,
                  input_shape= (150,150,3))

这里向构造函数中传递入三个参数。

  • weights 指定模型初始化的权重检查点。
  • include_top 指定模型最后是否包括密集连接分类器。默认情况下,这个密集连接分类器应该对应于ImageNet的1000个类别。因为我们打算使用自己的密集连接分类器(只有两个类别:cat和dog),所以不需要包含它。
  • input_shape 是指输入到网络的图像张量的形状。这个参数是可选的。如果不选择,那么网络可以处理任意形状的输入。
    最后输出的特征图的形状为(4,4,512)。

下一步有两种方法可供选择。

  • 在你的数据集上运行卷积基,将输出保存为硬盘中的Numpy数组,然后将这个数据作为输入,输入到独立的密集连接分类器中。
  • 在顶部添加Dense层来扩展已有模型(即conv_base),并在输入数据上端到端的运行整个模型。这样你可以使用数据增强,因为每个输入图像进入模型时都会经过卷积基。但是出于同样的原因,这种方法计算代价很高。

3.2 使用预训练的卷积基提取特征

from keras.applications import  VGG16
import  os
import  numpy as np
from keras import  models
from keras import  layers
from keras import optimizers
from keras.preprocessing.image import  ImageDataGenerator
base_dir ='D:/严少青毕设/CNN-BiLSTM/cnn-bilstm/base_data'
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
conv_base = VGG16(weights='imagenet',
                  include_top=False,
                  input_shape= (150,150,3))
def extract_freatures(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
if __name__ == '__main__':
    train_features,train_labels =extract_freatures(train_dir,2000)
    validation_features, validation_labels = extract_freatures(validation_dir,1000)
    test_features, test_labels = extract_freatures(test_dir,1000)
    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))
    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(learning_rate=2e-5),
                  loss='binary_crossentropy',
                  metrics='accuracy')
    history = model.fit(train_features,train_labels,
                        epochs=30,
                        batch_size=20,
                        validation_data=(validation_features,validation_labels))
Found 2000 images belonging to 2 classes.
1/1 [==============================] - 1s 1s/step
Found 1000 images belonging to 2 classes.
1/1 [==============================] - 1s 1s/step
Found 1000 images belonging to 2 classes.
1/1 [==============================] - 1s 1s/step
Epoch 1/30
100/100 [==============================] - 2s 19ms/step - loss: 0.6917 - accuracy: 0.9960 - val_loss: 0.6876 - val_accuracy: 0.9920
Epoch 2/30
100/100 [==============================] - 2s 17ms/step - loss: 0.6861 - accuracy: 0.9950 - val_loss: 0.6812 - val_accuracy: 0.9910
Epoch 3/30
100/100 [==============================] - 2s 18ms/step - loss: 0.6772 - accuracy: 0.9970 - val_loss: 0.6754 - val_accuracy: 0.9900
Epoch 4/30
100/100 [==============================] - 2s 18ms/step - loss: 0.6686 - accuracy: 0.9980 - val_loss: 0.6687 - val_accuracy: 0.9910

可以看见训练和验证精度都非常高。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是基于TensorFlow(Keras)搭建的VGG16卷积神经网络,实现手写数字识别的代码: ```python import tensorflow as tf from tensorflow.keras import layers, models, datasets, utils # 加载数据集 (train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data() # 数据预处理 train_images = train_images.reshape((60000, 28, 28, 1)) / 255.0 test_images = test_images.reshape((10000, 28, 28, 1)) / 255.0 # 将标签进行one-hot编码 train_labels = utils.to_categorical(train_labels) test_labels = utils.to_categorical(test_labels) # 构建VGG16模型 model = models.Sequential() model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=(28, 28, 1))) model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same')) model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same')) model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same')) model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dense(4096, activation='relu')) model.add(layers.Dense(4096, activation='relu')) model.add(layers.Dense(10, activation='softmax')) # 模型编译 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 模型训练 model.fit(train_images, train_labels, epochs=5, batch_size=64, validation_data=(test_images, test_labels)) # 模型评估 test_loss, test_acc = model.evaluate(test_images, test_labels) print('Test accuracy:', test_acc) ``` 需要注意的是,这个模型的训练需要较长时间,可以在Colab等云环境中进行训练。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪中奇侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值