TensorFlow 实战(八)(3)

简介: TensorFlow 实战(八)

TensorFlow 实战(八)(2)https://developer.aliyun.com/article/1522968

附录 B:计算机视觉

B.1 Grad-CAM:解释计算机视觉模型

Grad-CAM(代表梯度类激活映射)在第七章介绍过,是由 Ramprasaath R. Selvaraju 等人在“Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization”(arxiv.org/pdf/1610.02391.pdf)中介绍的一种深度神经网络模型解释技术。深度网络以其难以解释的特性而臭名昭著,因此被称为黑盒子。因此,我们必须进行一些分析,并确保模型按预期工作。

让我们在第七章实现的模型上刷新一下记忆:一个名为 InceptionResNet v2 的预训练模型,其顶部是一个具有 200 个节点的 softmax 分类器(即我们的图像分类数据集 TinyImageNet 中的类别数量相同;请参阅下面的列表)。

清单 B.1 我们在第七章定义的 InceptionResNet v2 模型

import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras.applications import InceptionResNetV2
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Input, Dense, Dropout
K.clear_session()
def get_inception_resnet_v2_pretrained():
    model = Sequential([                                       ❶
        Input(shape=(224,224,3)),                              ❷
        InceptionResNetV2(include_top=False, pooling='avg'),   ❸
        Dropout(0.4),                                          ❹
        Dense(200, activation='softmax')                       ❺
    ])
    loss = tf.keras.losses.CategoricalCrossentropy()
    adam = tf.keras.optimizers.Adam(learning_rate=0.0001)
    model.compile(loss=loss, optimizer=adam, metrics=['accuracy'])
    return model 
model = get_inception_resnet_v2_pretrained()
model.summary()

❶ 使用 Sequential API 定义一个模型。

❷ 定义一个输入层来接收大小为 224 × 224 × 3 的图像批次。

❸ 下载并使用预训练的 InceptionResNetV2 模型(不包括内置分类器)。

❹ 添加一个 dropout 层。

❺ 添加一个具有 200 个节点的新分类器层。

如果你打印此模型的摘要,你将得到以下输出:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
inception_resnet_v2 (Model)  (None, 1536)              54336736  
_________________________________________________________________
dropout (Dropout)            (None, 1536)              0         
_________________________________________________________________
dense (Dense)                (None, 200)               307400    
=================================================================
Total params: 54,644,136
Trainable params: 54,583,592
Non-trainable params: 60,544
_________________________________________________________________

如您所见,InceptionResNet v2 模型被视为我们模型中的单个层。换句话说,它是一个嵌套模型,其中外层模型(sequential)有一个内层模型(inception_resnet_v2)。但是我们需要更多的透明度,因为我们将要访问 inception_resnet_v2 模型内的特定层,以实现 Grad-CAM。因此,我们将“解开”或移除此嵌套,并且只描述模型的层。我们可以使用以下代码实现这一点:

K.clear_session()
model = load_model(os.path.join('models','inception_resnet_v2.h5'))
def unwrap_model(model):
    inception = model.get_layer('inception_resnet_v2')
    inp = inception.input
    out = model.get_layer('dropout')(inception.output)
    out = model.get_layer('dense')(out)
    return Model(inp, out)   
unwrapped_model = unwrap_model(model)
unwrapped_model.summary()

实质上我们正在做的是取现有模型并略微更改其输入。在取得现有模型后,我们将输入更改为 inception_resnet_v2 模型的输入层。然后,我们定义一个新模型(本质上使用与旧模型相同的参数)。然后你将看到以下输出。没有更多的模型在模型内部:

