TensorFlow 1.x 深度学习秘籍:1~5(2)

简介: TensorFlow 1.x 深度学习秘籍:1~5(2)

TensorFlow 1.x 深度学习秘籍:1~5(1)https://developer.aliyun.com/article/new/ai#ZqvnG

五、高级卷积神经网络

在本章中,我们将讨论如何将卷积神经网络CNN)用于除图像以外的领域中的深度学习。 我们的注意力将首先集中在文本分析和自然语言处理NLP)上。 在本章中,我们将介绍一些用于以下方面的方法:

  • 创建卷积网络进行情感分析
  • 检查 VGG 预建网络学习了哪些过滤器
  • 使用 VGGNet,ResNet,Inception 和 Xception 对图像进行分类
  • 复用预先构建的深度学习模型来提取特征
  • 用于迁移学习的非常深的 Inception-v3 网络
  • 使用膨胀的 ConvNets,WaveNet 和 NSynth 生成音乐
  • 回答有关图像的问题(可视化问答)
  • 使用预训练网络通过六种不同方式来分类视频

介绍

在上一章中,我们了解了如何将 ConvNets 应用于图像。 在本章中,我们将类似的思想应用于文本。

文本和图像有什么共同点? 乍一看,很少。 但是,如果我们将句子或文档表示为矩阵,则此矩阵与每个单元都是像素的图像矩阵没有区别。 因此,下一个问题是,我们如何将文本表示为矩阵? 好吧,这很简单:矩阵的每一行都是一个向量,代表文本的基本单位。 当然,现在我们需要定义什么是基本单位。 一个简单的选择就是说基本单位是一个字符。 另一个选择是说基本单位是一个单词,另一个选择是将相似的单词聚合在一起,然后用代表符号表示每个聚合(有时称为簇或嵌入)。

请注意,无论我们的基本单位采用哪种具体选择,我们都需要从基本单位到整数 ID 的 1:1 映射,以便可以将文本视为矩阵。 例如,如果我们有一个包含 10 行文本的文档,并且每行都是 100 维嵌入,那么我们将用10 x 100的矩阵表示文本。 在这个非常特殊的图像中,如果该句子x包含位置y表示的嵌入,则打开像素。 您可能还会注意到,文本实际上不是矩阵,而是向量,因为位于文本相邻行中的两个单词几乎没有共同点。 确实,与图像的主要区别在于,相邻列中的两个像素最有可能具有某种相关性。

现在您可能会想:我知道您将文本表示为向量,但是这样做会使我们失去单词的位置,而这个位置应该很重要,不是吗?

好吧,事实证明,在许多实际应用中,知道一个句子是否包含特定的基本单位(一个字符,一个单词或一个合计)是非常准确的信息,即使我们不记住句子中的确切位置也是如此。 基本单元位于。

创建用于情感分析的卷积网络

在本秘籍中,我们将使用 TFLearn 创建基于 CNN 的情感分析深度学习网络。 如上一节所述,我们的 CNN 将是一维的。 我们将使用 IMDb 数据集,用于训练的 45,000 个高度受欢迎的电影评论和用于测试的 5,000 个集合。

准备

TFLearn 具有用于自动从网络下载数据集并促进卷积网络创建的库,因此让我们直接看一下代码。

操作步骤

我们按以下步骤进行:

  1. 导入 TensorFlow tflearn和构建网络所需的模块。 然后,导入 IMDb 库并执行一键编码和填充:
import tensorflow as tf
import tflearn
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.conv import conv_1d, global_max_pool
from tflearn.layers.merge_ops import merge
from tflearn.layers.estimator import regression
from tflearn.data_utils import to_categorical, pad_sequences
from tflearn.datasets import imdb
  1. 加载数据集,将句子填充到最大长度为 0 的位置,并对标签执行两个编码,分别对应于真值和假值的两个值。 注意,参数n_words是要保留在词汇表中的单词数。 所有多余的单词都设置为未知。 另外,请注意trainXtrainY是稀疏向量,因为每个评论很可能包含整个单词集的子集:
# IMDb Dataset loading
train, test, _ = imdb.load_data(path='imdb.pkl', n_words=10000,
valid_portion=0.1)
trainX, trainY = train
testX, testY = test
#pad the sequence
trainX = pad_sequences(trainX, maxlen=100, value=0.)
testX = pad_sequences(testX, maxlen=100, value=0.)
#one-hot encoding
trainY = to_categorical(trainY, nb_classes=2)
testY = to_categorical(testY, nb_classes=2)
  1. 打印一些维度以检查刚刚处理的数据并了解问题的维度是什么:
print ("size trainX", trainX.size)
print ("size testX", testX.size)
print ("size testY:", testY.size)
print ("size trainY", trainY.size)
size trainX 2250000
 size testX 250000
 size testY: 5000
 site trainY 45000
  1. 为数据集中包含的文本构建嵌入。 就目前而言,将此步骤视为一个黑盒子,该黑盒子接受这些单词并将它们映射到聚合(群集)中,以便相似的单词可能出现在同一群集中。 请注意,先前步骤的词汇是离散且稀疏的。 通过嵌入,我们将创建一个映射,该映射会将每个单词嵌入到连续的密集向量空间中。 使用此向量空间表示将为我们提供词汇表的连续,分布式表示。 当我们谈论 RNN 时,将详细讨论如何构建嵌入:
