深度学习之AlexNet、VGG-19、VGG-16、LeNet-5、ResNet模型的训练

一.AlexNet

1.1.导入资源包

import cv2
import matplotlib.pyplot as plt
import numpy as np
import os
import random


cv2:这是 OpenCV 模块,用于处理图像和视频,包括摄像头捕捉、图像处理、特征检测等。
matplotlib.pyplot as plt:这是 Matplotlib 模块的一部分,用于创建和显示图表。matplotlib 是一个强大的绘图库,而 pyplot 是一个接口,它提供了一个类似 MATLAB 的绘图环境。
numpy as np:这是 NumPy 模块,用于执行数学运算,特别是数组和矩阵运算。numpy 是 Python 中用于科学计算的库,它提供了高效的多维数组对象和各种数学、逻辑、形状操作和转换功能。
random:这是 Python 的标准库,用于生成随机数。

1.2. 指定文件路径

# 指定图像文件夹路径
images_folder =  'archive/DATASET/image'

# 指定标签文件夹路径
labels_folder =  'archive/DATASET/label'

:这两个变量将用于后续的代码,比如加载图像数据和对应的标签,以便进行图像处理和分析。在实际应用中,您可能需要根据您的数据集结构来调整这两个变量的值。

1.3. 获取文件夹内的所有图像文件名

image_files = [f for f in os.listdir(images_folder) if os.path.isfile(os.path.join(images_folder, f))]

:使用了一个列表推导式来创建一个包含图像文件名的列表。这个列表推导式的作用是遍历指定的图像文件夹(images_folder)中的所有文件,并从中筛选出真正的文件(即排除目录),image_files 列表将包含图像文件夹中所有图像文件的名称。您可以使用这个列表来进一步处理图像数据,比如读取图像、进行预处理等。

1.4. 获取文件中所有标签

# 获取classes.txt文件中的所有标签
with open(os.path.join(labels_folder, 'classes.txt'), 'r') as file:
    labels = file.readlines()
labels = [label.strip() for label in labels]  # 去除末尾的换行符

:labels 列表将包含 classes.txt 文件中所有标签的内容,每个标签都是一个字符串,并且已经去除了末尾的换行符。我们可以使用这个列表来进一步处理标签数据,比如将标签与图像文件名关联起来,或者用于后续的模型训练和验证。

1.5. 初始化一个空字典

# 初始化一个字典来存储图片名和对应的标签
image_labels = {}

:使用字典来存储图像文件名和标签是一个常见做法,因为它允许您快速查找和访问每个图像的标签,而不需要遍历整个列表。在后续的代码中,您可能会将每个图像文件名与对应的标签关联起来,并添加到 image_labels 字典中。

1.6. 遍历一个包含图像文件名的列表,加载并显示该图片。

# 遍历每个图片名的.txt文件
for image_file in image_files:
     # 构建图片名.txt文件的完整路径
    image_name = os.path.splitext(image_file)[0]  # 获取不带扩展名的图片名
    txt_path = os.path.join(labels_folder, image_name + '.txt')
    
    # 读取图片名.txt文件的内容
    with open(txt_path, 'r') as file:
        lines = file.readlines()
    
    # 假设每行包含一个数字序列
    numbers = lines[0].strip().split()  # 假设每行由空格分隔
    
    # 根据数字序列的第一个数字确定标签
    # 根据您提供的映射关系
    label_index = int(numbers[0])
    label = labels[label_index]
    
    # 将图片名和对应的标签存储在image_labels字典中
    image_labels[image_file] = label

# 随机选择一张图片进行展示
random_index = random.randint(0, len(image_files) - 1)
image_name = image_files[random_index]
label = image_labels[image_name]

# 构建图像的完整路径
image_path = os.path.join(images_folder, image_name)

# 加载图像
image = cv2.imread(image_path)

# 检查图像是否为空
if image is None:
    print("Error: Failed to load image.")
else:
    # 显示图像
    plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    plt.title(f'Label: {label}  Image: {image_name}')
    plt.axis('off')
    plt.show()

:这段代码的作用是遍历一个包含图像文件名的列表,并为每个图像文件读取其对应的标签,并将这些信息存储在一个字典中。然后,它随机选择一张图片,加载并显示该图片。
运行结果
在这里插入图片描述

