keras猫狗图像分类+可视化特征图

构建网络

构建卷积神经网络,包括4对卷积层和池化层,输出层用sigmoid激活(二分类),并且对

from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32,(3,3), activation="relu", input_shape=(150,150,3)))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(512, activation="relu"))
model.add(layers.Dense(1, activation="sigmoid"))

编译模型

使用二分类交叉熵损失函数

#编译模型
from keras import optimizers
model.compile(loss="binary_crossentropy",
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=["accuracy"]
              )

数据预处理

利用keras将本地存储的训练图像数据读取出来返回生成器,并对图像进行数据增强

#数据预处理
from keras.preprocessing.image import ImageDataGenerator

#存储数据的路径
train_img_dir = "E:/code/python deeplearning/dataset/c_d_0/train"
validation_img_dir = "E:/code/python deeplearning/dataset/c_d_0/validation"

#数据生成器,将原像素值压缩到0-1之间并对训练数据进行数据增强
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
)
test_datagen = ImageDataGenerator(rescale=1./255,)

#训练数据生成器
train_generator = train_datagen.flow_from_directory(
    train_img_dir,
    target_size=(150,150),
    batch_size=20,
    class_mode="binary"
)

#验证数据生成器
validation_generator = test_datagen.flow_from_directory(
    validation_img_dir,
    target_size=(150,150),
    batch_size=20,
    class_mode="binary"
)

在这里插入图片描述
读取到训练数据2000条,验证数据500条

模型训练

fit进训练数据进行训练,batch大小为20,所有每轮次需要100步,验证每轮次需要25步

history = model.fit_generator(
    train_generator,
    steps_per_epoch=100,
    epochs=100,
    validation_data=validation_generator,
    validation_steps=25
)

在这里插入图片描述
结果显示验证集准确率达到0.8240

模型保存至本地

model.save("E:/code/python deeplearning/model/cats_dogs_1.h5")

保存结果如下:
在这里插入图片描述

绘制损失和精度曲线

import matplotlib.pyplot as plt

acc = history.history["accuracy"]
loss = history.history["loss"]

val_acc = history.history["val_accuracy"]
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("Training and Validation accuracy")
plt.legend()
plt.figure()

plt.plot(epochs, loss, "bo", label="Training_loss")
plt.plot(epochs, val_loss, "b", label="Validation_loss")
plt.title("Training and Validation loss")
plt.legend()

plt.show()

在这里插入图片描述

特征图可视化

从测试数据中读取一条样本

img_path = "E:/code/python deeplearning/dataset/c_d_1/test/cat.2018.jpg"

from keras.preprocessing import image
import numpy as np

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.
print(img_tensor.shape)

在这里插入图片描述

显示该样本

import matplotlib.pyplot as plt

plt.imshow(img_tensor[0])
plt.show()

在这里插入图片描述

建立模型,输入为原图像,输出为原模型的前8层的激活输出的特征图

from keras import models

layer_outputs = [layer.output for layer in model.layers[:8]]
activation_model = models.Model(inputs=model.input, outputs=layer_outputs)

获得改样本的特征图

activations = activation_model.predict(img_tensor)

显示第一层激活输出特的第一个滤波器的特征图

import matplotlib.pyplot as plt
first_layer_activation = activations[0]
plt.matshow(first_layer_activation[0,:,:,1],  cmap="viridis")

在这里插入图片描述

显示前8层激活输出的全部特征图

#存储层的名称
layer_names = []
for layer in model.layers[:8]:
    layer_names.append(layer.name)
# 每行显示16个特征图
images_pre_row = 16  #每行显示的特征图数
# 循环8次显示8层的全部特征图
for layer_name, layer_activation in zip(layer_names, activations):
    n_features = layer_activation.shape[-1] #保存当前层的特征图个数
    size = layer_activation.shape[1]  #保存当前层特征图的宽高
    n_col = n_features // images_pre_row #计算当前层显示多少行
    #生成显示图像的矩阵
    display_grid = np.zeros((size*n_col, images_pre_row*size))
    #遍历将每个特张图的数据写入到显示图像的矩阵中
    for col in range(n_col):
        for row in range(images_pre_row):
        	#保存该张特征图的矩阵(size,size,1)
            channel_image = layer_activation[0,:,:,col*images_pre_row+row]
            #为使图像显示更鲜明,作一些特征处理
            channel_image -= channel_image.mean()
            channel_image /= channel_image.std()
            channel_image *= 64
            channel_image += 128 
            #把该特征图矩阵中不在0-255的元素值修改至0-255
            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")

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cyj5201314/article/details/113769185
今日推荐