# Build an embedding
network = input_data(shape=[None, 100], name='input')
network = tflearn.embedding(network, input_dim=10000, output_dim=128)
  1. 建立一个合适的convnet。 我们有三个卷积层。 由于我们正在处理文本,因此我们将使用一维卷积网络,并且各层将并行运行。 每层采用大小为 128 的张量(嵌入的输出),并应用有效填充,激活函数 ReLU 和 L2 regularizer的多个滤波器(分别为 3、4、5)。 然后,将每个层的输出与合并操作连接在一起。 此后,添加一个最大池层,然后以 50% 的概率进行删除。 最后一层是具有 softmax 激活的完全连接层:
#Build the convnet
branch1 = conv_1d(network, 128, 3, padding='valid', activation='relu', regularizer="L2")
branch2 = conv_1d(network, 128, 4, padding='valid', activation='relu', regularizer="L2")
branch3 = conv_1d(network, 128, 5, padding='valid', activation='relu', regularizer="L2")
network = merge([branch1, branch2, branch3], mode='concat', axis=1)
network = tf.expand_dims(network, 2)
network = global_max_pool(network)
network = dropout(network, 0.5)
network = fully_connected(network, 2, activation='softmax')
  1. 学习阶段意味着使用categorical_crossentropy作为损失函数的 Adam 优化器:
network = regression(network, optimizer='adam', learning_rate=0.001,
loss='categorical_crossentropy', name='target')
  1. 然后,我们使用batch_size = 32运行训练,并观察训练和验证集达到的准确率。 如您所见,在预测电影评论所表达的情感方面,我们能够获得 79% 的准确率:
# Training
model = tflearn.DNN(network, tensorboard_verbose=0)
model.fit(trainX, trainY, n_epoch = 5, shuffle=True, validation_set=(testX, testY), show_metric=True, batch_size=32)
Training Step: 3519 | total loss: 0.09738 | time: 85.043s
 | Adam | epoch: 005 | loss: 0.09738 - acc: 0.9747 -- iter: 22496/22500
 Training Step: 3520 | total loss: 0.09733 | time: 86.652s
 | Adam | epoch: 005 | loss: 0.09733 - acc: 0.9741 | val_loss: 0.58740 - val_acc: 0.7944 -- iter: 22500/22500
 --

工作原理

用于句子分类的卷积神经网络,Yoon Kim,EMNLP 2014。 请注意,由于筛选器窗口对连续单词进行操作,因此本文提出的模型保留了一些有关位置的信息。 从论文中提取的以下图像以图形方式表示了网络之外的主要直觉。 最初,文本被表示为基于标准嵌入的向量,从而为我们提供了一维密集空间中的紧凑表示。 然后,使用多个标准一维卷积层处理矩阵。

请注意,模型使用多个过滤器(窗口大小不同)来获取多个特征。 之后,进行最大池操作,其思想是捕获最重要的特征-每个特征图的最大值。 为了进行正则化,该文章建议在倒数第二层上采用对权重向量的 L2 范数有约束的丢弃项。 最后一层将输出情感为正或负。

为了更好地理解该模型,有以下几点观察:

  • 过滤器通常在连续空间上卷积。 对于图像,此空间是像素矩阵表示形式,在高度和宽度上在空间上是连续的。 对于文本而言,连续空间无非是连续单词自然产生的连续尺寸。 如果仅使用单次编码表示的单词,则空间稀疏;如果使用嵌入,则由于聚集了相似的单词,因此生成的空间密集。
  • 图像通常具有三个通道(RGB),而文本自然只有一个通道,因为我们无需表示颜色。

更多

论文《用于句子分类的卷积神经网络》(Yoon Kim,EMNLP 2014)进行了广泛的实验。 尽管对超参数的调整很少,但具有一层卷积的简单 CNN 在句子分类方面的表现却非常出色。 该论文表明,采用一组静态嵌入(将在我们谈论 RNN 时进行讨论),并在其之上构建一个非常简单的卷积网络,实际上可以显着提高情感分析的表现:

如图所示的模型架构示例

使用 CNN 进行文本分析是一个活跃的研究领域。 我建议看看以下文章:

  • 《从头开始理解文本》(张翔,Yann LeCun)。 本文演示了我们可以使用 CNN 将深度学习应用于从字符级输入到抽象文本概念的文本理解。 作者将 CNN 应用于各种大规模数据集,包括本体分类,情感分析和文本分类,并表明它们可以在不了解单词,词组,句子或任何其他句法或语义结构的情况下实现惊人的表现。 一种人类的语言。 这些模型适用于英文和中文。

检查 VGG 预建网络了解了哪些过滤器

在本秘籍中,我们将使用 keras-vis,这是一个外部 Keras 包,用于直观检查预建的 VGG16 网络从中学到了什么不同的过滤器。 这个想法是选择一个特定的 ImageNet 类别,并了解 VGG16 网络如何学会代表它。

准备

第一步是选择用于在 ImageNet 上训练 VGG16 的特定类别。 假设我们采用类别 20,它对应于下图中显示的美国北斗星鸟:

美国北斗星的一个例子

可以在网上找到 ImageNet 映射作为 python 泡菜字典,其中 ImageNet 1000 类 ID 映射到了人类可读的标签。

操作步骤

我们按以下步骤进行:

  1. 导入 matplotlib 和 keras-vis 使用的模块。 此外,还导入预构建的 VGG16 模块。 Keras 使处理此预建网络变得容易:
