El aprendizaje profundo de Keras utiliza la red neuronal preentrenada VGG16 para lograr la clasificación de gatos y perros

El aprendizaje profundo de Keras utiliza la red neuronal preentrenada VGG16 para lograr la clasificación de gatos y perros

Acabo de estar en contacto con el aprendizaje profundo recientemente, y Keras es el más adecuado para comenzar entre muchos marcos de aprendizaje profundo, y la clasificación de imágenes de gatos y perros también es un caso clásico en la visión por computadora. Permítanme presentarles la implementación. proceso:

Pre-ambiente

  1. Python3.6 Pip3
  2. Keras, usando Tensorflow como backend
  3. entumecido
  4. matplotlib
  5. abiertocv

Proceso de implementación

entrenamiento modelo

En primer lugar, necesitamos importar los paquetes necesarios. Para este modelo de entrenamiento, se utiliza el modelo de red preentrenado VGG16. También es una buena noticia para aquellos que no tienen soporte de GPU. Puede acelerar el entrenamiento del modelo y también puede mejorar en gran medida la precisión de los conjuntos de datos de lotes pequeños.

import keras
import tensorflow as tf
from keras import layers
import numpy as np
import os
import shutil
import matplotlib.pyplot as plt
%matplotlib inline
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16

A partir de los recursos del conjunto de datos de gatos y perros que se encuentran en Internet, cargue el conjunto de datos de gatos y perros y divida los datos de entrenamiento (entrenamiento) de gatos y perros y los datos de prueba (prueba). He subido el conjunto de datos original de gatos y perros al disco de la nube de Baidu, recoja los artículos requeridos al final del artículo.

# 创建划分好的训练测试目录
BASE_DIR = './cat_dog'
train_dir = os.path.join(BASE_DIR, 'train')
train_dir_dog = os.path.join(train_dir, 'dog')
train_dir_cat = os.path.join(train_dir, 'cat')

test_dir = os.path.join(BASE_DIR, 'test')
test_dir_dog = os.path.join(test_dir, 'dog')
test_dir_cat = os.path.join(test_dir, 'cat')
train_dir_dog, test_dir_cat

os.mkdir(BASE_DIR)
os.mkdir(train_dir)
os.mkdir(train_dir_dog)
os.mkdir(train_dir_cat)
os.mkdir(test_dir)
os.mkdir(test_dir_dog)
os.mkdir(test_dir_cat)

# 数据集拷贝
source_dir = './source_data/train'

# 拷贝1000张猫的训练集到新划分的目录
fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(train_dir_cat, fname)
    shutil.copyfile(s, d)

# 拷贝1000张狗的训练集到新划分的目录
fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(train_dir_dog, fname)
    shutil.copyfile(s, d)

# 拷贝猫和狗测试集图片各500张,共1000张
fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(test_dir_dog, fname)
    shutil.copyfile(s, d)

fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(test_dir_cat, fname)
    shutil.copyfile(s, d)

Cree un iterador de datos de imagen y normalice la imagen original

train_datagen = ImageDataGenerator(rescale=1 / 255)
test_datagen = ImageDataGenerator(rescale=1 / 255)

# 训练集数据生成器,从数据目录生成,读取成200*200的统一图像resize,本质是一个二分类问题,model我们使用binary
train_generator = train_datagen.flow_from_directory(train_dir, 
target_size=(200, 200), batch_size=20, class_mode='binary')

# 测试集数据
test_generator = test_datagen.flow_from_directory(test_dir, 
target_size=(200, 200), batch_size=20, class_mode='binary')

Usando Matplotlib, podemos generar la imagen; los datos de la imagen son esencialmente el valor de datos de color de los tres canales, es decir, el valor RGB.

# [批次](批次数据集, 批次二分类结果)[批次数据集下标] --- 对应迭代器的数据格式
# 0 为猫;1 为狗  --- 二分类结果表示
plt.imshow(train_generator[0][0][0])
print(train_generator[0][1][0])

inserte la descripción de la imagen aquí
Inicialice la red neuronal preentrenada VGG16; use la red vgg, use los pesos imageNet, ya sea que include_top incluya la última capa completamente conectada y la capa de salida,

covn_base = VGG16(weights='imagenet', include_top=False, input_shape=(200,200,3))

Utilice summary() para ver la estructura de la red neuronal. Puede ver que la estructura de VGG16 también se compone de varias capas de Conv2D (convolución) y MaxPooling2D (agrupación).

covn_base.summary()

inserte la descripción de la imagen aquí
Use la red VGG para extraer el valor de la característica de la imagen y colóquelo en la red lineal para entrenar y mejorar la velocidad

