深度学习之基于CNN和VGG19实现灵笼人物识别

VGG19是VGG网络中一个更复杂的网络,相比较于VGG16,它的层数更深。
VGG19网络都使用了同样大小的卷积核尺寸(3x3)和最大池化尺寸(2x2)。但是它的训练时间过长,调参难度大,并且需要的存储容量大,不利于部署。
本次基于CNN和VGG19,对灵笼人物进行识别。其中VGG19网络分别调用了官方模型和自己搭建的模型。

1.导入库

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import os,PIL,pathlib
from tensorflow import keras
from tensorflow.keras import layers,models,Sequential,Input
from tensorflow.keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout
from tensorflow.keras.models import Model

2.数据加载

①添加文件路径

data_dir = "E:/tmp/.keras/datasets/linglong_photos"
data_dir = pathlib.Path(data_dir)

②构建一个ImageDataGenerator

#因为训练集和测试集是在一个文件夹中,所以构建一个ImageDataGenerator就可以
train_data_gen = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./255,
    rotation_range=45,
    shear_range=0.2,
    validation_split=0.2,#以8:2的比例划分训练集和测试集
    horizontal_flip=True
)

③划分训练集和测试集

train_ds = train_data_gen.flow_from_directory(
    directory=data_dir,
    target_size=(height,width),
    batch_size=batch_size,
    shuffle=True,
    class_mode='categorical',
    subset='training'
)
test_ds = train_data_gen.flow_from_directory(
    directory=data_dir,
    target_size=(height,width),
    batch_size=batch_size,
    class_mode='categorical',
    subset='validation'
)

结果如下:

Found 225 images belonging to 6 classes.
Found 55 images belonging to 6 classes.

3.设置超参数

height = 224
width = 224
batch_size = 16
epochs = 10

4.搭建CNN网络

网络结构:3层卷积池化层+Flatten+全连接层

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(16,3,padding="same",activation="relu",input_shape=(height,width,3)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32,3,padding="same",activation="relu"),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64,3,padding="same",activation="relu"),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(128,3,padding="same",activation="relu"),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(1024,activation="relu"),
    tf.keras.layers.Dense(512,activation="relu"),
    tf.keras.layers.Dense(6,activation="softmax")
])

网络编译&&运行

model.compile(optimizer="adam",
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=["acc"])
history = model.fit(
    train_ds,
    validation_data=test_ds,
    epochs=epochs
)

实验结果如下:
深度学习之基于CNN和VGG19实现灵笼人物识别_第1张图片
不尽如人意,这个上下波动就很无语。将epochs调大后的结果如下:

深度学习之基于CNN和VGG19实现灵笼人物识别_第2张图片
在20次训练之后没有任何的效果。
修改优化器:

opt = tf.keras.optimizers.Adam(learning_rate=1e-5)
model.compile(optimizer=opt,
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=["acc"])

深度学习之基于CNN和VGG19实现灵笼人物识别_第3张图片
在改变优化器之后,效果得到了很大的改善,准确率也得到了提高。

4.VGG19网络

网络结构如下所示:
在这里插入图片描述
①官方模型

conv_base = tf.keras.applications.VGG19(weights='imagenet',include_top=False)
#设置为不可训练
conv_base.trainable =False
#模型搭建
model = tf.keras.Sequential()
model.add(conv_base)
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(1024,activation='relu'))
model.add(tf.keras.layers.Dense(6,activation='sigmoid'))

opt = tf.keras.optimizers.Adam(learning_rate=1e-5)
model.compile(optimizer=opt,
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=["acc"])
history = model.fit(
    train_ds,
    validation_data=test_ds,
    epochs=epochs
)

实验结果如下所示(epochs=10):
深度学习之基于CNN和VGG19实现灵笼人物识别_第4张图片
相比于上面的网络,效果还算可以。没有出现大规模的波动,最后的准确率也比较高。
②自己搭建VGG19网络

参考自K同学啊

def VGG19(nb_classes,input_shape):
    input_ten = Input(shape=input_shape)
    #1block
    x = Conv2D(64,(3,3),activation='relu',padding='same',name='block1_conv1')(input_ten)
    x = Conv2D(64,(3,3),activation='relu',padding='same',name='block1_conv2')(x)
    x = MaxPooling2D((2,2),strides=(2,2),name='block1_pool')(x)
    #2block
    x = Conv2D(128,(3,3),activation='relu',padding='same',name='block2_conv1')(x)
    x = Conv2D(128,(3,3),activation='relu',padding='same',name='block2_conv2')(x)
    x = MaxPooling2D((2,2),strides=(2,2),name='block2_pool')(x)
    #3block
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv4')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)
    #4block
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv4')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)
    #5block
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv4')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)
    #Full
    x = Flatten()(x)
    x = Dense(4096, activation='relu', name='fc1')(x)
    x = Dense(4096, activation='relu', name='fc2')(x)
    output_ten = Dense(nb_classes, activation='softmax', name='predictions')(x)

    model = Model(input_ten, output_ten)
    return model
model = VGG19(6,(width,height,3))

实验结果如下所示:
深度学习之基于CNN和VGG19实现灵笼人物识别_第5张图片
就特么离谱,都不知道为啥会有这么大的差别,希望路过的大佬批评指正。
总结
经过改变优化器以及增加epochs之后,自己搭建的CNN准确率是比较好的,但是出现了较大规模的波动。VGG19网络的训练速度确实比较慢,但是官方模型的准确率是比较好的,没有出现CNN模型的波动情况。由于硬件原因,博主在实验时的epochs设置的都比较小,可以尝试一下epochs增大时的效果如何。自己搭建的VGG19网络,最后的模型准确率也比较高,但是波动较大,而且很不稳定,具体原因不清楚。

你可能感兴趣的:(机器学习,神经网络,tensorflow,深度学习)