from matplotlib import pyplot as plt
from vis.utils import utils
from vis.utils.vggnet import VGG16
from vis.visualization import visualize_class_activation
  1. 通过使用 Keras 中包含的并经过 ImageNet 权重训练的预构建层来访问 VGG16 网络:
# Build the VGG16 network with ImageNet weights
model = VGG16(weights='imagenet', include_top=True)
model.summary()
print('Model loaded.')
  1. 这就是 VGG16 网络在内部的外观。 我们有许多卷积网络,与 2D 最大池化交替使用。 然后,我们有一个展开层,然后是三个密集层。 最后一个称为预测,并且这一层应该能够检测到高级特征,例如人脸或我们的鸟类形状。 请注意,顶层已明确包含在我们的网络中,因为我们想可视化它学到的知识:
_________________________________________________________________
 Layer (type) Output Shape Param #
 =================================================================
 input_2 (InputLayer) (None, 224, 224, 3) 0
 _________________________________________________________________
 block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
 _________________________________________________________________
 block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
 _________________________________________________________________
 block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
 _________________________________________________________________
 block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
 _________________________________________________________________
 block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
 _________________________________________________________________
 block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
 _________________________________________________________________
 block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
 _________________________________________________________________
 block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
 _________________________________________________________________
 block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
 _________________________________________________________________
 block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
 _________________________________________________________________
 block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
 _________________________________________________________________
 block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
 _________________________________________________________________
 block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
 _________________________________________________________________
 block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
 _________________________________________________________________
 block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
 _________________________________________________________________
 block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
 _________________________________________________________________
 block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
 _________________________________________________________________
 block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
 _________________________________________________________________
 flatten (Flatten) (None, 25088) 0
 _________________________________________________________________
 fc1 (Dense) (None, 4096) 102764544
 _________________________________________________________________
 fc2 (Dense) (None, 4096) 16781312
 _________________________________________________________________
 predictions (Dense) (None, 1000) 4097000
 =================================================================
 Total params: 138,357,544
 Trainable params: 138,357,544
 Non-trainable params: 0
 _________________________________________________________________
 Model loaded.

从外观上看,网络可以如下图所示:

VGG16 网络

  1. 现在,让我们着重于通过关注 American Dipper(ID 20)来检查最后一个预测层的内部外观:
layer_name = 'predictions'
layer_idx = [idx for idx, layer in enumerate(model.layers) if layer.name == layer_name][0]
# Generate three different images of the same output index.
vis_images = []
for idx in [20, 20, 20]:
img = visualize_class_activation(model, layer_idx, filter_indices=idx, max_iter=500)
img = utils.draw_text(img, str(idx))
vis_images.append(img)
  1. 让我们在给定特征的情况下显示特定层的生成图像,并观察网络如何在内部看到美国北斗星鸟的概念:

因此,这就是神经网络在内部代表鸟类的方式。 这是一种令人毛骨悚然的形象,但我发誓没有为网络本身提供任何特定种类的人造药物! 这正是这种特殊的人工网络自然学到的东西。

  1. 您是否仍然想了解更多? 好吧,让我们选择一个较早的层,并代表网络如何在内部看到相同的American Dipper训练类别:
layer_name = 'block3_conv1'
layer_idx = [idx for idx, layer in enumerate(model.layers) if layer.name == layer_name][0]
vis_images = []
for idx in [20, 20, 20]:
img = visualize_class_activation(model, layer_idx, filter_indices=idx, max_iter=500)
img = utils.draw_text(img, str(idx))
vis_images.append(img)
stitched = utils.stitch_images(vis_images)
plt.axis('off')
plt.imshow(stitched)
plt.title(layer_name)
plt.show()

以下是上述代码的输出:

不出所料,该特定层正在学习非常基本的特征,例如曲线。 但是,卷积网络的真正力量在于,随着我们对模型的深入研究,网络会推断出越来越复杂的特征。

工作原理

密集层的 keras-vis 可视化的关键思想是生成一个输入图像,该图像最大化与鸟类类相对应的最终密集层输出。 因此,实际上该模块的作用是解决问题。 给定具有权重的特定训练密集层,将生成一个新的合成图像,它最适合该层本身。

每个转换滤波器都使用类似的想法。 在这种情况下,请注意,由于卷积网络层在原始像素上运行,因此可以通过简单地可视化其权重来解释它。 后续的卷积过滤器对先前的卷积过滤器的输出进行操作,因此直接可视化它们不一定很有解释性。 但是,如果我们独立地考虑每一层,我们可以专注于仅生成可最大化滤波器输出的合成输入图像。

更多

GitHub 上的 keras-vis 存储库提供了一组很好的可视化示例,这些示例说明了如何内部检查网络,包括最近的显着性映射,其目的是在图像经常包含其他元素(例如草)时检测图像的哪个部分对特定类别(例如老虎)的训练贡献最大。 种子文章是《深度卷积网络:可视化图像分类模型和显着性图》(Karen Simonyan,Andrea Vedaldi,Andrew Zisserman),并在下面报告了从 Git 存储库中提取的示例,在该示例中,网络可以自行了解定义为老虎的图像中最突出的部分是:

显着性映射的示例

将 VGGNet,ResNet,Inception 和 Xception 用于图像分类