batch_size = 20
def extract_features(data_generator, sample_count):
    i = 0
    features = np.zeros(shape=(sample_count, 6, 6, 512))
    labels = np.zeros(shape=(sample_count))
    for inputs_batch, labels_batch in data_generator:
        features_batch = covn_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_featrues, train_labels = extract_features(train_generator, 2000)
test_featrues, test_labels = extract_features(test_generator, 1000)

Cree la capa densa completamente conectada de su propio modelo y emita los resultados; use GlobalAveragePooling2D para aplanar los datos de imagen procesados ​​por VGG16 (es decir, convertirlos en datos unidimensionales) y, finalmente, reduzca al problema de y=w1x1+w2x2. ..+b. Se emite el resultado; use la función de activación relu; use Dropout para suprimir el sobreajuste; finalmente emita el resultado, porque el resultado es una clasificación binaria, es decir, 0 es un gato y 1 es un perro. Por lo tanto, solo hay un resultado de salida, por lo que la función sigmoidea se usa para generar el resultado de la clasificación binaria.

model = keras.Sequential()
model.add(layers.GlobalAveragePooling2D(input_shape=(6, 6, 512)))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

Compile el modelo; use la función de activación de Adam y ajuste la tasa de optimización; debido a que es un problema de dos categorías, la función de pérdida aquí usa binary_crossentropy

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0005/10), loss='binary_crossentropy', metrics=['acc'])

Comience a entrenar el modelo; pruebe el conjunto de prueba durante el entrenamiento, aquí un total de 50 entrenamientos

history = model.fit(train_featrues,train_labels, epochs=50, 
batch_size=50, validation_data=(test_featrues, test_labels))

Los siguientes son los resultados del entrenamiento. Entre ellos, loss es el valor de pérdida del conjunto de entrenamiento, acc es la tasa de precisión del conjunto de entrenamiento, val_loss es el valor de pérdida del conjunto de prueba y val_acc es la tasa de precisión del conjunto de prueba. Se puede ver que los resultados son relativamente ideales, la precisión del conjunto de entrenamiento y el conjunto de prueba puede alcanzar alrededor del 90% y el ajuste es muy bueno.
inserte la descripción de la imagen aquí
Usando Matplotlib para dibujar las curvas de precisión del siguiente conjunto de entrenamiento y conjunto de prueba, puede ver los cambios en el proceso de entrenamiento con mayor claridad.

plt.plot(range(50), history.history.get('val_acc'), c='r', label='val_acc')
plt.plot(range(50), history.history.get('acc'), c='b', label='acc')
plt.legend

inserte la descripción de la imagen aquí
Guarde el modelo entrenado como un archivo de tipo h5 local

model.save('cat_dog_model.h5')

Una vez que se completa el proceso de capacitación anterior, el siguiente paso es usar el modelo entrenado guardado para probar los datos reales

prueba modelo

En la prueba del modelo, por conveniencia, usamos OpenCV para ayudarnos a cambiar el tamaño de las imágenes adquiridas en la red y mostrar los resultados de salida convenientemente.
Importe los paquetes necesarios.

import tensorflow as tf
import numpy as np
from keras.models import load_model
import cv2

Definir la función de visualización de imágenes de OpenCV

def show(image):
    cv2.namedWindow('test', 0)
    cv2.imshow('test', image)
    # 0任意键终止窗口
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Cargue el peso de VGG16 y el modelo de entrenamiento guardado

covn_base = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_shape=(200, 200, 3))
cat_dog_model = load_model('./cat_dog_model.h5')

Use OpenCV para leer la imagen y cambie el tamaño de la imagen a un tamaño de 200✖️200, y expanda los datos de la imagen al formato de datos requerido por VGG16

image = cv2.imread('cat1.jpeg')
resize_image = cv2.resize(image, (200, 200), interpolation=cv2.INTER_AREA)
input_data = np.expand_dims(resize_image, axis=0)

Use VGG16 y su propio modelo entrenado para predecir la imagen

result = int(cat_dog_model.predict(covn_base.predict(input_data))[0][0])

Emitir el resultado del reconocimiento y mostrar la imagen de entrada

if result == 1:
    print("狗")
if result == 0:
    print("猫")
show(resize_image)

Puede ver que el siguiente es el resultado del reconocimiento, el gato es preciso y
inserte la descripción de la imagen aquí
la imagen del perro se reconoce y el resultado es preciso
inserte la descripción de la imagen aquí

Este es el final del artículo. Incluso si este caso es una pequeña prueba del aprendizaje profundo de Keras, espero que también pueda usarse como uno de los casos pequeños para que todos ingresen al aprendizaje profundo.

Conjunto de datos de perros y gatos Enlace de disco de red de Baidu

Enlace: https://pan.baidu.com/s/16K4P5Nb1k5_sfFml-qEF2g Código de extracción: mchl

Supongo que te gusta

Origin blog.csdn.net/wFitting/article/details/123921832
Recomendado
Clasificación