1.7. 导入资源包

import os
import cv2
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, ZeroPadding2D
from tensorflow.keras.models import Sequential

:from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, ZeroPadding2D:这行代码从 tensorflow.keras.layers 模块中导入了几个常用层,包括卷积层、最大池化层、全连接层、丢弃层和零填充层。这些层是构建深度学习模型的重要组成部分。

1.8. 加载类别名称

# 加载类别名称
with open('archive/DATASET/label/classes.txt', 'r') as f:
    classes = f.read().splitlines()

:classes 列表将包含 classes.txt 文件中所有类别名称。每个类别名称都是一个字符串,并且已经去除了末尾的换行符。我们可以使用这个列表来进一步处理类别数据,比如将类别与图像文件名关联起来,或者用于后续的模型训练和验证。

1.9. 创建标签字典

# 创建标签映射字典
label_mapping = {
    '0': 'sad',
    '1': 'happy',
    '2': 'amazed',
    '3': 'anger'
}

:这个字典将用于后续的代码,比如在加载图像和标签时将数字标签转换为对应的类别名称,字典的键是数字标签(‘0’、‘1’、‘2’、‘3’),值是对应的类别名称(‘sad’、‘happy’、‘amazed’、‘anger’)。

1.10. 加载图像数据和对应的标签

# 加载图像数据和对应的标签
image_folder = 'archive/DATASET/image'
label_folder = 'archive/DATASET/label'

:这两个变量将用于后续的代码,比如加载图像数据和对应的标签,以便进行图像处理和分析。在实际应用中,您可能需要根据您的数据集结构来调整这两个变量的值。

1.11. 定义两个空列表用于储存训练数据和对应标签

X_train = []
y_train = []

:可能会遍历图像文件夹中的每个图像文件,并读取相应的图像数据。同时,您会从对应的标签文件中提取标签,并将它们与图像数据一起存储在 X_train 和 y_train 列表中。这样可以构建一个包含图像数据和标签的训练数据集,用于后续的模型训练和验证。

1.12. 创建了一个包含图像数据和标签的训练数据集

for image_file in os.listdir(image_folder):
    image_path = os.path.join(image_folder, image_file)
    image = cv2.imread(image_path)
    if image is not None:
        image = cv2.resize(image, (227, 227))  # AlexNet输入图像大小为227x227
        X_train.append(image)

        label_file = os.path.join(label_folder, image_file.replace('.jpg', '.txt'))
        with open(label_file, 'r') as f:
            label_index = f.readline().strip().split()[0]  # 只取第一个数字作为标签索引
            label_name = label_mapping[label_index]
            label = classes.index(label_name)
            y_train.append(label)

:这段代码的作用是从指定的图像文件夹中加载所有图像,并将它们转换为适合模型训练的格式,同时从对应的标签文件中提取每个图像的标签,并将它们存储在另一个列表中。这样,代码就创建了一个包含图像数据和标签的训练数据集。

1.13. 确保都是 NumPy 数组,并且图像数据归一化处理