图像分类是典型的深度学习应用。 由于 ImageNet 图像数据库,该任务的兴趣有了最初的增长。 它按照 WordNet 层次结构(目前仅是名词)来组织,其中每个节点都由成百上千的图像描绘。 更准确地说,ImageNet 旨在将图像标记和分类为将近 22,000 个单独的对象类别。 在深度学习的背景下,ImageNet 通常指的是 ImageNet 大规模视觉识别挑战,或简称 ILSVRC 中包含的工作。在这种情况下,目标是训练一个模型,该模型可以将输入图像分类为 1,000 个单独的对象类别。 在此秘籍中,我们将使用超过 120 万个训练图像,50,000 个验证图像和 100,000 个测试图像的预训练模型。

VGG16 和 VGG19

《用于大型图像识别的超深度卷积网络》(Karen Simonyan,Andrew Zisserman,2014 年)中,引入了 VGG16 和 VGG19。 该网络使用3×3卷积层堆叠并与最大池交替,两个 4096 个全连接层,然后是 softmax 分类器。 16 和 19 代表网络中权重层的数量(列 D 和 E):

一个非常深的网络配置示例

在 2015 年,拥有 16 或 19 层就足以考虑网络的深度,而今天(2017 年)我们达到了数百层。 请注意,VGG 网络的训练速度非常慢,并且由于末端的深度和完全连接的层数,它们需要较大的权重空间。

ResNet

ResNet 已在《用于图像识别的深度残差学习》(何开明,张向宇,任少青,孙健,2015)中引入。 该网络非常深,可以使用称为残差模块的标准网络组件使用标准的随机下降梯度进行训练,然后使用该网络组件组成更复杂的网络(该网络在网络中称为子网络)。

与 VGG 相比,ResNet 更深,但是模型的大小更小,因为使用了全局平均池化操作而不是全密层。

Inception

《重新思考计算机视觉的初始架构》(Christian Szegedy,Vincent Vanhoucke,Sergey Ioffe,Jonathon Shlens,Zbigniew Wojna,2015 年)中引入了 Inception 。关键思想是在同一模块中具有多种大小的卷积作为特征提取并计算1×13×35×5卷积。 这些滤波器的输出然后沿着通道尺寸堆叠,并发送到网络的下一层。 下图对此进行了描述:

在“重新思考计算机视觉的 Inception 架构”中描述了 Inception-v3,而在《Inception-v4,Inception-ResNet 和残余连接对学习的影响》(Szegedy,Sergey Ioffe,Vincent Vanhoucke,Alex Alemi,2016 年)中描述了 Inception-v4。

Xception

Xception 是 Inception 的扩展,在《Xception:具有深度可分离卷积的深度学习》(FrançoisChollet,2016 年)中引入。 Xception 使用一种称为深度可分离卷积运算的新概念,该概念使其在包含 3.5 亿张图像和 17,000 个类别的大型图像分类数据集上的表现优于 Inception-v3。 由于 Xception 架构具有与 Inception-v3 相同数量的参数,因此表现的提高并不是由于容量的增加,而是由于模型参数的更有效使用。

准备

此秘籍使用 Keras,因为该框架已预先完成了上述模块的实现。 Keras 首次使用时会自动下载每个网络的权重,并将这些权重存储在本地磁盘上。 换句话说,您不需要重新训练网络,而是可以利用互联网上已经可用的训练。 在您希望将网络分类为 1000 个预定义类别的假设下,这是正确的。 在下一个秘籍中,我们将了解如何从这 1,000 个类别开始,并通过称为迁移学习的过程将它们扩展到自定义集合。

操作步骤

我们按以下步骤进行:

  1. 导入处理和显示图像所需的预建模型和其他模块:
from keras.applications import ResNet50
from keras.applications import InceptionV3
from keras.applications import Xception # TensorFlow ONLY
from keras.applications import VGG16
from keras.applications import VGG19
from keras.applications import imagenet_utils
from keras.applications.inception_v3 import preprocess_input
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import load_img
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
from PIL import Image
%matplotlib inline
  1. 定义用于记忆用于训练网络的图像大小的映射。 这些是每个模型的众所周知的常数:
MODELS = {
"vgg16": (VGG16, (224, 224)),
"vgg19": (VGG19, (224, 224)),
"inception": (InceptionV3, (299, 299)),
"xception": (Xception, (299, 299)), # TensorFlow ONLY
"resnet": (ResNet50, (224, 224))
}
  1. 定义用于加载和转换每个图像的辅助函数。 注意,预训练网络已在张量上训练,该张量的形状还包括batch_size的附加维度。 因此,我们需要将此尺寸添加到图像中以实现兼容性:
def image_load_and_convert(image_path, model):
pil_im = Image.open(image_path, 'r')
imshow(np.asarray(pil_im))
# initialize the input image shape
# and the pre-processing function (this might need to be changed
inputShape = MODELS[model][1]
preprocess = imagenet_utils.preprocess_input
image = load_img(image_path, target_size=inputShape)
image = img_to_array(image)
# the original networks have been trained on an additional
# dimension taking into account the batch size
# we need to add this dimension for consistency
# even if we have one image only
image = np.expand_dims(image, axis=0)
image = preprocess(image)
return image
  1. 定义用于对图像进行分类的辅助函数,并在预测上循环,并显示 5 级预测以及概率:
