基于tensorflow使用VGG16实现猫狗识别
import tensorflow as tf
import numpy as np
from tensorflow.keras import layers, models, optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator# 定义 VGG16 模型
class VGG16(tf.keras.Model):def __init__(self, num_classes=2):super(VGG16, self).__init__()self.features = models.Sequential([layers.Conv2D(64, (3, 3), padding='same', activation='relu', input_shape=(224, 224, 3)),layers.MaxPooling2D((2, 2), strides=(2, 2)),layers.Conv2D(128, (3, 3), padding='same', activation='relu'),layers.MaxPooling2D((2, 2), strides=(2, 2)),layers.Conv2D(256, (3, 3), padding='same', activation='relu'),layers.Conv2D(256, (3, 3), padding='same', activation='relu'),layers.MaxPooling2D((2, 2), strides=(2, 2)),layers.Conv2D(512, (3, 3), padding='same', activation='relu'),layers.Conv2D(512, (3, 3), padding='same', activation='relu'),layers.MaxPooling2D((2, 2), strides=(2, 2)),layers.Conv2D(512, (3, 3), padding='same', activation='relu'),layers.Conv2D(512, (3, 3), padding='same', activation='relu'),layers.MaxPooling2D((2, 2), strides=(2, 2)),])self.classifier = models.Sequential([layers.Flatten(),layers.Dense(4096, activation='relu'),layers.Dropout(0.5),layers.Dense(4096, activation='relu'),layers.Dropout(0.5),layers.Dense(num_classes, activation='softmax'),])def call(self, x):x = self.features(x)x = self.classifier(x)return x# 使用 ImageDataGenerator 加载并预处理数据集
data_dir = 'data'
input_shape = (224, 224)
batch_size = 4train_datagen = ImageDataGenerator(rescale=1.0/255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True
)
val_datagen = ImageDataGenerator(rescale=1.0/255)train_gen = train_datagen.flow_from_directory(directory=f'{data_dir}/train',target_size=input_shape,batch_size=batch_size,class_mode='binary'
)val_gen = val_datagen.flow_from_directory(directory=f'{data_dir}/validation',target_size=input_shape,batch_size=batch_size,class_mode='binary'
)# 初始化模型、优化器和损失函数
model = VGG16(num_classes=2)
# 构建模型结构(明确指定输入形状)
model.build(input_shape=(None, 224, 224, 3)) # None 表示动态批次大小# 查看模型结构
model.summary()
model.compile(optimizer=optimizers.Adam(learning_rate=0.0001),loss='sparse_categorical_crossentropy',metrics=['accuracy'])# 训练循环
epochs = 20
steps_per_epoch = train_gen.samples // batch_size
validation_steps = val_gen.samples // batch_sizefor epoch in range(epochs):print(f"=========== Epoch {epoch + 1} ==============")history = model.fit(train_gen,steps_per_epoch=steps_per_epoch,validation_data=val_gen,validation_steps=validation_steps,epochs=1)train_loss = history.history['loss'][0]val_loss = history.history['val_loss'][0]val_accuracy = history.history['val_accuracy'][0]print(f"训练集上的损失:{train_loss}")print(f"验证集上的损失:{val_loss}")print(f"验证集上的精度:{val_accuracy:.1%}")# 保存模型model.save_weights(f"Adogandcat_epoch_{epoch + 1}.h5")print("模型权重已保存。")#预测部分
# 定义和加载 VGG16 模型
vgg16 = VGG16(num_classes=2)
vgg16.build(input_shape=(None, 224, 224, 3))
vgg16.load_weights('Adogandcat_epoch_20.h5') # 替换为训练好的 VGG16 权重路径# 加载和预处理图像
def load_and_preprocess_image(image_path, target_size=(224, 224)):img = load_img(image_path, target_size=target_size) # 加载图像并调整大小img_array = img_to_array(img) # 转换为 NumPy 数组img_array = np.expand_dims(img_array, axis=0) # 添加批次维度img_array = preprocess_input(img_array) # VGG16 所需的标准化return img, img_array# 预测和显示图像
def predict_and_display(image_path, model, model_name):# 加载图像original_img, processed_img = load_and_preprocess_image(image_path)# 预测类别predictions = model(processed_img, training=False)predicted_class = np.argmax(predictions, axis=1)[0]confidence = predictions[0][predicted_class]# 显示结果plt.figure(figsize=(6, 6))plt.imshow(original_img)plt.axis('off')plt.title(f"Model: {model_name}\nPredicted Class: {predicted_class}\nConfidence: {confidence:.2f}")plt.show()# 测试图像路径
image_path = 'data/test/1.jpg' # 替换为实际图像路径# 使用 CustomCNN 预测
predict_and_display(image_path, custom_cnn, "Custom CNN")# 使用 VGG16 预测
predict_and_display(image_path, vgg16, "VGG16")
训练结果:
运行时间:46 mins. Found 18750 images belonging to 2 classes. Found 6250 images belonging to 2 classes. 2024-11-22 00:51:58.211251: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. 2024-11-22 00:51:58.612873: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1510] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 38404 MB memory: -> device: 0, name: NVIDIA A100-SXM4-40GB, pci bus id: 0000:4b:00.0, compute capability: 8.0 =========== Epoch 1 ============== 4687/4687 [==============================] - 140s 29ms/step - loss: 0.6943 - accuracy: 0.5031 - val_loss: 0.6932 - val_accuracy: 0.5010 训练集上的损失:0.6943416595458984 验证集上的损失:0.6932020783424377 验证集上的精度:50.1% 模型已保存。 =========== Epoch 2 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.6843 - accuracy: 0.5500 - val_loss: 0.6604 - val_accuracy: 0.6079 训练集上的损失:0.6842659711837769 验证集上的损失:0.660356879234314 验证集上的精度:60.8% 模型已保存。 =========== Epoch 3 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.6018 - accuracy: 0.6783 - val_loss: 0.4973 - val_accuracy: 0.7553 训练集上的损失:0.6018291711807251 验证集上的损失:0.4972682297229767 验证集上的精度:75.5% 模型已保存。 =========== Epoch 4 ============== 4687/4687 [==============================] - 139s 30ms/step - loss: 0.4743 - accuracy: 0.7762 - val_loss: 0.4171 - val_accuracy: 0.8156 训练集上的损失:0.4742658734321594 验证集上的损失:0.4170766770839691 验证集上的精度:81.6% 模型已保存。 =========== Epoch 5 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.3851 - accuracy: 0.8273 - val_loss: 0.3572 - val_accuracy: 0.8489 训练集上的损失:0.3850820064544678 验证集上的损失:0.3571555018424988 验证集上的精度:84.9% 模型已保存。 =========== Epoch 6 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.3096 - accuracy: 0.8676 - val_loss: 0.2901 - val_accuracy: 0.8841 训练集上的损失:0.30961713194847107 验证集上的损失:0.29008445143699646 验证集上的精度:88.4% 模型已保存。 =========== Epoch 7 ============== 4687/4687 [==============================] - 139s 30ms/step - loss: 0.2486 - accuracy: 0.8966 - val_loss: 0.2143 - val_accuracy: 0.9088 训练集上的损失:0.2486010491847992 验证集上的损失:0.2143394649028778 验证集上的精度:90.9% 模型已保存。 =========== Epoch 8 ============== 4687/4687 [==============================] - 139s 30ms/step - loss: 0.2155 - accuracy: 0.9101 - val_loss: 0.1907 - val_accuracy: 0.9205 训练集上的损失:0.2155471295118332 验证集上的损失:0.1906772404909134 验证集上的精度:92.0% 模型已保存。 =========== Epoch 9 ============== 4687/4687 [==============================] - 139s 30ms/step - loss: 0.1929 - accuracy: 0.9192 - val_loss: 0.1902 - val_accuracy: 0.9214 训练集上的损失:0.19291609525680542 验证集上的损失:0.19024263322353363 验证集上的精度:92.1% 模型已保存。 =========== Epoch 10 ============== 4687/4687 [==============================] - 143s 30ms/step - loss: 0.1751 - accuracy: 0.9284 - val_loss: 0.1607 - val_accuracy: 0.9337 训练集上的损失:0.17511127889156342 验证集上的损失:0.1606709510087967 验证集上的精度:93.4% 模型已保存。 =========== Epoch 11 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.1559 - accuracy: 0.9391 - val_loss: 0.1388 - val_accuracy: 0.9416 训练集上的损失:0.155866801738739 验证集上的损失:0.13884252309799194 验证集上的精度:94.2% 模型已保存。 =========== Epoch 12 ============== 4687/4687 [==============================] - 137s 29ms/step - loss: 0.1457 - accuracy: 0.9401 - val_loss: 0.1550 - val_accuracy: 0.9470 训练集上的损失:0.14570224285125732 验证集上的损失:0.15503031015396118 验证集上的精度:94.7% 模型已保存。 =========== Epoch 13 ============== 4687/4687 [==============================] - 138s 30ms/step - loss: 0.1359 - accuracy: 0.9451 - val_loss: 0.1201 - val_accuracy: 0.9520 训练集上的损失:0.1359049379825592 验证集上的损失:0.12010601162910461 验证集上的精度:95.2% 模型已保存。 =========== Epoch 14 ============== 4687/4687 [==============================] - 138s 30ms/step - loss: 0.1293 - accuracy: 0.9489 - val_loss: 0.1366 - val_accuracy: 0.9486 训练集上的损失:0.12929560244083405 验证集上的损失:0.13661223649978638 验证集上的精度:94.9% 模型已保存。 =========== Epoch 15 ============== 4687/4687 [==============================] - 139s 30ms/step - loss: 0.1206 - accuracy: 0.9516 - val_loss: 0.1472 - val_accuracy: 0.9478 训练集上的损失:0.12062755972146988 验证集上的损失:0.1471676379442215 验证集上的精度:94.8% 模型已保存。 =========== Epoch 16 ============== 4687/4687 [==============================] - 137s 29ms/step - loss: 0.1174 - accuracy: 0.9544 - val_loss: 0.1282 - val_accuracy: 0.9475 训练集上的损失:0.11741997301578522 验证集上的损失:0.1282137632369995 验证集上的精度:94.8% 模型已保存。 =========== Epoch 17 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.1139 - accuracy: 0.9552 - val_loss: 0.1264 - val_accuracy: 0.9563 训练集上的损失:0.11387941241264343 验证集上的损失:0.12638334929943085 验证集上的精度:95.6% 模型已保存。 =========== Epoch 18 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.1123 - accuracy: 0.9557 - val_loss: 0.1192 - val_accuracy: 0.9585 训练集上的损失:0.11233851313591003 验证集上的损失:0.11923010647296906 验证集上的精度:95.9% 模型已保存。 =========== Epoch 19 ============== 4687/4687 [==============================] - 138s 29ms/step - loss: 0.1124 - accuracy: 0.9579 - val_loss: 0.1174 - val_accuracy: 0.9534 训练集上的损失:0.11243574321269989 验证集上的损失:0.11737789213657379 验证集上的精度:95.3% 模型已保存。 =========== Epoch 20 ============== 4687/4687 [==============================] - 150s 32ms/step - loss: 0.0986 - accuracy: 0.9616 - val_loss: 0.1180 - val_accuracy: 0.9539 训练集上的损失:0.09860984236001968 验证集上的损失:0.11801616102457047 验证集上的精度:95.4% 模型已保存。 |
原文使用的是pytorch:
VGG网络详解(实现猫猫和狗狗识别)_vgg卷积神经网络猫狗实验-CSDN博客