CNN基础二:使用预训练网络提取图像特征

上一节中,我们采用了一个自定义的网络结构,从头开始训练猫狗大战分类器,最终在使用图像增强的方式下得到了82%的验证准确率。但是,想要将深度学习应用于小型图像数据集,通常不会贸然采用复杂网络并且从头开始训练(training from scratch),因为训练代价高,且很难避免过拟合问题。相对的,通常会采用一种更高效的方法——使用预训练网络。

预训练网络的使用通常有两种方式,一种是利用预训练网络简单提取图像的特征,之后可能会利用这些特征进行其他操作(比如和文本信息结合以用于image caption,或者简单的进行分类);另一种是对预训练的网络进行裁剪和微调,以适应自己的任务。

第一种方式训练代价极低,因为它就是简单提取个特征,不涉及训练;缺点是保存提取出来的特征需要占用一定空间,且无法使用图像增强(而图像增强对于防止小型数据集的过拟合非常重要)。第二种方式可以使用图像增强,但训练代价也会大幅增加。(当然相对于从头训练来说,使用预训练网络的训练代价肯定要低得多。)

这一节中我们以VGG16提取图像特征为例,展示第一种使用方式。该案例接着上一个例子,使用同样的数据集,利用keras中自带的VGG16模型提取图像特征,然后以这些图像特征为输入,训练一个小型分类器。

import numpy as np
from keras.applications.vgg16 import VGG16

#实例化一个VGG16卷积基
#输入维度根据需要自行指定,这里仍然采用上一个例子的维度,卷积基的输出是(None,4,4,512)
conv_base = VGG16(include_top=False, input_shape=(150,150,3))
#conv_base.summary()

###############单纯用VGG16卷积基直接提取特征,不使用图像增强####################
import os
from keras.preprocessing.image import ImageDataGenerator

#定义提取图像特征的函数
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: #分别为(20,150,150,3) (20,)
        features_batch = conv_base.predict(inputs_batch)  #(20,4,4,512)
        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_dir = r'D:\KaggleDatasets\MyDatasets\dogs-vs-cats-small\train'
validation_dir = r'D:\KaggleDatasets\MyDatasets\dogs-vs-cats-small\validation'
test_dir = r'D:\KaggleDatasets\MyDatasets\dogs-vs-cats-small\test'
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)

#将各自的图像特征展平,作为后续Dense层的输入
assert train_features.shape == (2000, 4, 4, 512)
assert validation_features.shape == (1000, 4, 4, 512)
assert test_features.shape == (1000, 4, 4, 512)
train_features = train_features.reshape(2000, 4*4*512)
validation_features = validation_features.reshape(1000, 4*4*512)
test_features = test_features.reshape(1000, 4*4*512)

###################定义并训练一个小型分类器#########################
from keras.models import Model
from keras.layers import Input, Dense, Dropout

input = Input(shape=(4*4*512,))
X = Dense(256, activation='relu')(input)
X = Dropout(0.5)(X)
X = Dense(1, activation='sigmoid')(X)

model = Model(inputs=input, outputs=X)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

H = model.fit(train_features, train_labels,
              validation_data=(validation_features, validation_labels),
              epochs=30, batch_size=64, verbose=1)

#######################训练结果可视化############################
import matplotlib.pyplot as plt

acc = H.history['acc']
val_acc = H.history['val_acc']
loss = H.history['loss']
val_loss = H.history['val_loss']
epoch = range(1, len(loss) + 1)

fig, ax = plt.subplots(1, 2, figsize=(10,4))
fig.subplots_adjust(wspace=0.2)
ax[0].plot(epoch, loss, label='Train loss') #注意不要写成labels
ax[0].plot(epoch, val_loss, label='Validation loss')
ax[0].set_xlabel('Epoch')
ax[0].set_ylabel('Loss')
ax[0].legend()
ax[1].plot(epoch, acc, label='Train acc')
ax[1].plot(epoch, val_acc, label='Validation acc')
ax[1].set_xlabel('Epoch')
ax[1].set_ylabel('Accuracy')
ax[1].legend()
plt.show()

训练结果如下所示。可以看出,相对于上一个从头开始训练的猫狗分类任务,很轻松的就把验证集准确率由82%提高到90%左右,更重要的是,现在还没有使用重量级武器——图像增强。下一节,我们会使用第二种更常用更高效的方式——模型微调。

原文地址:https://www.cnblogs.com/inchbyinch/p/11980247.html

时间: 2024-10-16 11:08:06

CNN基础二:使用预训练网络提取图像特征的相关文章

原来CNN是这样提取图像特征的。。。

对于即将到来的人工智能时代,作为一个有理想有追求的程序员,不懂深度学习(Deep Learning)这个超热的领域,会不会感觉马上就out了?作为机器学习的一个分支,深度学习同样需要计算机获得强大的学习能力,那么问题来了,我们究竟要计算机学习什么东西?答案当然是图像特征了.将一张图像看做是一个个像素值组成的矩阵,那么对图像的分析就是对矩阵的数字进行分析,而图像的特征,就隐藏在这些数字规律中.深度学习对外推荐自己的一个很重要的点--深度学习能够自动提取特征.本文主要介绍卷积层提取特征的原理过程,文