def classify_image(image_path, model):
img = image_load_and_convert(image_path, model)
Network = MODELS[model][0]
model = Network(weights="imagenet")
preds = model.predict(img)
P = imagenet_utils.decode_predictions(preds)
# loop over the predictions and display the rank-5 predictions
# along with probabilities
for (i, (imagenetID, label, prob)) in enumerate(P[0]):
print("{}. {}: {:.2f}%".format(i + 1, label, prob * 100))

5.然后开始测试不同类型的预训练网络:

classify_image("images/parrot.jpg", "vgg16")

接下来,您将看到具有相应概率的预测列表:

1.金刚鹦鹉:99.92%

2.美洲豹:0.03%

3.澳洲鹦鹉:0.02%

4.蜂食者:0.02%

5.巨嘴鸟:0.00%

金刚鹦鹉的一个例子

classify_image("images/parrot.jpg", "vgg19")

1.金刚鹦鹉:99.77%

2.鹦鹉:0.07%

3.巨嘴鸟:0.06%

4.犀鸟:0.05%

5.贾卡马尔:0.01%

classify_image("images/parrot.jpg", "resnet")

1.金刚鹦鹉:97.93%

2.孔雀:0.86%

3.鹦鹉:0.23%

4. j:0.12%

5.杰伊:0.12%

classify_image("images/parrot_cropped1.jpg", "resnet")

1.金刚鹦鹉:99.98%

2.鹦鹉:0.00%

3.孔雀:0.00%

4.硫凤头鹦鹉:0.00%

5.巨嘴鸟:0.00%

classify_image("images/incredible-hulk-180.jpg", "resnet")

1. comic_book:99.76%

2. book_jacket:0.19%

3.拼图游戏:0.05%

4.菜单:0.00%

5.数据包:0.00%

如中所示的漫画分类示例

classify_image("images/cropped_panda.jpg", "resnet")

大熊猫:99.04%

2.英迪尔:0.59%

3.小熊猫:0.17%

4.长臂猿:0.07%

5. titi:0.05%

classify_image("images/space-shuttle1.jpg", "resnet")

1.航天飞机:92.38%

2.三角恐龙:7.15%

3.战机:0.11%

4.牛仔帽:0.10%

5.草帽:0.04%

classify_image("images/space-shuttle2.jpg", "resnet")

1.航天飞机:99.96%

2.导弹:0.03%

3.弹丸:0.00%

4.蒸汽机车:0.00%

5.战机:0.00%

classify_image("images/space-shuttle3.jpg", "resnet")

1.航天飞机:93.21%

2.导弹:5.53%

3.弹丸:1.26%

4.清真寺:0.00%

5.信标:0.00%

classify_image("images/space-shuttle4.jpg", "resnet")

1.航天飞机:49.61%

2.城堡:8.17%

3.起重机:6.46%

4.导弹:4.62%

5.航空母舰:4.24%

请注意,可能会出现一些错误。 例如:

classify_image("images/parrot.jpg", "inception")

1.秒表:100.00%

2.貂皮:0.00%

3.锤子:0.00%

4.黑松鸡:0.00%

5.网站:0.00%

classify_image("images/parrot.jpg", "xception")

1.背包:56.69%

2.军装:29.79%

3.围兜:8.02%

4.钱包:2.14%

5.乒乓球:1.52%

  1. 定义一个辅助函数,用于显示每个预构建和预训练网络的内部架构:
def print_model(model):
print ("Model:",model)
Network = MODELS[model][0]
model = Network(weights="imagenet")
model.summary()
print_model('vgg19')
('Model:', 'vgg19')
 _________________________________________________________________
 Layer (type) Output Shape Param #
 =================================================================
 input_14 (InputLayer) (None, 224, 224, 3) 0
 _________________________________________________________________
 block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
 _________________________________________________________________
 block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
 _________________________________________________________________
 block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
 _________________________________________________________________
 block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
 _________________________________________________________________
 block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
 _________________________________________________________________
 block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
 _________________________________________________________________
 block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
 _________________________________________________________________
 block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
 _________________________________________________________________
 block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
 _________________________________________________________________
 block3_conv4 (Conv2D) (None, 56, 56, 256) 590080
 _________________________________________________________________
 block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
 _________________________________________________________________
 block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
 _________________________________________________________________
 block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
 _________________________________________________________________
 block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
 _________________________________________________________________
 block4_conv4 (Conv2D) (None, 28, 28, 512) 2359808
 _________________________________________________________________
 block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
 _________________________________________________________________
 block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
 _________________________________________________________________
 block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
 _________________________________________________________________
 block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
 _________________________________________________________________
 block5_conv4 (Conv2D) (None, 14, 14, 512) 2359808
 _________________________________________________________________
 block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
 _________________________________________________________________
 flatten (Flatten) (None, 25088) 0
 _________________________________________________________________
 fc1 (Dense) (None, 4096) 102764544
 _________________________________________________________________
 fc2 (Dense) (None, 4096) 16781312
 _________________________________________________________________
 predictions (Dense) (None, 1000) 4097000
 =================================================================
 Total params: 143,667,240
 Trainable params: 143,667,240
 Non-trainable params: 0

工作原理

我们使用了 Keras 应用,预训练的 Keras 学习模型,该模型随预训练的权重一起提供。 这些模型可用于预测,特征提取和微调。 在这种情况下,我们将模型用于预测。 我们将在下一个秘籍中看到如何使用模型进行微调,以及如何在最初训练模型时最初不可用的数据集上构建自定义分类器。