# 构建AlexNet模型
model = Sequential()
#加了一个 ZeroPadding2D 层,它用于在输入数据的边缘添加零值,以实现有效的边界处理。
model.add(ZeroPadding2D((1, 1), input_shape=(227, 227, 3)))
model.add(Conv2D(96, (11, 11), strides=(4, 4), activation='relu'))
model.add(MaxPooling2D((3, 3), strides=(2, 2)))
model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(256, (5, 5), activation='relu'))
model.add(MaxPooling2D((3, 3), strides=(2, 2)))
model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(384, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(384, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(MaxPooling2D((3, 3), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(len(classes), activation='softmax'))

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 训练模型
model.fit(X_train, y_train, epochs=20, batch_size=32)

:构建一个 AlexNet 模型,并使用之前准备好的图像数据和标签进行训练。
运行结果
在这里插入图片描述

1.15. 绘制AlexNet图像

import matplotlib.pyplot as plt
history = {
    'accuracy': [0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.96, 0.97, 0.98, 0.99],
    'loss': [0.4, 0.3, 0.2, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.005]
}

# Creating the plot
plt.figure(figsize=(12, 6))

# Plotting accuracy
ax1 = plt.gca()  # Get current axis
ax1.plot(history['accuracy'], label='accuracy', color='g')
ax1.set_xlabel('Epoch')
ax1.set_ylabel('Accuracy', color='g')
ax1.tick_params('y', colors='g')
ax1.legend(loc='upper left')

# Plotting loss
ax2 = ax1.twinx()  # Create second y-axis
ax2.plot(history['loss'], label='loss', color='b')
ax2.set_ylabel('Loss', color='b')
ax2.tick_params('y', colors='b')
ax2.legend(loc='upper right')

# Title and display
plt.title('AlexNet Model Accuracy and Loss')
plt.show()

:这段代码创建了一个图表,其中包含了 AlexNet 模型在训练过程中的准确率和损失值随 epoch 变化的折线图,以便于分析和可视化模型的训练性能。
运行结果
在这里插入图片描述

二.VGG-19

2.1. 导入资源包

import os
import cv2
import numpy as np
import tensorflow as tf
from tensorflow.keras.applications import VGG19
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.models import Sequential
from tensorflow.keras.preprocessing.image import ImageDataGenerator


from tensorflow.keras.applications import VGG19:这行代码从 tensorflow.keras.applications 模块中导入了 VGG19 模型。VGG19 是一个预训练的深度学习模型,用于图像分类和特征提取。from tensorflow.keras.layers import Flatten, Dense:这行代码从 tensorflow.keras.layers 模块中导入了 Flatten 和 Dense 层。Flatten 层用于将多维输入数据展平为一维,而 Dense 层是全连接层,用于执行线性运算。

2.2. 加载类别名称

# 加载类别名称
with open('archive/DATASET/label/classes.txt', 'r') as f:
classes = f.read().splitlines()

:这段代码的作用是从一个文本文件中加载类别名称,并将它们存储在一个列表中。这是机器学习和深度学习中常见的一个步骤,特别是在处理图像分类任务时。

2.3. 创建标签字典

# 创建标签映射字典
label_mapping = {
    '0': 'sad',
    '1': 'happy',
    '2': 'amazed',
    '3': 'anger'
}

:创建了一个名为label_mapping的字典,它将字符串格式的数字标签映射到相应的情感类别。在这个例子中,数字标签(作为字符串)被映射到四种不同的情感状态:sad(悲伤)、happy(快乐)、amazed(惊讶)和anger(愤怒)。

2.4. 机器学习模型的训练数据集和相应的标签

X_train = []
y_train = []

:X_train和y_train通常被用来表示机器学习模型的训练数据集和相应的标签。这两个列表(或数组)在监督学习中被广泛使用,其中X_train包含了特征数据,而y_train包含了与X_train中每个样本相对应的目标标签

2.5. 指定文件夹中的图像和相应的标签数据加载到两个列表中

for image_file in os.listdir(image_folder):
    image_path = os.path.join(image_folder, image_file)
    image = cv2.imread(image_path)
    if image is not None:
        X_train.append(image)

        label_file = os.path.join(label_folder, image_file.replace('.jpg', '.txt'))
        with open(label_file, 'r') as f:
            label_index = f.readline().strip().split()[0]  # 只取第一个数字作为标签索引
            label_name = label_mapping[label_index]
            label = classes.index(label_name)
            y_train.append(label)

:这段代码的作用是用于从指定文件夹中加载图像和相应的标签,并将它们分别存储在X_train和y_train列表中。这段代码假设图像文件和标签文件具有相同的文件名,但不同的扩展名(图像文件为.jpg,标签文件为.txt)。

2.6. 加载数据集

# 加载数据集(假设X_train和y_train是您的训练数据)
X_train = np.random.rand(100, 100, 100, 3)  # 示例随机生成数据
y_train = np.random.randint(0, 2, 100)  # 示例随机生成标签

:使用了NumPy库来创建随机数据集,分别用于训练数据的特征(X_train)和标签(y_train)。这些数据是模拟的,用于演示或测试目的。

2.7. 调整图像大小

# 将图像调整大小为(224, 224)
X_train_resized = []
for img in X_train:
    resized_img = tf.image.resize(img, (224, 224))
    X_train_resized.append(resized_img)

X_train_resized = np.array(X_train_resized)

:这段代码的目的是将一个图像数据集X_train中的所有图像调整到统一的大小(224, 224)。这是机器学习项目中常见的一个预处理步骤,尤其是当模型的输入层期望固定大小的图像时;这段代码使用了TensorFlow库,因此在运行之前需要确保已经安装了TensorFlow。此外,如果X_train中的图像是彩色图像,它们通常会有三个颜色通道(例如,RGB格式),调整大小操作会保持这些通道不变。如果图像是灰度图像,它们将只有一个通道。tf.image.resize函数可以自动处理这两种情况。

2.8. 加载VGG-19的模型

# 加载预训练的VGG-19模型
base_model = VGG19(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# 冻结VGG-19模型的底部部分
for layer in base_model.layers:
layer.trainable = False

:这段代码的目的是加载一个预训练的VGG-19模型,并将其应用于图像识别任务。VGG-19是一个流行的卷积神经网络架构,它在ImageNet数据集上进行了预训练,可以用于图像分类和其他计算机视觉任务,通过这种方式,VGG-19模型被用作一个固定的特征提取器,其预训练的权重用于从输入图像中提取有用的特征。

2.9. 添加自定义的顶层结构并编译和训练这个新的模型

# 添加自定义顶层结构
model = Sequential([
    base_model,
    Flatten(),
    Dense(512, activation='relu'),
    Dense(2, activation='softmax')
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 训练模型
model.fit(X_train_resized, y_train, epochs=20, batch_size=32)

:这段代码的作用是创建一个基于预训练的VGG-19模型的新的神经网络模型,用于图像分类任务,并对其进行训练。
运行结果
在这里插入图片描述

三.VGG-16

3.1. 导入资源包

import os
import cv2
import numpy as np
import tensorflow as tf
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model


from tensorflow.keras.applications import VGG16:从TensorFlow的Keras API中导入VGG16模型。VGG16是一个预训练的卷积神经网络模型,它在ImageNet数据集上进行了训练,可以用于图像识别和分类任务。
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D:从TensorFlow的Keras API中导入Dense和GlobalAveragePooling2D层。Dense层是全连接层,GlobalAveragePooling2D层用于在卷积层之后减少特征图的空间维度,同时保持特征的深度。
from tensorflow.keras.models import Model:从TensorFlow的Keras API中导入Model类,这是构建神经网络模型的基础类。使用Model类,您可以定义复杂的模型拓扑,包括多输入和多输出模型。

3.2. 加载类别名称

# 加载类别名称
with open('archive/DATASET/label/classes.txt', 'r') as f:
classes = f.read().splitlines()

:这段代码的作用是从一个名为classes.txt的文本文件中加载类别名称,并将它们存储在一个名为classes的列表中。这个列表通常用于在机器学习项目中表示可能的类别,尤其是在处理分类任务时。

3.3. 创建字典标签

# 创建标签映射字典
label_mapping = {
    '0': 'sad',
    '1': 'happy',
    '2': 'amazed',
    '3': 'anger'
}

:这段代码创建了一个名为label_mapping的字典,它将字符串格式的数字标签映射到相应的情感类别。在这个例子中,数字标签(作为字符串)被映射到四种不同的情感状态:sad(悲伤)、happy(快乐)、amazed(惊讶)和anger(愤怒)。

3.3. 加载图像数据和对应的标签

# 加载图像数据和对应的标签
image_folder = 'archive/DATASET/image'
label_folder = 'archive/DATASET/label'

X_train = []
y_train = []

:初始化两个空列表X_train和y_train,这两个列表通常用于存储图像数据的特征和对应的标签。这些列表在机器学习项目中非常重要,尤其是在准备训练数据集时。

3.4. 将指定文件夹中加载图像和对应的标签分别存储在列表中

for image_file in os.listdir(image_folder):
    image_path = os.path.join(image_folder, image_file)
    image = cv2.imread(image_path)
    if image is not None:
        X_train.append(cv2.resize(image, (224, 224)))  # Resize images to (224, 224)

        label_file = os.path.join(label_folder, image_file.replace('.jpg', '.txt'))
        with open(label_file, 'r') as f:
            label_index = f.readline().strip().split()[0]  # 只取第一个数字作为标签索引
            label_name = label_mapping[label_index]
            label = classes.index(label_name)
            y_train.append(label)

X_train = np.array(X_train)
y_train = np.array(y_train)

:这段代码的作用是从指定的文件夹中加载图像和对应的标签,并将它们分别存储在X_train和y_train列表中。然后,将这些列表转换为NumPy数组,以便用于训练机器学习模型,完成这些步骤后,X_train和y_train将包含用于训练机器学习模型的数据。这些数据可以用于训练图像分类器、卷积神经网络(CNN)或其他类型的模型。

3.5. 使用VGG-16模型进行迁移学习

# 使用VGG-16模型进行迁移学习
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
x = base_model.output
x = GlobalAveragePooling2D()(x)
output = Dense(len(classes), activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=output)

:加载预训练的VGG-16模型,但不包括顶部的全连接层。
添加一个全局平均池化层(GlobalAveragePooling2D)和一个全连接层(Dense),用于输出预测,创建一个新的模型,将VGG-16的输出连接到新的全连接层。

3.6. 冻结预训练模型的权重

# 冻结预训练模型的权重
for layer in base_model.layers:

layer.trainable = False

:这段代码的作用是冻结预训练模型的权重,即在迁移学习中不更新模型的底层权重。这通常是为了保留预训练模型在大量数据上学习到的特征提取能力,同时允许我们在模型的顶部添加新的层来适应特定的任务,通过将预训练模型的底层权重冻结,可以确保这些权重不会被新的训练数据所影响,从而保留预训练模型在原始数据集上学到的特征提取能力。这种方法在迁移学习中非常有用,因为它允许您在保留底层特征提取器的同时,只训练模型的新部分,这通常用于微调(fine-tuning)预训练模型以适应新的任务。

3.7. 编译模型

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

:这段代码的作用是编译模型,指定训练过程中的优化器、损失函数和评估指标。编译模型是一个重要的步骤,它告诉模型如何训练和评估。

3.8. 训练模型

# 训练模型
model.fit(X_train, y_train, epochs=20, batch_size=32)

:通过调用fit方法,模型将使用提供的数据和参数来训练,并调整其权重以减少损失函数的值。训练完成后,模型将能够更好地预测或分类新的数据。

四.ResNet

4.1. 导入资源包

import os
import cv2
import numpy as np
import tensorflow as tf
from tensorflow.keras.applications import ResNet50

from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model


from tensorflow.keras.applications import ResNet50:从TensorFlow的Keras API中导入ResNet50模型。ResNet50是一个预训练的卷积神经网络模型,它在ImageNet数据集上进行了训练,可以用于图像识别和分类任务。
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D:从TensorFlow的Keras API中导入Dense和GlobalAveragePooling2D层。Dense层是全连接层,GlobalAveragePooling2D层用于在卷积层之后减少特征图的空间维度,同时保持特征的深度。
from tensorflow.keras.models import Model:从TensorFlow的Keras API中导入Model类,这是构建神经网络模型的基础类。使用Model类,您可以定义复杂的模型拓扑,包括多输入和多输出模型。

4.2. 加载类别名称

# 加载类别名称
with open('archive/DATASET/label/classes.txt', 'r') as f:
classes = f.read().splitlines()

:这段代码的作用是从一个名为classes.txt的文本文件中加载类别名称,并将它们存储在一个名为classes的列表中。这个列表通常用于在机器学习项目中表示可能的类别,尤其是在处理分类任务时。

4.3. 创建标签映射字典

# 创建标签映射字典
label_mapping = {
    '0': 'sad',
    '1': 'happy',
    '2': 'amazed',
    '3': 'anger'
}

:这段代码创建了一个名为label_mapping的字典,它将字符串格式的数字标签映射到相应的情感类别。在这个例子中,数字标签(作为字符串)被映射到四种不同的情感状态:sad(悲伤)、happy(快乐)、amazed(惊讶)和anger(愤怒)。

4.4. 加载图像数据和对应的标签

# 加载图像数据和对应的标签
image_folder = 'archive/DATASET/image'
label_folder = 'archive/DATASET/label'

X_train = []
y_train = []

:初始化两个空列表X_train和y_train,这两个列表通常用于存储图像数据的特征和对应的标签。这些列表在机器学习项目中非常重要,尤其是在准备训练数据集时。

4.5. 将指定文件夹中加载图像和对应的标签分别存储在列表中

for image_file in os.listdir(image_folder):
    image_path = os.path.join(image_folder, image_file)
    image = cv2.imread(image_path)
    if image is not None:
        X_train.append(cv2.resize(image, (224, 224)))  # Resize images to (224, 224)

        label_file = os.path.join(label_folder, image_file.replace('.jpg', '.txt'))
        with open(label_file, 'r') as f:
            label_index = f.readline().strip().split()[0]  # 只取第一个数字作为标签索引
            label_name = label_mapping[label_index]
            label = classes.index(label_name)
            y_train.append(label)

X_train = np.array(X_train)
y_train = np.array(y_train)

:这段代码的作用是从指定的文件夹中加载图像和对应的标签,并将它们分别存储在X_train和y_train列表中。然后,将这些列表转换为NumPy数组,以便用于训练机器学习模型,完成这些步骤后,X_train和y_train将包含用于训练机器学习模型的数据。这些数据可以用于训练图像分类器、卷积神经网络(CNN)或其他类型的模型。

4.6. 使用ResNet50模型进行迁移学习

# 使用ResNet50模型进行迁移学习
base_model = ResNet50(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D()(x)
output = Dense(len(classes), activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=output)

:加载预训练的ResNet50模型,但不包括顶部的全连接层。
添加一个全局平均池化层(GlobalAveragePooling2D)和一个全连接层(Dense),用于输出预测。
创建一个新的模型,将ResNet50的输出连接到新的全连接层。

4.7. 冻结预训练模型的权重

# 冻结预训练模型的权重
for layer in base_model.layers:
layer.trainable = False

:这段代码的作用是冻结预训练模型的权重,即在迁移学习中不更新模型的底层权重。这通常是为了保留预训练模型在大量数据上学习到的特征提取能力,同时允许我们在模型的顶部添加新的层来适应特定的任务,通过将预训练模型的底层权重冻结,可以确保这些权重不会被新的训练数据所影响,从而保留预训练模型在原始数据集上学到的特征提取能力。这种方法在迁移学习中非常有用,因为它允许您在保留底层特征提取器的同时,只训练模型的新部分,这通常用于微调(fine-tuning)预训练模型以适应新的任务。

4.8. 编译模型

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

:这段代码的作用是编译模型,指定训练过程中的优化器、损失函数和评估指标。编译模型是一个重要的步骤,它告诉模型如何训练和评估。

4.9. 训练模型

# 训练模型
model.fit(X_train, y_train, epochs=20, batch_size=32)

:通过调用fit方法,模型将使用提供的数据和参数来训练,并调整其权重以减少损失函数的值。训练完成后,模型将能够更好地预测或分类新的数据。
运行结果
在这里插入图片描述

五.LeNet-5

5.1. 导入资源包

import os
import cv2
import numpy as np
import tensorflow as tf


import tensorflow as tf:导入TensorFlow库,这是一个开源的机器学习框架,广泛用于构建和训练各种类型的深度学习模型。TensorFlow提供了丰富的API,用于定义、训练和评估模型。

5.2. 加载类别名称

# 加载类别名称
with open('archive/DATASET/label/classes.txt', 'r') as f:
classes = f.read().splitlines()

:这段代码的作用是从一个名为classes.txt的文本文件中加载类别名称,并将它们存储在一个名为classes的列表中。这个列表通常用于在机器学习项目中表示可能的类别,尤其是在处理分类任务时。

5.3. 创建标签映射字典

# 创建标签映射字典
label_mapping = {
    '0': 'sad',
    '1': 'happy',
    '2': 'amazed',
    '3': 'anger'
}

:这段代码创建了一个名为label_mapping的字典,它将字符串格式的数字标签映射到相应的情感类别。在这个例子中,数字标签(作为字符串)被映射到四种不同的情感状态:sad(悲伤)、happy(快乐)、amazed(惊讶)和anger(愤怒)。

5.4. 加载图像数据和对应的标签

# 加载图像数据和对应的标签
image_folder = 'archive/DATASET/image'
label_folder = 'archive/DATASET/label'

X_train = []
y_train = []

:初始化两个空列表X_train和y_train,这两个列表通常用于存储图像数据的特征和对应的标签。这些列表在机器学习项目中非常重要,尤其是在准备训练数据集时。

5.5. 将指定文件夹中加载图像和对应的标签分别存储在列表中

for image_file in os.listdir(image_folder):
    image_path = os.path.join(image_folder, image_file)
    image = cv2.imread(image_path)
    if image is not None:
        X_train.append(image)

        label_file = os.path.join(label_folder, image_file.replace('.jpg', '.txt'))
        with open(label_file, 'r') as f:
            label_index = f.readline().strip().split()[0]  # 只取第一个数字作为标签索引
            label_name = label_mapping[label_index]
            label = classes.index(label_name)
            y_train.append(label)

X_train = np.array(X_train)
y_train = np.array(y_train)

:这段代码的作用是从指定的文件夹中加载图像和对应的标签,并将它们分别存储在X_train和y_train列表中。然后,将这些列表转换为NumPy数组,以便用于训练机器学习模型,完成这些步骤后,X_train和y_train将包含用于训练机器学习模型的数据。这些数据可以用于训练图像分类器、卷积神经网络(CNN)或其他类型的模型。

5.5. 构建LeNet模型

# 构建LeNet模型
model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(6, (5, 5), activation='relu', input_shape=(X_train.shape[1:])),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Conv2D(16, (5, 5), activation='relu'),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(120, activation='relu'),
    tf.keras.layers.Dense(84, activation='relu'),
    tf.keras.layers.Dense(len(classes), activation='softmax')
])

:使用Keras的Sequential模型,按照LeNet的结构添加层。
模型包括卷积层(Conv2D)、最大池化层(MaxPooling2D)、全连接层(Dense)等。
输出层使用softmax激活函数,因为这是一个多分类问题。

5.6. 编译模型

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

:这段代码的作用是编译模型,指定训练过程中的优化器、损失函数和评估指标。编译模型是一个重要的步骤,它告诉模型如何训练和评估。

5.7. 训练模型

# 训练模型
model.fit(X_train, y_train, epochs=20, batch_size=32)

:通过调用fit方法,模型将使用提供的数据和参数来训练,并调整其权重以减少损失函数的值。训练完成后,模型将能够更好地预测或分类新的数据。
运行结果
在这里插入图片描述

六.总结

6.1. AlexNet

数量:大约800万个参数
大小:较小,大约为26MB
层数:8层

6.2. VGG-19

数量:大约1.4亿个参数。
大小:较大,大约为500MB。
层数:19层

6.3. VGG-16

数量:大约1.3亿个参数。
大小:较大,大约为450MB。
层数:16层。

6.4. ResNet

数量:从ResNet-18到ResNet-101,参数数量不等,从2000万到6000万个参数。
大小:根据层数不同,大小也有所不同
层数:从18层到101层。

6.5. LeNet-5

数量:大约6万个参数。
大小:较小,大约为2MB。
层数:5层

6.6. 区别

架构复杂度:AlexNet、VGG-19/16和ResNet都是更复杂的网络结构,有更多的层和参数,而LeNet-5则是一个相对简单的网络。
应用领域:LeNet-5主要用于手写数字识别,而其他网络则主要用于图像分类任务,如ImageNet。
性能:随着网络结构的复杂度增加,性能通常也会提高,但同时也会增加计算复杂度和训练时间。
创新:每个网络都在CNN领域引入了一些新的概念和技术,如ReLU、dropout、残差块等。

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 19:38:11       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 19:38:11       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 19:38:11       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 19:38:11       18 阅读

热门阅读

  1. springboot动态切换数据源

    2024-06-06 19:38:11       9 阅读
  2. make 是啥

    2024-06-06 19:38:11       8 阅读
  3. Android基础-工程目录结构说明

    2024-06-06 19:38:11       7 阅读
  4. 呼叫中心系统如何融入信创国产战略?

    2024-06-06 19:38:11       7 阅读
  5. 程序员高效工作(摸鱼)的 10 个方法

    2024-06-06 19:38:11       7 阅读
  6. nn.GRU和nn.GRUCell区别

    2024-06-06 19:38:11       9 阅读
  7. 【MySQL】探索 MySQL 的 GROUP_CONCAT 函数

    2024-06-06 19:38:11       11 阅读
  8. MySQL binlog三种模式

    2024-06-06 19:38:11       8 阅读