[转] 轻松使用多种预训练卷积网络抽取图像特征

选自GitHub,机器之心整理. 最近 GitHub 有一个非常有意思的项目,它可以使用多种预训练 TensorFLow 模型计算图像特征.对于每一个模型,它们都会输出最后的全连接层,即 AlexNet 的第七个全连接层.VGG_19 的第 8 个全连接层等.这些层级将最终抽取出图像的特征,并能进一步用于图像分类和聚类等.机器之心简要地介绍了该项目,并测试了使用Inception_V1预训练模型抽取图像特征. 项目地址:https://github.com/cameronfabbri/Compu

CNN----卷积为何能提取图像特征

一.曲线过滤器 二.过滤器作用于图像 对于过滤器识别的特征,将计算得到很大的值 不符合过滤器的特征,将得到很小的值 三.高层特征 对原图进行的第一次卷积,经过池化以后得到的特征图,是特征激活图.第二层的卷积,就是被激活特征的组合 原文地址:https://www.cnblogs.com/mimandehuanxue/p/9057262.html

fine-tuning:预训练中的迁移

什么是fine-tuning? 概述 在实践中,由于数据集不够大,很少有人从头开始训练网络.常见的做法是使用预训练的网络(例如在ImageNet上训练的分类1000类的网络)来重新fine-tuning(也叫微调),或者当做特征提取器. 以下是常见的两类迁移学习场景: 卷积网络当做特征提取器.使用在ImageNet上预训练的网络,去掉最后的全连接层,剩余部分当做特征提取器(例如AlexNet在最后分类器前,是4096维的特征向量).这样提取的特征叫做CNN codes.得到这样的特征后,可以使用

【猫狗数据集】使用预训练的resnet18模型

数据集下载地址: 链接:https://pan.baidu.com/s/1l1AnBgkAAEhh0vI5_loWKw提取码:2xq4 创建数据集:https://www.cnblogs.com/xiximayou/p/12398285.html 读取数据集:https://www.cnblogs.com/xiximayou/p/12422827.html 进行训练:https://www.cnblogs.com/xiximayou/p/12448300.html 保存模型并继续进行训练:htt

CNN基础模型总结

之前被问到了CNN类基础模型的一些特性,比如1X1卷积,还有经典卷积网络发展及为什么采用此结构,结果被问住了.学习过程中其实没有做过更深层次的思考,比如为什么会选择这种架构,可不可以采用其他结构来替换,只是会用一些经典模型.到最后别人问几个为什么就不知道了.基础还是要加强呀.现在先参考别人的专栏还有论文总结一下. 参考: https://www.cnblogs.com/guoyaohua/p/8534077.html  https://zhuanlan.zhihu.com/p/50754671

预训练中Word2vec,ELMO,GPT与BERT对比

预训练 先在某个任务(训练集A或者B)进行预先训练,即先在这个任务(训练集A或者B)学习网络参数,然后存起来以备后用.当我们在面临第三个任务时,网络可以采取相同的结构,在较浅的几层,网络参数可以直接加载训练集A或者B训练好的参数,其他高层仍然随机初始化.底层参数有两种方式:frozen,即预训练的参数固定不变,fine-tuning,即根据现在的任务调整预训练的参数. 优势: 1.当前任务数据量少,难以训练更多的网络参数,可以加载预训练的模型,然后根据当前的任务对参数进行fine-tuning,

卷积神经网络(CNN)基础介绍

本文是对卷积神经网络的基础进行介绍,主要内容包含卷积神经网络概念.卷积神经网络结构.卷积神经网络求解.卷积神经网络LeNet-5结构分析.卷积神经网络注意事项. 一.卷积神经网络概念 上世纪60年代.Hubel等人通过对猫视觉皮层细胞的研究,提出了感受野这个概念.到80年代.Fukushima在感受野概念的基础之上提出了神经认知机的概念,能够看作是卷积神经网络的第一个实现网络,神经认知机将一个视觉模式分解成很多子模式(特征),然后进入分层递阶式相连的特征平面进行处理,它试图将视觉系统模型化,使其

CNN基础及开发环境搭建(综合参考)

CNN基础及环境搭建 Author:王帅:Mail:[email protected] 目前,深度学习在解决图像分类,语音识别等问题上获得了已知的最优结果,该系列算法越来越受到学术界和工业界的重视.何为深度学习?一个直观的解释是如果一个机器学习算法在建模的过程中使用了多层的自动特征表示,则该机器学习算法可以称之为深度学习算法,也就是该机器学习算法可以自动地计算特征的特征表示.而卷积神经网络(以下简称为CNN)则是深度学习中最基础且有效的算法,CNN虽然最早由KunihikoFukushima提出