更多

截至 2017 年 7 月,Inception-v4 尚未在 Keras 中直接提供,但可以作为单独的模块在线下载。 安装后,该模块将在首次使用时自动下载砝码。

AlexNet 是最早的堆叠式深层网络之一,它仅包含八层,前五层是卷积层,然后是全连接层。 该网络是在 2012 年提出的,明显优于第二名(前五名的错误率为 16%,而第二名的错误率为 26% )。

关于深度神经网络的最新研究主要集中在提高准确率上。 较小的 DNN 架构具有同等的准确率,至少具有三个优点:

  • 较小的 CNN 在分布式训练期间需要较少的跨服务器通信。
  • 较小的 CNN 需要较少的带宽才能将新模型从云导出到提供模型的位置。
  • 较小的 CNN 在具有有限内存的 FPGA 和其他硬件上部署更可行。 为了提供所有这些优点,SqueezeNet 在论文 SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size 中提出。 SqueezeNet 通过减少 50 倍的参数在 ImageNet 上达到 AlexNet 级别的准确率。 此外,借助模型压缩技术,我们可以将 SqueezeNet 压缩到小于 0.5 MB(比 AlexNet 小 510 倍)。 Keras 将 SqueezeNet 作为单独的模块在线实现

复用预建的深度学习模型来提取特征

在本秘籍中,我们将看到如何使用深度学习来提取相关特征

准备

一个非常简单的想法是通常使用 VGG16 和 DCNN 进行特征提取。 该代码通过从特定层提取特征来实现该想法。

操作步骤

我们按以下步骤进行:

  1. 导入处理和显示图像所需的预建模型和其他模块:
from keras.applications.vgg16 import VGG16
from keras.models import Model
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import numpy as np
  1. 从网络中选择一个特定的层,并获得作为输出生成的特征:
# pre-built and pre-trained deep learning VGG16 model
base_model = VGG16(weights='imagenet', include_top=True)
for i, layer in enumerate(base_model.layers):
print (i, layer.name, layer.output_shape)
# extract features from block4_pool block
model =
Model(input=base_model.input, output=base_model.get_layer('block4_pool').output)
  1. 提取给定图像的特征,如以下代码片段所示:
img_path = 'cat.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
# get the features from this block
features = model.predict(x)

工作原理

现在,您可能想知道为什么我们要从 CNN 的中间层提取特征。 关键的直觉是:随着网络学会将图像分类,各层学会识别进行最终分类所必需的特征。

较低的层标识较低阶的特征(例如颜色和边缘),较高的层将这些较低阶的特征组合为较高阶的特征(例如形状或对象)。 因此,中间层具有从图像中提取重要特征的能力,并且这些特征更有可能有助于不同种类的分类。

这具有多个优点。 首先,我们可以依靠公开提供的大规模训练,并将这种学习迁移到新颖的领域。 其次,我们可以节省昂贵的大型训练时间。 第三,即使我们没有针对该领域的大量训练示例,我们也可以提供合理的解决方案。 对于手头的任务,我们也有一个很好的起始网络形状,而不是猜测它。

用于迁移学习的非常深的 InceptionV3 网络

迁移学习是一种非常强大的深度学习技术,在不同领域中有更多应用。 直觉非常简单,可以用类推来解释。 假设您想学习一种新的语言,例如西班牙语,那么从另一种语言(例如英语)已经知道的内容开始可能会很有用。

按照这种思路,计算机视觉研究人员现在通常使用经过预训练的 CNN 来生成新任务的表示形式,其中数据集可能不足以从头训练整个 CNN。 另一个常见的策略是采用经过预先训练的 ImageNet 网络,然后将整个网络微调到新颖的任务。

InceptionV3 Net 是 Google 开发的非常深入的卷积网络。 Keras 实现了整个网络,如下图所示,并且已在 ImageNet 上进行了预训练。 该模型的默认输入大小在三个通道上为299x299

ImageNet v3 的示例

准备

此框架示例受到 Keras 网站上在线提供的方案的启发。 我们假设在与 ImageNet 不同的域中具有训练数据集 D。 D 在输入中具有 1,024 个特征,在输出中具有 200 个类别。

操作步骤

我们可以按照以下步骤进行操作:

  1. 导入处理所需的预建模型和其他模块:
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras import backend as K
# create the base pre-trained model
base_model = InceptionV3(weights='imagenet', include_top=False)
  1. 我们使用训练有素的 Inception-v3,但我们不包括顶级模型,因为我们要在 D 上进行微调。顶层是具有 1,024 个输入的密集层,最后一个输出是具有 200 类输出的 softmax 密集层。 x = GlobalAveragePooling2D()(x)用于将输入转换为密集层要处理的正确形状。 实际上,base_model.output张量具有dim_ordering="th"的形状(样本,通道,行,列),dim_ordering="tf"具有(样本,行,列,通道),但是密集层需要GlobalAveragePooling2D计算(行,列)平均值,将它们转换为(样本,通道)。 因此,如果查看最后四层(在include_top=True中),则会看到以下形状:
