精华内容
下载资源
问答
  • 今天有点空,聊个IT监控系统中常见的小细节:主机热力图。所谓主机热力图,就是采用矩阵热力图的方式,来展现环境内一批主机的健康状态。类似的界面应该大家都比较熟悉。我这先贴几个业内最有名的实现:阿里云的容器...

    今天有点空,聊个IT监控系统中常见的小细节:主机热力图。

    所谓主机热力图,就是采用矩阵热力图的方式,来展现环境内一批主机的健康状态。类似的界面应该大家都比较熟悉。我这先贴几个业内最有名的实现:

    1. 阿里云的容器服务热力图:

    31aa3881cc0772772c6eba419fbae712.png

    2. datadog的主机热力图:

    d5bee39a19f65ea6a63f81304395ecc5.png

    3. SignalFx的基础设施概览图:

    35b179fa309dfc7cbb1f63b9dd0310ea.png

    国内外例子太多,就不一一例举了。从这些图例里,可以看到他们的用法和功能设计有几点共性:

    1. 用颜色深浅来表示负载程度,一般而言越深的负载越高,越可能不太健康。
    2. 支持采用某些固定维度进行分组展示,一般来说,比如机房啊,设备类型啊等。
    3. 负载程度的具体指标是可选的。通常会采用:内存使用率、CPU使用率、磁盘使用率、带宽使用率等可以有比较明确对比意义的百分比指标。

    看似很不错,基础运维需求就是一眼了解全局的运行状态嘛。但是问题来了:实际主机上跑的业务类型各不一样,一个MySQL主机和一个LVS主机,能用同一个指标来衡量自己的工作负载情况么?

    第二个问题:就算按照datadog那样,按业务和机型做分组,保证每个组里的主机确实可以用相同的指标衡量。你又怎么确定到底多深的颜色是「有点忙」,多深的颜色是「注意,要挂了」,多深的颜色是「完蛋,喊人」呢?

    SignalFx的应对办法是:额外加了一条规则,如果这台主机有关联的告警产生,就把对应的色块直接置为红色。

    实在是简单粗暴啊——但是告警本身也有轻有重有误报,这又怎么办


    事实上,AIOps领域还真的有些研究,在尝试用算法解决这个问题——按照综合情况,而不是单一的指标/告警,来评定主机的负载健康状态。

    注意:一般我们说健康度,大家听过更多的都是业务层面的,因为业务层面可以选取最最重要的某个指标作为代表,然后其他指标作为该指标的不同维度,做个分类算法,就能判断业务健康了。

    但是主机,谁也说不好用哪个指标来代表啊?就必须要「无中生有」了。

    今天这里稍微介绍一下的,是北卡州立大学顾晓晖教授在2012年发表的一篇论文:

    UBL: Unsupervised Behavior Learning for Predicting Performance Anomalies in Virtualized Cloud Systemsdance.csc.ncsu.edu

    论文中,对IaaS云主机采集了各种基础性能指标,采用自组织映射神经网络算法(Self Organizing Map, SOM),聚类并构成一个 32*32 维的 1024 神经元的拓扑图。

    接着,如何表示图上每个节点代表的系统健康状态呢?办法是计算它邻近区域的大小,并以此作为节点的颜色深浅的值。

    由于训练数据都是正样本,在算法做过一些权重调整以后,聚类之间的距离比较合适,那么每个节点的邻近区域大小也都差不多,换而言之,这张拓扑图上的颜色深浅看起来也就都差不多。

    等模型上线运行以后,如果实际数据体现在拓扑图上,某个节点颜色过深,那就代表这片区域的系统状态有问题了。如下图,是论文中两个场景举例:

    99a88a21fd1a5bea53b70f70b8f040fc.png

    作为热力图的部分,其实就这样了。但是作为UBL,显然还可以把热力图代表的异常情况,作为告警发出,并进行一定的根因分析推荐。

    分析推荐过程也非常简单:既然已经有了颜色最深的那个节点,依次往外扩散找邻居节点,但是要找的是颜色依然正常的。如果邻居都不正常,就找隔一跳的邻居,直到凑够了5个正常邻居。然后把这5个节点所代表的主机性能指标集拿出来,挨个和异常节点的做5次相关性排序。然后简单多数投票,得到最终的top5的根因指标推荐。


    SOM是个特偏门的算法,具体过程就留给读者自己阅读论文吧。

    注1:UBL系统已经被顾教授申请专利了哦:U.S. Patent Application No. 14/480,270。包括国内,也有类似做「无中生有」型设备健康度的专利申请,比如:国防科大的CN201410690233.9。大家核心思想,都是认定稳态下,所有设备的健康度应该趋向一致。

    注2:主机热力图加上时间变化趋势,就可以变种为分面日历热力图,也是一种不错的监控可视化方法。下图是顾教授做的产品效果:

    5d8cdea350bc1d362b58758e921530f6.png
    展开全文
  • 现有的深度神经网络可解释方法主要分为基于数据的方法和基于模型的方法。基于数据的可解释性分析方法中最典型的是可视化方法。可视化方法主要通过可视化工具将数据中的重要部分进行标注,将学习过程与原始数据结合...

    近年来,深度学习系统的解释方法已引起人们的广泛关注。现有的深度神经网络可解释方法主要分为基于数据的方法和基于模型的方法。基于数据的可解释性分析方法中最典型的是可视化方法。可视化方法主要通过可视化工具将数据中的重要部分进行标注,将学习过程与原始数据结合起来,进而帮助我们直观地理解深度学习的学习过程。例如,塞尔瓦拉朱(Selvaraju)等人使用了可视化方法,通过对卷积层的梯度生成热力图,对输入图像中的重要像素进行显示和标注,帮助我们理解深度学习的学习区域;欧拉(Olah)等人则使用了特征可视化的方法,对神经元学习到的内容进行可视化。这些可视化方法让人们对神经网络的内在机理有了直接印象,但是由于这类方法无法深人了解模型内部结构,难以对模型决策逻辑进行直接解释,因此对于神经网络的黑盒问题并没有实质性地解决。

    1e9e13130a248c000cb9d91c9d8e190d.png

    基于模型的可解释性分析方法主要分为代理模型和自动特征提取两种。代理模型方法是通过构建新的模型以模拟黑盒模型的输入和输出,通过该代理模型来理解原黑盒模型,比较典型的有里贝罗(Ribeiro)等人提出的基于模型无关的局部可解释性描述(Local Interpretable Model-Agnostic Explanations,LIME)的线性代理模型。自动特征提取则是另一种研究深度学习系统可解释性的方法,其主要通过对输入、输出以及模型内部元素的关系进行研究,进而分析解释其决策逻辑。具体有通过对各层、各神经元使用if-then规则进行自动特征提取的KT方法,使用采样进行自动特征提取的方法,以及通过连接权、偏导、输入变量的改变来判断输入变量重要程度的敏感性分析方法等。尽管这些方法能对现有神经网络的决策逻辑进行一定的分析,但是无法直接构建可解释性的神经网络。

    基于数据的可解释分析方法虽然能对神经网络的决策逻辑提供直观的印象,但是很难指导我们进行有目的的建模。而基于模型的可解释分析方法虽然在一定程度上对可解释性有所帮助,但是仍然很难帮助我们解决深度学习系统难以判读的问题。所以寻找一种新的能同时拥有可判读和可理解两大特要性,并可直接构建新的神经网络的方法成为了解决深度学习智能系统安全的核心问题之一。

    展开全文
  • 预训练网络(pretrained network)是一个保存好的网络,之前已在大型数据集(通常是大规模 像分类任务)上训练好。这个方法也叫迁移学习。预训练的模型学到的特征的空间层次结构可以有效地作为视觉世界的通用模型较低...

    选择预训练模型

    将深度学习应用于小型图像数据集,一种常用且非常高效的方法是使用预训练网络。

    预训练网络(pretrained network)是一个保存好的网络,之前已在大型数据集(通常是大规模图 像分类任务)上训练好。这个方法也叫迁移学习。预训练的模型学到的特征的空间层次结构可以有效地作为视觉世界的通用模型

    较低层学到的结构都是一些点线等低层次的特征,

    这里使用的预训练的模型的数据是 ImageNet 数据集(140 万张标记图像,1000 个不同的类别),为了降低理解的难度使用VGG16架构来获取预训练的模型。它是一种简单而又广泛使用的卷积神经网络架构。其实还有很多架构例如: - VGG - ResNet - Inception - Inception-ResNet - Xception

    预训练模型的特征提取

    特征提取是使用之前网络学到的表示来从新样本中提取出有用的特征。然后将这些特征输入一个新的分类器,从头开始训练。

    卷积基

    对于分类的卷积神经网络基本包含两个主要组成: - 一系列池化层和卷积层 卷积基 - 一个密集连接分类器

    特征提取就是取出之前训练好的网络的卷积基,在上面运行新数据,然后在输出上面训练一个新的分类器 具体如下图:

    卷积基复用性卷积基学到的表示可能更加通用,因此更适合重复使用

    特征图表示通用概念在图像中是否存在

    特征图表示输入图像中的位置信息

    使用预训练模型的时候需要注意: - 低层学到的结构都是一些点线等低层次的特征(比如视觉边缘、颜色和纹理) - 靠近顶部的层提取的是更加抽象的概念(猫的眼睛,狗的鼻子)

    如果新的数据集与预训练的数据集差异很大,那么最好只使用前几层来做特征提取

    keras内置的模型

    keras.applications 中的一部分图像分类模型,都是在 ImageNet 数据集上预训练得到:VGG16

    VGG19

    ResNet50

    Inception V3

    MobileNet

    具体的使用如下函数,参数如下weights: 指定模型初始化的权重检查点

    include_top:指定模型最后是否包含密集连接分类器,

    input_shape: 是输入到网络中的图像张量的形状

    from keras.applications import VGG16

    conv_base = VGG16(weights = 'imagenet',

    include_top = False,

    input_shape=(150,150,3))

    Using TensorFlow backend.

    Colocations handled automatically by placer.

    conv_base.summary()

    _________________________________________________________________

    Layer (type) Output Shape Param #

    =================================================================

    input_1 (InputLayer) (None, 150, 150, 3) 0

    _________________________________________________________________

    block1_conv1 (Conv2D) (None, 150, 150, 64) 1792

    _________________________________________________________________

    block1_conv2 (Conv2D) (None, 150, 150, 64) 36928

    _________________________________________________________________

    block1_pool (MaxPooling2D) (None, 75, 75, 64) 0

    _________________________________________________________________

    block2_conv1 (Conv2D) (None, 75, 75, 128) 73856

    _________________________________________________________________

    block2_conv2 (Conv2D) (None, 75, 75, 128) 147584

    _________________________________________________________________

    block2_pool (MaxPooling2D) (None, 37, 37, 128) 0

    _________________________________________________________________

    block3_conv1 (Conv2D) (None, 37, 37, 256) 295168

    _________________________________________________________________

    block3_conv2 (Conv2D) (None, 37, 37, 256) 590080

    _________________________________________________________________

    block3_conv3 (Conv2D) (None, 37, 37, 256) 590080

    _________________________________________________________________

    block3_pool (MaxPooling2D) (None, 18, 18, 256) 0

    _________________________________________________________________

    block4_conv1 (Conv2D) (None, 18, 18, 512) 1180160

    _________________________________________________________________

    block4_conv2 (Conv2D) (None, 18, 18, 512) 2359808

    _________________________________________________________________

    block4_conv3 (Conv2D) (None, 18, 18, 512) 2359808

    _________________________________________________________________

    block4_pool (MaxPooling2D) (None, 9, 9, 512) 0

    _________________________________________________________________

    block5_conv1 (Conv2D) (None, 9, 9, 512) 2359808

    _________________________________________________________________

    block5_conv2 (Conv2D) (None, 9, 9, 512) 2359808

    _________________________________________________________________

    block5_conv3 (Conv2D) (None, 9, 9, 512) 2359808

    _________________________________________________________________

    block5_pool (MaxPooling2D) (None, 4, 4, 512) 0

    =================================================================

    Total params: 14,714,688

    Trainable params: 14,714,688

    Non-trainable params: 0

    _________________________________________________________________

    VGG16的模型架构非常的常见,如上面所示。最后的特征图的反馈的是(4,4,512).目前有两种方式来使用VGG16的卷积基。 - 独立使用卷积基:就是先将输入数据再卷积基上运行一次,然后将结果作为输入,再放到独立的Dense网络中计算训练一个dense 网络。 - 速度快,计算代价低,因为每个输入图像只需运行一次卷积基 - 但是无法做数据扩增,容易过拟合 - 对于电脑配置不高的可以使用该方法将卷积基放到整个模型中,直接使用数据输入端到端的运行整个模型计算量大,需要电脑的配置较高,一定要有GPU的加持

    可以使用数据增强来训练模型,

    独立使用卷积基的快速特征提取利用conv_base predict 方法从模型中的使用预训练的卷积基提取特征

    提取的特征形状为,并将将其展平成密集连接分类器的数据

    定义自己的密集连接分类器

    从图中可以看到验证精度达到了约 90%,比上一节从头开始训练的小型模型效果要好得多。但从图中也可以看出,虽然 dropout 比率相当大,但模型几乎从一开始就过拟合。

    import os

    import numpy as np

    from keras.preprocessing.image import ImageDataGenerator

    base_dir = "G:/Data/Kaggle/dogcat/smallData"

    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

    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:

    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

    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)

    Found 2000 images belonging to 2 classes.

    Found 1000 images belonging to 2 classes.

    Found 1000 images belonging to 2 classes.

    #其形状展平为

    print(train_features.shape)

    print(validation_features.shape)

    print(test_features.shape)

    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))

    print(test_features.shape)

    (1000, 8192)

    # 定义并训练密集连接分类器

    from keras import models

    from keras import layers

    from 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_crossentropy',

    metrics=['acc'])

    history = model.fit(train_features, train_labels,

    epochs=30,

    batch_size=20,

    validation_data=(validation_features, validation_labels))

    Use tf.cast instead.

    Train on 2000 samples, validate on 1000 samples

    Epoch 1/30

    2000/2000 [==============================] - 2s 764us/step - loss: 0.6043 - acc: 0.6650 - val_loss: 0.4369 - val_acc: 0.8600

    Epoch 2/30

    2000/2000 [==============================] - 1s 348us/step - loss: 0.4321 - acc: 0.8055 - val_loss: 0.3604 - val_acc: 0.8730

    Epoch 3/30

    2000/2000 [==============================] - 1s 349us/step - loss: 0.3655 - acc: 0.8365 -

    Epoch 30/30

    2000/2000 [==============================] - 1s 374us/step - loss: 0.0938 - acc: 0.9700 - val_loss: 0.2330 - val_acc: 0.9050

    #  绘制训练过程中的损失曲线和精度曲线

    import matplotlib.pyplot as plt

    acc = history.history['acc']

    val_acc = history.history['val_acc']

    loss = history.history['loss']

    val_loss = history.history['val_loss']

    epochs = range(1,len(acc) +1)

    plt.plot(epochs,acc,'bo',label='Training acc')

    plt.plot(epochs,val_acc,'b',label='validation acc')

    plt.title('train and validation acc')

    plt.legend()

    plt.figure()

    plt.plot(epochs,loss,'bo',label='Training loss')

    plt.plot(epochs,val_loss,'b',label='val_loss acc')

    plt.title('train and validation loss')

    plt.legend()

    plt.show()

    联合卷积基进行特征提取

    模型的行为和层类似,所以你可以向 Sequential 模型中添加一个模型,具体模型如下:

    VGG16 的卷积基有 14 714 688 个参数,非常多。在其上添加的分类器有 200 万个参数.如此多的参数都是预先定义好的 所以这里再训练的时候不需要重新再训练一遍:在编译和训练模型之前,一定要“冻结”卷积基。 冻结(freeze) 一个或多个层是指在训练过程中保持其权重不变。

    #在卷积基上添加一个密集连接分类器

    from keras import models

    from keras import layers

    model2 = models.Sequential()

    model2.add(conv_base)

    model2.add(layers.Flatten())

    model2.add(layers.Dense(256,activation='relu'))

    model2.add(layers.Dense(1,activation = 'sigmoid'))

    model2.summary()

    _________________________________________________________________

    Layer (type) Output Shape Param #

    =================================================================

    vgg16 (Model) (None, 4, 4, 512) 14714688

    _________________________________________________________________

    flatten_1 (Flatten) (None, 8192) 0

    _________________________________________________________________

    dense_1 (Dense) (None, 256) 2097408

    _________________________________________________________________

    dense_2 (Dense) (None, 1) 257

    =================================================================

    Total params: 16,812,353

    Trainable params: 16,812,353

    Non-trainable params: 0

    _________________________________________________________________

    keras冻结网络层的方法

    冻结网络的方法是将其 trainable 属性设为 False,如此设置之后,只有添加的两个 Dense 层的权重才会被训练。总共有 4 个权重张量,每层 2 个(主权重矩阵和偏置向量)。 *注意,为了让这些修改生效,你必须先编译模型。如果在编译之后修改了权重的 trainable 属性,那么应该重新编译模型,否则这些修改将被忽略。

    #conv_base.trainable = True

    print('This is the number of trainable weights '

    'before freezing the conv base:', len(model2.trainable_weights))

    conv_base.trainable = False

    print('This is the number of trainable weights '

    'after freezing the conv base:', len(model2.trainable_weights))

    This is the number of trainable weights before freezing the conv base: 30

    This is the number of trainable weights after freezing the conv base: 4

    from keras.preprocessing.image import ImageDataGenerator

    from keras import optimizers

    train_datagen = ImageDataGenerator(

    rescale=1./255,

    rotation_range=40,

    width_shift_range=0.2,

    height_shift_range=0.2,

    shear_range=0.2,

    zoom_range=0.2,

    horizontal_flip=True,

    fill_mode='nearest'

    )

    test_datagen = ImageDataGenerator(rescale=1./255)

    train_generator = train_datagen.flow_from_directory(

    train_dir,

    target_size=(150,150),

    batch_size = 20,

    class_mode = 'binary'

    )

    validation_generator = test_datagen.flow_from_directory(

    validation_dir,

    target_size=(150,150),

    batch_size = 20,

    class_mode='binary'

    )

    model2.compile(loss='binary_crossentropy',

    optimizer=optimizers.RMSprop(lr = 2e-5),

    metrics=['acc'])

    history = model2.fit_generator(

    train_generator,

    steps_per_epoch=100,

    epochs=30,

    validation_data=validation_generator,

    validation_steps=50

    )

    Found 2000 images belonging to 2 classes.

    Found 1000 images belonging to 2 classes.

    Use tf.cast instead.

    Epoch 1/30

    100/100 [==============================] - 21s 210ms/step - loss: 0.5961 - acc: 0.6910 - val_loss: 0.4507 - val_acc: 0.8360

    Epoch 2/30

    100/100 [==============================] - 17s 174ms/step - loss: 0.4815 - acc: 0.7915 - val_loss: 0.3790 - val_acc: 0.8640

    Epoch 30/30

    100/100 [==============================] - 17s 166ms/step - loss: 0.2839 - acc: 0.8835 - val_loss: 0.2366 - val_acc: 0.9050

    #  绘制训练过程中的损失曲线和精度曲线

    import matplotlib.pyplot as plt

    acc = history.history['acc']

    val_acc = history.history['val_acc']

    loss = history.history['loss']

    val_loss = history.history['val_loss']

    epochs = range(1,len(acc) +1)

    plt.plot(epochs,acc,'bo',label='Training acc')

    plt.plot(epochs,val_acc,'b',label='validation acc')

    plt.title('train and validation acc')

    plt.legend()

    plt.figure()

    plt.plot(epochs,loss,'bo',label='Training loss')

    plt.plot(epochs,val_loss,'b',label='val_loss acc')

    plt.title('train and validation loss')

    plt.legend()

    plt.show()

    请大家关注公众号:瓦力人工智能

    分享关于人工智能,机器学习,深度学习以及计算机视觉的好文章,同时自己对于这个领域学习心得笔记。想要一起深入学习人工智能的小伙伴一起结伴学习吧!

    展开全文
  • Keras中可视化卷积层的类激活热力图C小C 2018-12-26 17:05:12 5546 收藏 15展开【时间】2018.12.26【题目】Keras中可视化卷积层的类激活热力图概述本文是对《Deep Learning with python》一书中第5.4.3节Keras中可视...

    Keras中可视化卷积层的类激活热力图

    C小C 2018-12-26 17:05:12 5546 收藏 15

    展开

    【时间】2018.12.26

    【题目】Keras中可视化卷积层的类激活热力图

    概述

    本文是对《Deep Learning with python》一书中第5.4.3节Keras中可视化类激活的热力图的整理与总结,参考链接:https://blog.csdn.net/einstellung/article/details/82858974

    一、什么是类激活图(CAP)?

    类激活图(CAM,class activation map)是与特定输出类别相关的二维分数网格,对于输入图像的每个位置进行计算,它表示每个位置对该类别的重要程度。

    二、类激活图可视化

    类激活图可视化有助于了解一张图像的哪一部分让卷积神经网络做出了最终的分类决策。这有助于对卷积神经网络的决策过程进行调试,特别是分类错误的情况下。同时,这种方法可以定位图像中的特定目标。这里,我们介绍的具体实现方式是“Grad-CAM:visual explanations from deep networks via gradiaent-based localization',它是在2017年提出来的,具体实现方法是:给定一张输入图像,对于一个卷积层的输出特征图,用类别相对于每一个通道的梯度对这个特征图中的每个通道进行加权。

    三、使用VGG16演示类激活图可视化

    3.1 加载预训练的VGG-16:

    from keras.applications.vgg16 import VGG16

    model = VGG16(weights='imagenet')

    model.summary()

    【VGG-16】模型结构如下:最后输出的是1000维的向量,表示属于1000个类别的概率

    3.2 载入输入图像及预处理

    如图所示,这是两只非洲象的图片。我们将这张图片转换为VGG16能够读取的格式:大小为224X224的图像,这些训练图像都根据keras.applications.vgg16.preprocess_input函数中的内置的规则进行预处理。因此,我们需要加载图像,将其大小调整为224X224,然后将其转化为float32格式的Numpy张量,并应用这些预处理规则。

    from keras.preprocessing import image

    from keras.applications.vgg16 import preprocess_input, decode_predictions

    import numpy as np

    img_path = '/Users/fchollet/Downloads/creative_commons_elephant.jpg'

    img = image.load_img(img_path, target_size=(224, 224))   # 大小为224*224的Python图像库图像

    x = image.img_to_array(img)  # 形状为(224, 224, 3)的float32格式Numpy数组

    x = np.expand_dims(x, axis=0)  # 添加一个维度,将数组转化为(1, 224, 224, 3)的形状批量

    x = preprocess_input(x)   #按批量进行预处理(按通道颜色进行标准化)

    这时,可以在图像上运行预训练的VGG16网络,并将预测向量解码为我们可以读的形式。

    【代码】

    preds = model.predict(x)

    print('Predicted:', decode_predictions(preds, top=3)[0])

    【运行结果】:

    Predicted: [(‘n02504458’, ‘African_elephant’, 0.90942144),

    (‘n01871265’, ‘tusker’, 0.08618243),

    (‘n02504013’, ‘Indian_elephant’, 0.0043545929)]

    对这个图像预测的前三个类别分别是:

    非洲象:92.5%的概率

    长牙动物:7%的概率

    印度象:0.4%的概率

    网络认为预测向量中最大激活的元素对应是“非洲象”类别的元素,索引编号386

    np.argmax(preds[0])

    386

    3.3.  应用Grad-CAM算法

    african_elephant_output = model.output[:, 386]   # 预测向量中的非洲象元素

    last_conv_layer = model.get_layer('block5_conv3')  # block5_conv3层的输出特征图,它是VGG16的最后一个卷积层

    grads = K.gradients(african_elephant_output, last_conv_layer.output)[0]   # 非洲象类别相对于block5_conv3输出特征图的梯度

    pooled_grads = K.mean(grads, axis=(0, 1, 2))   # 形状是(512, )的向量,每个元素是特定特征图通道的梯度平均大小

    iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])  # 这个函数允许我们获取刚刚定义量的值:对于给定样本图像,pooled_grads和block5_conv3层的输出特征图

    pooled_grads_value, conv_layer_output_value = iterate([x])  # 给我们两个大象样本图像,这两个量都是Numpy数组

    for i in range(512):

    conv_layer_output_value[:, :, i] *= pooled_grads_value[i]  # 将特征图数组的每个通道乘以这个通道对大象类别重要程度

    heatmap = np.mean(conv_layer_output_value, axis=-1)  # 得到的特征图的逐通道的平均值即为类激活的热力图

    【注意】

    K.gradients(y,x)用于求y关于x 的导数(梯度),(y和x可以是张量tensor也可以是张量列表,形如 [tensor1, tensor2, …, tensorn]),返回的是一个张量列表,列表长度是张量列表y的长度,列表元素是与x具有一样shape的张量。在本例中,grads = K.gradients(african_elephant_output, last_conv_layer.output)[0],african_elephant_output是(1,)张量,last_conv_layer.output是(1,7,7,512)张量,所以返回的是只有一个元素的(1,7,7,512)张量列表,grads取了列表中唯一一个元素。

    3.4 热力图后处理

    为了便于可视化,我们需要将热力图标准化到0~1范围内,如下。

    heatmap = np.maximum(heatmap, 0)  # heatmap与0比较,取其大者

    heatmap /= np.max(heatmap)

    plt.matshow(heatmap)

    plt.show()

    【结果】

    3.5 将热力图与原始图叠加,实现可视化

    最后,我们可以用OpenCV来生成一张图像,将原始图像叠加在刚刚得到的热力图上

    import cv2

    img = cv2.imread(img_path)  # 用cv2加载原始图像

    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))  # 将热力图的大小调整为与原始图像相同

    heatmap = np.uint8(255 * heatmap)  # 将热力图转换为RGB格式

    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)   # 将热力图应用于原始图像

    superimposed_img = heatmap * 0.4 + img    # 这里的0.4是热力图强度因子

    cv2.imwrite('/Users/fchollet/Downloads/elephant_cam.jpg', superimposed_img)   # 将图像保存到硬盘

    【注意】cv2.applyColorMap()是opencv中的伪彩色函数,用于画色度图(colarmap),具体可看:opencv中伪彩色applyColorMap函数

    【最终结果】

    四、代码汇总

    from keras.applications.vgg16 import VGG16

    from keras.preprocessing import image

    from keras.applications.vgg16 import preprocess_input, decode_predictions

    from keras import backend as K

    import numpy as np

    import cv2

    model = VGG16(weights='imagenet')

    model.summary()

    img_path = '/Users/fchollet/Downloads/creative_commons_elephant.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)

    african_elephant_output = model.output[:, 386]

    last_conv_layer = model.get_layer('block5_conv3')

    grads = K.gradients(african_elephant_output, last_conv_layer.output)[0]

    pooled_grads = K.mean(grads, axis=(0, 1, 2))

    iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])

    pooled_grads_value, conv_layer_output_value = iterate([x])

    for i in range(512):

    conv_layer_output_value[:, :, i] *= pooled_grads_value[i]

    heatmap = np.mean(conv_layer_output_value, axis=-1)

    heatmap = np.maximum(heatmap, 0)  # heatmap与0比较,取其大者

    heatmap /= np.max(heatmap)

    img = cv2.imread(img_path)

    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))

    heatmap = np.uint8(255 * heatmap)

    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)

    superimposed_img = heatmap * 0.4 + img

    cv2.imwrite('/Users/fchollet/Downloads/elephant_cam.jpg', superimposed_img)

    ————————————————

    版权声明:本文为CSDN博主「C小C」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/C_chuxin/java/article/details/85265082

    展开全文
  • Paper nameGrad-CAM: Visual Explanations from Deep Networks via Gradient-based LocalizationPaper Reading NoteURL: ...DR提出一种对神经网络输出进行可视化的方式Grad-CAM(Gradient-weighted Cla...
  • 在训练期间,空间特征图Φ(xt)和Φ(xt’ )以及关键点坐标Ψ(xt) 和Ψ(xt’) 利用卷积神经网络和斯坦福此前提出的PointNet进行帧的预测,再次过程中,关键点的坐标被转换成高斯热力图(Gaussian heatmaps) HΨ(xt) ...
  • SenseToVec是一种神经网络模型,用其读取2015年Reddit上的所有评论,再使用word2vec和spaCy来建立语义地图。通过搜索一个词或短语,得到和该词或短语最相似的单词(甚至可以使用它来查找同义词)。比如输入“机器学习...
  • 可视化卷及神经网络热力图

    万次阅读 多人点赞 2018-09-26 20:40:31
    我们这里介绍的一种可视化方法,它有助于了解一张图像的哪一部分让卷积神经网络做出了最终的分类决策。这有助于对卷积神经网络的决策过程进行调试,特别是分类错误的情况下。这种方法可以定位图像中的特定目标。 ...
  • 本文将介绍在卷积神经网络(CNN)中,针对图像的某些部位可视化从而做出判断的不同技术。 类激活映射(CAM)是一种生成热力图的技术,用于突出图像的类的特定区域。 热力图效用 下面是一个典型的热力图: 图片来源:...
  • heatmap) # 将热力图转换为RGB格式 heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) # 将热力图应用于原始图像 superimposed_img = heatmap * 0.4 + img # 这里的0.4是热力图强度因子 # 将图像保存到硬盘 ...
  • 具体而言是为了做一个特定场景的车辆/车种检测,因为摄像头角度问题,大多时候只有车辆的一部分处于画面内,所以没有走检测的方式,而是尝试了一下通过各种数据增强(主要是裁剪)来指导网络对不同车种车辆的各个部位...
  • 所幸的是,近几年来的论文,也从常规的神经网络结构转向神经网络可视化,目的是让我们能看见卷积神经网络“学习”到了什么,神经网络是怎么判别物体的类别 今天就要为大家介绍一种卷积神经网络可视化的技巧,它发表...
  • Pytorch可视化神经网络热力图(CAM)

    千次阅读 热门讨论 2019-12-03 11:03:17
    具体而言是为了做一个特定场景的车辆/车种检测,因为摄像头角度问题,大多时候只有车辆的一部分处于画面内,所以没有走检测的方式,而是尝试了一下通过各种数据增强(主要是裁剪)来指导网络对不同车种车辆的各个...
  • 神经网络分别中,我们不仅想知道最终预测结果,还需要了解网络是凭借图像什么特征进行判断的。其中类激活热力图 (CAM,class activation map)就是一种很好的呈现方式。 目录标题类激活热力图 (CAM,class ...
  • 基于卷积神经网络和热图回归的非结构化道路消失点检测 前言:20年的一篇文章,是关于非结构化道路VP检测中第一篇基于深度学习的解决方案。之前读过,这里再读一下,顺便再跑一下程序。 原文链接: ...
  • 卷机神经网络的可视化(可视化类激活的热力图) 参考:https://www.cnblogs.com/zhhfan/p/9978099.html 可视化类激活的热力图 我还要介绍另一种可视化方法,它有助于了解一张图像的哪一部分让卷积神经网络做出了最终...
  • 使用神经网络进行预测时,一个明显的缺陷就是缺少可解释性,我们不能通过一些简单的方法来知道网络做出决策或者预测的理由,这在很多方面就使得它的应用受限。虽然不能通过一些数学方法来证明模型的有效性,但我们仍...

空空如也

空空如也

1 2 3 4
收藏数 73
精华内容 29
关键字:

热力图神经网络