python学习之猫狗数据集分类实验(二)

28 篇文章 0 订阅

前面一个博客,介绍了训练之类的详情:https://blog.csdn.net/qq_43433255/article/details/93855517
下面,就用得到.h5文件继续。
这里是所有的头文件的汇总:

import keras
keras.__version__
from keras.models import load_model
from keras.preprocessing import image
import numpy as np
from keras import models
import matplotlib.pyplot as plt
from keras.applications import VGG16
from keras import backend as K

因为使用的是anaconda下的python,后面一步一步运行的时候,我也会贴上引入的库,

import keras
keras.__version__

在这里插入图片描述

from keras.models import load_model

model = load_model('G:\\WangLuoRuanJian\\Pythondaima\\qianrushi\\cats_and_dogs_small_2.h5')
model.summary()  # 作为提醒

在这里插入图片描述
在这里插入图片描述

from keras.preprocessing import image
import numpy as np

img_path = 'G:/2018and2019two/qianrushi/kaggle_dogandcat_small/test/cats/cat.1700.jpg'
#我们将图像预处理成4d张量。
img = image.load_img(img_path, target_size=(150, 150))
img_tensor = image.img_to_array(img)
img_tensor = np.expand_dims(img_tensor, axis=0)
#记住,模型是根据输入进行培训的
#以以下方式预处理:
img_tensor /= 255.
#它的形状是(1150,150,3)
print(img_tensor.shape)
plt.imshow(img_tensor[0])
plt.show()

在这里插入图片描述
在这里插入图片描述

from keras import models
import matplotlib.pyplot as plt

'''
为了提取我们想要查看的特征图,我们将创建一个以成批图像为输入的keras模型,并输出所有卷积和池层的激活。为此,我们将使用keras类模型。使用两个参数来实例化模型:输入张量(或输入张量列表)和输出张量(或输出张量列表)。结果类是一个keras模型,就像您熟悉的顺序模型一样,将指定的输入映射到指定的输出。使模型类与众不同的是,它允许具有多个输出的模型,与顺序的不同。
'''
#提取前8层的输出:
layer_outputs = [layer.output for layer in model.layers[:8]]
#创建一个将返回这些输出的模型,给定模型输入:
activation_model = models.Model(inputs=model.input, outputs=layer_outputs)
#这将返回5个numpy数组的列表:
#每层激活一个阵列
activations = activation_model.predict(img_tensor)
first_layer_activation = activations[0]
print(first_layer_activation.shape)
plt.matshow(first_layer_activation[0, :, :, 3], cmap='viridis')
plt.show()
#这个通道似乎编码了一个对角边缘检测器。
#让我们试试第30个通道——但是请注意,您自己的通道可能会有所不同,
#因为卷积层学习的特定过滤器并不具有确定性。
plt.matshow(first_layer_activation[0, :, :, 30], cmap='viridis')
plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import keras

#这些是图层的名称,因此可以将它们作为绘图的一部分
layer_names = []
for layer in model.layers[:8]:
    layer_names.append(layer.name)
images_per_row = 16
#现在让我们展示我们的功能图
for layer_name, layer_activation in zip(layer_names, activations):
   #这是功能图中的功能数量
    n_features = layer_activation.shape[-1]
   #功能图具有形状(1, size, size, n_features)
    size = layer_activation.shape[1]
    #我们将在此矩阵中平铺激活通道
    n_cols = n_features // images_per_row
    display_grid = np.zeros((size * n_cols, images_per_row * size))
    #我们将把每个过滤器平铺到这个大的水平网格中
    for col in range(n_cols):
        for row in range(images_per_row):
            channel_image = layer_activation[0,
                                             :, :,
                                             col * images_per_row + row]
            #后期处理该功能,使其视觉效果良好
            channel_image -= channel_image.mean()
            channel_image /= channel_image.std()
            channel_image *= 64
            channel_image += 128
            channel_image = np.clip(channel_image, 0, 255).astype('uint8')
            display_grid[col * size : (col + 1) * size,
                         row * size : (row + 1) * size] = channel_image
    # 显示网格
    scale = 1. / size
    plt.figure(figsize=(scale * display_grid.shape[1],
                        scale * display_grid.shape[0]))
    plt.title(layer_name)
    plt.grid(False)
    plt.imshow(display_grid, aspect='auto', cmap='viridis')