# layer.name, layer.input_shape, layer.output_shape
('mixed10', [(None, 8, 8, 320), (None, 8, 8, 768), (None, 8, 8, 768), (None, 8, 8, 192)], (None, 8, 8, 2048))
('avg_pool', (None, 8, 8, 2048), (None, 1, 1, 2048))
('flatten', (None, 1, 1, 2048), (None, 2048))
('predictions', (None, 2048), (None, 1000))
  1. 当包含_top=False时,将除去最后三层并暴露mixed_10层,因此GlobalAveragePooling2D层将(None, 8, 8, 2048)转换为(None, 2048),其中(None, 2048)张量中的每个元素都是(None, 8, 8, 2048)张量中每个对应的(8, 8)张量的平均值:
# add a global spatial average pooling layer
 x = base_model.output
 x = GlobalAveragePooling2D()(x)
 # let's add a fully-connected layer as first layer
 x = Dense(1024, activation='relu')(x)
 # and a logistic layer with 200 classes as last layer
 predictions = Dense(200, activation='softmax')(x)
 # model to train
 model = Model(input=base_model.input, output=predictions)
  1. 所有卷积级别都经过预训练,因此我们在训练完整模型时将其冻结。
# i.e. freeze all convolutional Inception-v3 layers
for layer in base_model.layers:
layer.trainable = False
  1. 然后,对模型进行编译和训练几个周期,以便对顶层进行训练:
# compile the model (should be done *after* setting layers to non-trainable)
 model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
# train the model on the new data for a few epochs
 model.fit_generator(...)
  1. 然后我们冻结 Inception 中的顶层并微调 Inception 层。 在此示例中,我们冻结了前 172 层(要调整的超参数):
# we chose to train the top 2 inception blocks, i.e. we will freeze
 # the first 172 layers and unfreeze the rest:
 for layer in model.layers[:172]:
 layer.trainable = False
 for layer in model.layers[172:]:
 layer.trainable = True
  1. 然后重新编译模型以进行微调优化。 我们需要重新编译模型,以使这些修改生效:
# we use SGD with a low learning rate
 from keras.optimizers import SGD
 model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')
 # we train our model again (this time fine-tuning the top 2 inception blocks
 # alongside the top Dense layers
 model.fit_generator(...)

工作原理

现在,我们有了一个新的深度网络,该网络可以重用标准的 Inception-v3 网络,但可以通过迁移学习在新的域 D 上进行训练。 当然,有许多参数需要微调以获得良好的精度。 但是,我们现在正在通过迁移学习重新使用非常庞大的预训练网络作为起点。 这样,我们可以通过重复使用 Keras 中已经可用的内容来节省对机器进行训练的需求。

更多

截至 2017 年,“计算机视觉”问题意味着在图像中查找图案的问题可以视为已解决,并且此问题影响了我们的生活。 例如:

  • 《皮肤科医师对具有深层神经网络的皮肤癌的分类》(Andre Esteva,Brett Kuprel,Roberto A. Novoa,Justin Ko,Susan M. Swetter,Helen M. Blau & Sebastian Thrun,2017 年)使用 129450 个临床图像的数据集训练 CNN,该图像由 2032 种不同疾病组成。 他们在 21 个经过董事会认证的皮肤科医生的活检验证的临床图像上对结果进行了测试,并使用了两个关键的二元分类用例:角质形成细胞癌与良性脂溢性角化病; 恶性黑色素瘤与良性痣。 CNN 在这两项任务上均达到了与所有测试过的专家相同的表现,展示了一种能够对皮肤癌进行分类的,具有与皮肤科医生相当的能力的人工智能。
  • 论文《通过多视图深度卷积神经网络进行高分辨率乳腺癌筛查》(Krzysztof J. Geras,Stacey Wolfson,S。Gene Kim,Linda Moy,Kyunghyun Cho)承诺通过其创新的架构来改善乳腺癌的筛查过程,该架构可以处理四个标准视图或角度,而不会牺牲高分辨率。 与通常用于自然图像的 DCN 架构(其可处理224 x 224像素的图像)相反,MV-DCN 也能够使用2600 x 2000像素的分辨率。

TensorFlow 1.x 深度学习秘籍:1~5(3)https://developer.aliyun.com/article/1426764