Model: "model"
___________________________________________________________________________
➥ ________________
Layer (type)                    Output Shape         Param #     Connected 
➥ to                     
===========================================================================
➥ ================
input_2 (InputLayer)            [(None, None, None,  0                                            
___________________________________________________________________________
➥ ________________
conv2d (Conv2D)                 (None, None, None, 3 864         
➥ input_2[0][0]                    
___________________________________________________________________________
➥ ________________
batch_normalization (BatchNorma (None, None, None, 3 96          
➥ conv2d[0][0]                     
___________________________________________________________________________
➥ ________________
activation (Activation)         (None, None, None, 3 0           
➥ batch_normalization[0][0]        
___________________________________________________________________________
➥ ________________
...
___________________________________________________________________________
➥ ________________
conv_7b (Conv2D)                (None, None, None, 1 3194880     
➥ block8_10[0][0]                  
___________________________________________________________________________
➥ ________________
conv_7b_bn (BatchNormalization) (None, None, None, 1 4608        
➥ conv_7b[0][0]                    
___________________________________________________________________________
➥ ________________
conv_7b_ac (Activation)         (None, None, None, 1 0           
➥ conv_7b_bn[0][0]                 
___________________________________________________________________________
➥ ________________
global_average_pooling2d (Globa (None, 1536)         0           
➥ conv_7b_ac[0][0]                 
___________________________________________________________________________
➥ ________________
dropout (Dropout)               (None, 1536)         0           
➥ global_average_pooling2d[0][0]   
___________________________________________________________________________
➥ ________________
dense (Dense)                   (None, 200)          307400      
➥ dropout[1][0]                    
===========================================================================
➥ ================
Total params: 54,644,136
Trainable params: 54,583,592
Non-trainable params: 60,544
___________________________________________________________________________
➥ ________________

接下来,我们将进行一次更改:向我们的模型引入一个新输出。请记住,我们使用功能 API 来定义我们的模型。这意味着我们可以在我们的模型中定义多个输出。我们需要的输出是 inception_resnet_v2 模型中最后一个卷积层产生的特征图。这是 Grad-CAM 计算的核心部分。您可以通过查看解开模型的模型摘要来获得最后一个卷积层的层名称:

last_conv_layer = 'conv_7b' # This is the name of the last conv layer of the model
grad_model = Model(
    inputs=unwrapped_model.inputs, 
    outputs=[
        unwrapped_model.get_layer(last_conv_layer).output,
        unwrapped_model.output
    ]    
)

有了我们的模型准备好后,让我们转向数据。我们将使用验证数据集来检查我们的模型。特别地,我们将编写一个函数(见清单 B.2)来接收以下内容:

  • image_path(str)- 数据集中图像的路径。
  • val_df(pd.DataFrame)—一个包含从图像名称到 wnid(即 WordNet ID)的映射的 pandas 数据框。请记住,wnid 是用于识别特定对象类的特殊编码。
  • class_indices(dict)—一个 wnid(字符串)到类别(0-199 之间的整数)的映射。这保留了关于哪个 wnid 在模型的最终输出层中由哪个索引表示的信息。
  • words(pd.DataFrame)—一个包含从 wnid 到类别的可读描述的映射的 pandas 数据框。

清单 B.2 检索转换后的图像、类别索引和人类可读标签

img_path = 'data/tiny-imagenet-200/val/images/val_434.JPEG'
val_df = pd.read_csv(                                                          ❶
    os.path.join('data','tiny-imagenet-200', 'val', 'val_annotations.txt'),
    sep='\t', index_col=0, header=None
)
with open(os.path.join('data','class_indices'),'rb') as f:                     ❷
    class_indices = pickle.load(f)
words = pd.read_csv(                                                           ❸
    os.path.join('data','tiny-imagenet-200', 'words.txt'), 
    sep='\t', index_col=0, header=None
)
def get_image_class_label(img_path, val_df, class_indices, words):
    """ Returns the normalized input, class (int) and the label name for a given image"""
    img = np.expand_dims(                                                      ❹
        np.asarray(
            Image.open(img_path).resize((224,224)                              ❺
    )
    img /= 127.5                                                               ❻
    img -= 1                                                                   ❻
    if img.ndim == 3:
        img = np.repeat(np.expand_dims(img, axis=-1), 3, axis=-1)              ❼
    _, img_name = os.path.split(img_path)
    wnid = val_df.loc[img_name,1]                                              ❽
    cls = class_indices[wnid]                                                  ❾
    label = words.loc[wnid, 1]                                                 ❿
    return img, cls, label
# Test the function with a test image
img, cls, label = get_image_class_label(img_path, val_df, class_indices, words)⓫

❶ 读取 val_annotations.txt。这将创建一个数据框,其中包含从图像文件名到 wnid(即 WordNet ID)的映射。

❷ 加载将 wnid 映射到类索引(整数)的类索引。

❸ 这将创建一个数据框,其中包含从 wnid 到类描述的映射。

❹ 加载由文件路径给出的图像。首先,我们添加一个额外的维度来表示批次维度。

❺ 将图像调整大小为 224×224 大小的图像。

❻ 将图像像素值调整到[-1, 1]的范围内。

❼ 如果图像是灰度的,则在通道维度上将图像重复三次,以与 RGB 图像具有相同的格式。

❽ 获取图像的 wnid。

❾ 获取图像的类别索引。

❿ 获取类的字符串标签。

⓫ 对一个示例图像运行该函数。

TensorFlow 实战(八)(4)https://developer.aliyun.com/article/1522971

相关文章
|
7月前
|
机器学习/深度学习 TensorFlow API
TensorFlow与Keras实战:构建深度学习模型
本文探讨了TensorFlow和其高级API Keras在深度学习中的应用。TensorFlow是Google开发的高性能开源框架,支持分布式计算,而Keras以其用户友好和模块化设计简化了神经网络构建。通过一个手写数字识别的实战案例,展示了如何使用Keras加载MNIST数据集、构建CNN模型、训练及评估模型,并进行预测。案例详述了数据预处理、模型构建、训练过程和预测新图像的步骤,为读者提供TensorFlow和Keras的基础实践指导。
518 59
|
2月前
|
机器学习/深度学习 TensorFlow API
机器学习实战:TensorFlow在图像识别中的应用探索
【10月更文挑战第28天】随着深度学习技术的发展,图像识别取得了显著进步。TensorFlow作为Google开源的机器学习框架,凭借其强大的功能和灵活的API,在图像识别任务中广泛应用。本文通过实战案例,探讨TensorFlow在图像识别中的优势与挑战,展示如何使用TensorFlow构建和训练卷积神经网络(CNN),并评估模型的性能。尽管面临学习曲线和资源消耗等挑战,TensorFlow仍展现出广阔的应用前景。
88 5
|
2月前
|
机器学习/深度学习 人工智能 TensorFlow
基于TensorFlow的深度学习模型训练与优化实战
基于TensorFlow的深度学习模型训练与优化实战
129 0
|
5月前
|
机器学习/深度学习 存储 前端开发
实战揭秘:如何借助TensorFlow.js的强大力量,轻松将高效能的机器学习模型无缝集成到Web浏览器中,从而打造智能化的前端应用并优化用户体验
【8月更文挑战第31天】将机器学习模型集成到Web应用中,可让用户在浏览器内体验智能化功能。TensorFlow.js作为在客户端浏览器中运行的库,提供了强大支持。本文通过问答形式详细介绍如何使用TensorFlow.js将机器学习模型带入Web浏览器,并通过具体示例代码展示最佳实践。首先,需在HTML文件中引入TensorFlow.js库;接着,可通过加载预训练模型如MobileNet实现图像分类;然后,编写代码处理图像识别并显示结果;此外,还介绍了如何训练自定义模型及优化模型性能的方法,包括模型量化、剪枝和压缩等。
99 1
|
5月前
|
机器学习/深度学习 数据采集 TensorFlow
使用TensorFlow进行模型训练:一次实战探索
【8月更文挑战第22天】本文通过实战案例详解使用TensorFlow进行模型训练的过程。首先确保已安装TensorFlow,接着预处理数据,包括加载、增强及归一化。然后利用`tf.keras`构建卷积神经网络模型,并配置训练参数。最后通过回调机制训练模型,并对模型性能进行评估。此流程为机器学习项目提供了一个实用指南。
|
4月前
|
机器学习/深度学习 数据挖掘 TensorFlow
解锁Python数据分析新技能,TensorFlow&PyTorch双引擎驱动深度学习实战盛宴
在数据驱动时代,Python凭借简洁的语法和强大的库支持,成为数据分析与机器学习的首选语言。Pandas和NumPy是Python数据分析的基础,前者提供高效的数据处理工具,后者则支持科学计算。TensorFlow与PyTorch作为深度学习领域的两大框架,助力数据科学家构建复杂神经网络,挖掘数据深层价值。通过Python打下的坚实基础,结合TensorFlow和PyTorch的强大功能,我们能在数据科学领域探索无限可能,解决复杂问题并推动科研进步。
83 0
|
5月前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
101 0
|
5月前
|
安全 Apache 数据安全/隐私保护
你的Wicket应用安全吗?揭秘在Apache Wicket中实现坚不可摧的安全认证策略
【8月更文挑战第31天】在当前的网络环境中,安全性是任何应用程序的关键考量。Apache Wicket 是一个强大的 Java Web 框架,提供了丰富的工具和组件,帮助开发者构建安全的 Web 应用程序。本文介绍了如何在 Wicket 中实现安全认证,
56 0
|
5月前
|
机器学习/深度学习 数据采集 TensorFlow
从零到精通:TensorFlow与卷积神经网络(CNN)助你成为图像识别高手的终极指南——深入浅出教你搭建首个猫狗分类器,附带实战代码与训练技巧揭秘
【8月更文挑战第31天】本文通过杂文形式介绍了如何利用 TensorFlow 和卷积神经网络(CNN)构建图像识别系统,详细演示了从数据准备、模型构建到训练与评估的全过程。通过具体示例代码,展示了使用 Keras API 训练猫狗分类器的步骤,旨在帮助读者掌握图像识别的核心技术。此外,还探讨了图像识别在物体检测、语义分割等领域的广泛应用前景。
57 0
|
6月前
|
机器学习/深度学习 数据挖掘 TensorFlow
解锁Python数据分析新技能,TensorFlow&PyTorch双引擎驱动深度学习实战盛宴
【7月更文挑战第31天】在数据驱动时代,Python凭借其简洁性与强大的库支持,成为数据分析与机器学习的首选语言。**数据分析基础**从Pandas和NumPy开始,Pandas简化了数据处理和清洗,NumPy支持高效的数学运算。例如,加载并清洗CSV数据、计算总销售额等。
70 2

热门文章

最新文章