plt.show()

在这里插入图片描述

from keras.applications import VGG16
from keras import backend as K

model = VGG16(weights='imagenet',
              include_top=False)
layer_name = 'block3_conv1'
filter_index = 0
layer_output = model.get_layer(layer_name).output
loss = K.mean(layer_output[:, :, :, filter_index])
#对“渐变”的调用返回张量列表 (of size 1 in this case)
#因此我们只保留第一个元素——张量。
grads = K.gradients(loss, model.input)[0]
#我们在除法之前加上1e-5,以避免意外地被0除法。
grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
iterate = K.function([model.input], [loss, grads])
# 测试它
import numpy as np
loss_value, grads_value = iterate([np.zeros((1, 150, 150, 3))])
#我们从有噪声的灰色图像开始
input_img_data = np.random.random((1, 150, 150, 3)) * 20 + 128.
#这是每个梯度更新的幅度
step = 1.  
for i in range(40):
    #计算损失值和梯度值
    loss_value, grads_value = iterate([input_img_data])
   #在这里,我们调整输入图像的方向,使损失最大化。
    input_img_data += grads_value * step
def deprocess_image(x):
    #归一化张量:以0为中心,确保std为0.1。
    x -= x.mean()
    x /= (x.std() + 1e-5)
    x *= 0.1
    # 剪辑到 [0, 1]
    x += 0.5
    x = np.clip(x, 0, 1)
    # 转换为RGB数组
    x *= 255
    x = np.clip(x, 0, 255).astype('uint8')
    return x
def generate_pattern(layer_name, filter_index, size=150):
    #构建一个最大化激活的丢失函数
    #所考虑层的第n个过滤器。
    layer_output = model.get_layer(layer_name).output
    loss = K.mean(layer_output[:, :, :, filter_index])
   #计算与此损失相关的输入图片的梯度
    grads = K.gradients(loss, model.input)[0]
    #归一化技巧:我们归一化梯度
    grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
    #此函数返回给定输入图片的损耗和梯度。
    iterate = K.function([model.input], [loss, grads])
   #我们从有噪声的灰色图像开始
    input_img_data = np.random.random((1, size, size, 3)) * 20 + 128.
   #40层
    step = 1.
    for i in range(40):
        loss_value, grads_value = iterate([input_img_data])
        input_img_data += grads_value * step
    img = input_img_data[0]
    return deprocess_image(img)
plt.imshow(generate_pattern('block3_conv1', 0))
plt.show()

在这里插入图片描述

for layer_name in ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1']:
    size = 64
    margin = 5
   #这是一个空的(黑色)图像,我们将在其中存储结果。
    results = np.zeros((8 * size + 7 * margin, 8 * size + 7 * margin, 3))
    for i in range(8):  遍历结果网格的行
        for j in range(8): #遍历结果网格的列
            #在层名称中为筛选器'i+(j*8)'生成模式`
            filter_img = generate_pattern(layer_name, i + (j * 8), size=size)
           #将结果放入结果网格的平方`(i,j)`
            horizontal_start = i * size + i * margin
            horizontal_end = horizontal_start + size
            vertical_start = j * size + j * margin
            vertical_end = vertical_start + size
            results[horizontal_start: horizontal_end, vertical_start: vertical_end, :] = filter_img
    #显示结果网格
    plt.figure(figsize=(20, 20))
    plt.imshow(results)
    plt.show()
plt.imshow(img_tensor[0])
plt.show()

在这里插入图片描述
效果不明显。

这些过滤器可视化告诉我们很多关于convnet层如何看待世界的信息;
convnet中的每一层都只是学习一组过滤器,这样它们的输入就可以表示为过滤器的组合。这类似于傅立叶变换如何将信号分解成一组余弦函数。随着我们在模型中的提升,这些convnet过滤器组中的过滤器变得越来越复杂和精细;
模型中第一层的过滤器(block1_conv1)编码简单的方向性边和颜色(在某些情况下为彩色边);
Block2_Conv1的过滤器对由边和颜色组合而成的简单纹理进行编码。
更高层的过滤器开始类似于自然图像中的纹理:羽毛、眼睛、树叶等。

参考链接:https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/5.4-visualizing-what-convnets-learn.ipynb

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值