相关文章
|
6天前
|
机器学习/深度学习 供应链 TensorFlow
深度学习实战营:TensorFlow+Python,打造你的数据驱动决策引擎
【9月更文挑战第13天】在数据爆炸时代,企业日益依赖精准分析进行决策。深度学习凭借其卓越的特征提取与模式识别能力,成为构建数据驱动决策引擎的关键技术。本项目通过TensorFlow和Python,利用LSTM构建零售业销量预测模型,优化库存管理和营销策略。首先确保安装TensorFlow,然后使用Keras API搭建模型,并通过训练、评估和部署流程,展示深度学习在数据驱动决策中的强大应用潜力,助力企业提升经营效率。
17 3
|
9天前
|
机器学习/深度学习 数据挖掘 TensorFlow
从数据小白到AI专家:Python数据分析与TensorFlow/PyTorch深度学习的蜕变之路
【9月更文挑战第10天】从数据新手成长为AI专家,需先掌握Python基础语法,并学会使用NumPy和Pandas进行数据分析。接着,通过Matplotlib和Seaborn实现数据可视化,最后利用TensorFlow或PyTorch探索深度学习。这一过程涉及从数据清洗、可视化到构建神经网络的多个步骤,每一步都需不断实践与学习。借助Python的强大功能及各类库的支持,你能逐步解锁数据的深层价值。
22 0
|
19天前
|
持续交付 测试技术 jenkins
JSF 邂逅持续集成,紧跟技术热点潮流,开启高效开发之旅,引发开发者强烈情感共鸣
【8月更文挑战第31天】在快速发展的软件开发领域,JavaServer Faces(JSF)这一强大的Java Web应用框架与持续集成(CI)结合,可显著提升开发效率及软件质量。持续集成通过频繁的代码集成及自动化构建测试,实现快速反馈、高质量代码、加强团队协作及简化部署流程。以Jenkins为例,配合Maven或Gradle,可轻松搭建JSF项目的CI环境,通过JUnit和Selenium编写自动化测试,确保每次构建的稳定性和正确性。
42 0
|
19天前
|
测试技术 数据库
探索JSF单元测试秘籍!如何让您的应用更稳固、更高效?揭秘成功背后的测试之道!
【8月更文挑战第31天】在 JavaServer Faces(JSF)应用开发中,确保代码质量和可维护性至关重要。本文详细介绍了如何通过单元测试实现这一目标。首先,阐述了单元测试的重要性及其对应用稳定性的影响;其次,提出了提高 JSF 应用可测试性的设计建议,如避免直接访问外部资源和使用依赖注入;最后,通过一个具体的 `UserBean` 示例,展示了如何利用 JUnit 和 Mockito 框架编写有效的单元测试。通过这些方法,不仅能够确保代码质量,还能提高开发效率和降低维护成本。
33 0
|
19天前
|
UED 开发者
哇塞!Uno Platform 数据绑定超全技巧大揭秘!从基础绑定到高级转换,优化性能让你的开发如虎添翼
【8月更文挑战第31天】在开发过程中,数据绑定是连接数据模型与用户界面的关键环节,可实现数据自动更新。Uno Platform 提供了简洁高效的数据绑定方式,使属性变化时 UI 自动同步更新。通过示例展示了基本绑定方法及使用 `Converter` 转换数据的高级技巧,如将年龄转换为格式化字符串。此外,还可利用 `BindingMode.OneTime` 提升性能。掌握这些技巧能显著提高开发效率并优化用户体验。
38 0
|
19天前
|
Apache 开发者 Java
Apache Wicket揭秘:如何巧妙利用模型与表单机制,实现Web应用高效开发?
【8月更文挑战第31天】本文深入探讨了Apache Wicket的模型与表单处理机制。Wicket作为一个组件化的Java Web框架,提供了多种模型实现,如CompoundPropertyModel等,充当组件与数据间的桥梁。文章通过示例介绍了模型创建及使用方法,并详细讲解了表单组件、提交处理及验证机制,帮助开发者更好地理解如何利用Wicket构建高效、易维护的Web应用程序。
14 0
|
19天前
|
机器学习/深度学习 人工智能 TensorFlow
深度学习入门:使用Python和TensorFlow构建你的第一个神经网络
【8月更文挑战第31天】 本文是一篇面向初学者的深度学习指南,旨在通过简洁明了的语言引导读者了解并实现他们的第一个神经网络。我们将一起探索深度学习的基本概念,并逐步构建一个能够识别手写数字的简单模型。文章将展示如何使用Python语言和TensorFlow框架来训练我们的网络,并通过直观的例子使抽象的概念具体化。无论你是编程新手还是深度学习领域的新兵,这篇文章都将成为你探索这个激动人心领域的垫脚石。
|
19天前
|
机器学习/深度学习 API TensorFlow
深入解析TensorFlow 2.x中的Keras API:快速搭建深度学习模型的实战指南
【8月更文挑战第31天】本文通过搭建手写数字识别模型的实例,详细介绍了如何利用TensorFlow 2.x中的Keras API简化深度学习模型构建流程。从环境搭建到数据准备,再到模型训练与评估,展示了Keras API的强大功能与易用性,适合初学者快速上手。通过简单的代码,即可完成卷积神经网络的构建与训练,显著降低了深度学习的技术门槛。无论是新手还是专业人士,都能从中受益,高效实现模型开发。
11 0
|
19天前
|
机器学习/深度学习 PyTorch TensorFlow
深度学习框架之争:全面解析TensorFlow与PyTorch在功能、易用性和适用场景上的比较,帮助你选择最适合项目的框架
【8月更文挑战第31天】在深度学习领域,选择合适的框架至关重要。本文通过开发图像识别系统的案例,对比了TensorFlow和PyTorch两大主流框架。TensorFlow由Google开发,功能强大,支持多种设备,适合大型项目和工业部署;PyTorch则由Facebook推出,强调灵活性和速度,尤其适用于研究和快速原型开发。通过具体示例代码展示各自特点,并分析其适用场景,帮助读者根据项目需求和个人偏好做出明智选择。
28 0
|
3月前
|
机器学习/深度学习 TensorFlow API
TensorFlow与Keras实战:构建深度学习模型
本文探讨了TensorFlow和其高级API Keras在深度学习中的应用。TensorFlow是Google开发的高性能开源框架,支持分布式计算,而Keras以其用户友好和模块化设计简化了神经网络构建。通过一个手写数字识别的实战案例,展示了如何使用Keras加载MNIST数据集、构建CNN模型、训练及评估模型,并进行预测。案例详述了数据预处理、模型构建、训练过程和预测新图像的步骤,为读者提供TensorFlow和Keras的基础实践指导。
253 59

热门文章

最新文章