【深度学习进阶】基于CNN的猫狗图片分类项目

介绍

基于卷积神经网络(CNN)的猫狗图片分类项目是机器学习领域中的一种常见任务,它涉及图像处理和深度学习技术。以下是该项目的技术点和流程介绍:

技术点

  • 卷积神经网络 (CNN): CNN 是一种专门用于处理具有类似网格结构的数据的神经网络模型,比如时间序列数据或二维的图像数据。CNN 的核心组件包括卷积层、池化层和全连接层。
  • 卷积层: 卷积层使用滤波器(或称内核)在输入图像上滑动,并计算局部加权和来检测图像中的特征,如边缘、纹理等。
  • 激活函数: 激活函数(如ReLU, Sigmoid等)引入非线性因素,使得网络可以学习到更复杂的模式。
  • 池化层: 通常采用最大池化或平均池化操作,用于减少空间尺寸,降低参数数量,同时保留最重要的信息。
  • 全连接层: 在最后几层,CNN 会将多维的特征图展平为一维向量,并通过全连接层进行分类预测。
  • 损失函数与优化算法: 使用交叉熵作为损失函数,通过反向传播和梯度下降等优化算法来更新网络权重。
  • 正则化技术: 包括L2正则化、Dropout等,以防止过拟合。
  • 数据增强: 通过对原始图像进行旋转、翻转、缩放等变换生成更多的训练样本,增加模型的泛化能力。
  • 预训练模型: 可以利用已经在大规模数据集上训练好的模型(如VGG16, ResNet等),并在此基础上进行迁移学习。

流程

  • 数据收集: 收集大量标注好的猫和狗的图片作为训练集和测试集。
  • 数据预处理: 对图像进行标准化(如调整大小、归一化像素值)以及可能的数据增强。
  • 构建模型: 设计CNN架构,选择合适的层数、滤波器大小和其他超参数。
  • 训练模型: 使用训练数据集对CNN进行训练,调整模型参数以最小化损失函数。
  • 评估模型: 在验证集或独立的测试集上评估模型性能,检查准确率、召回率等指标。
  • 调优模型: 根据评估结果调整模型架构或超参数,重复训练和评估过程直至满意。
  • 部署模型: 将最终训练好的模型部署到生产环境中,实现对新图像的实时分类。
  • 持续改进: 随着时间推移,可能会有新的数据加入,或者发现模型表现不佳的地方,这时就需要不断迭代和改进模型。

猫狗图片分类

猫狗图片分类模型是一个使用机器学习技术来辨别猫和狗图片的模型。该模型可以通过对输入的图片进行分析和比对,从而自动识别出图片中的是猫还是狗。

猫狗图片分类模型通常是基于卷积神经网络(Convolutional Neural Network,CNN)构建的。CNN是一种专门用于图像识别和处理的神经网络模型,其特点是能够自动学习图像特征并进行分类。

训练猫狗图片分类模型需要大量的带有标签的猫和狗图片作为训练数据。模型通过训练数据不断调整神经网络中的权重和参数,以提高判断猫和狗的准确性。

一旦训练完成,猫狗图片分类模型就可以用于对新的未知图片进行分类。用户只需输入一张图片,模型会自动输出猫或狗的分类结果。

猫狗图片分类模型可以应用于各种场景,比如社交媒体上的猫狗图片分享、电子商务平台上的宠物产品推荐等。该模型的准确性和性能取决于训练数据的质量和模型的设计。因此,对于更高准确性的要求,需要更多的训练数据和更复杂的模型设计。

导包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
import os

加载数据

base_dir = './data/cats_and_dogs'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')# 训练集
train_cats_dir = os.path.join(train_dir, 'cats')
train_dogs_dir = os.path.join(train_dir, 'dogs')# 验证集
validation_cats_dir = os.path.join(validation_dir, 'cats')
validation_dogs_dir = os.path.join(validation_dir, 'dogs')

数据处理

from tensorflow.keras.preprocessing.image import ImageDataGenerator
# ImageDataGenerator 图片生成器, 会自动的帮我们从指定目录中读取图片. 
train_datagen = ImageDataGenerator(rescale=1./255)
valid_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir, # 文件夹路径target_size=(64, 64),  # 指定图片缩放之后的大小batch_size=20,# 默认是categorical,表示多分类, 二分类用binaryclass_mode='binary')validation_generator = valid_datagen.flow_from_directory(validation_dir, # 文件夹路径target_size=(64, 64),  # 指定图片缩放之后的大小batch_size=20,# 默认是categorical,表示多分类, 二分类用binaryclass_mode='binary')
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.

构建CNN网络

网络结构

  1. Sequential模型:
  • 使用tf.keras.models.Sequential()创建一个线性堆叠的模型,意味着每一层都有一个输入张量和一个输出张量,并且这些层是顺序连接的。
  1. 第一组卷积层与池化层:
  • 第一个Conv2D层使用32个3x3的滤波器进行卷积操作,padding='same’保证了输出特征图与输入图像大小一致,激活函数采用ReLU。
  • 输入形状被指定为(64, 64, 3),表示输入图片尺寸为64x64像素,具有3个颜色通道(RGB)。
  • 第二个Conv2D层继续应用32个3x3的滤波器,进一步提取特征。
  • MaxPool2D层通过2x2窗口的最大值池化减少特征图的空间维度,从而降低计算复杂度并控制过拟合。
  1. 第二组卷积层与池化层:
  • 接下来增加了两个Conv2D层,每个都使用64个3x3的滤波器,这有助于捕捉更复杂的模式。
  • 再次应用MaxPool2D以减小空间维度。
  1. 第三组卷积层与池化层:
  • 类似地,这一部分包含两个Conv2D层,这次是128个3x3的滤波器,用于捕捉更加抽象的特征。
  • 最后一个MaxPool2D再次缩小特征图。
  1. 全连接层(密集层):
  • Flatten()将三维的特征图转换成一维向量,以便于后续的全连接层处理。
  • 第一个Dense层有512个神经元,并使用ReLU作为激活函数,提供非线性的映射能力。
  • 第二个Dense层有256个神经元,同样使用ReLU激活。
  1. 输出层:
    最后一层是一个具有单个神经元的Dense层,其激活函数为sigmoid。这是因为这是一个二分类问题,sigmoid函数可以将输出压缩到[0, 1]区间内,表示预测属于某一类的概率。
# 搭建卷积神经网络
model = tf.keras.models.Sequential()
# 2次卷积一次池化, 3层, 2层全连接. 
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3,padding='same',activation='relu',input_shape=(64, 64, 3)))
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=2))model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=2))model.add(tf.keras.layers.Conv2D(filters=128, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.Conv2D(filters=128, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=2))model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dense(256, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_6 (Conv2D)            (None, 64, 64, 32)        896       
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 64, 64, 32)        9248      
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 32, 32, 32)        0         
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 32, 32, 64)        18496     
_________________________________________________________________
conv2d_9 (Conv2D)            (None, 32, 32, 64)        36928     
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 16, 16, 64)        0         
_________________________________________________________________
conv2d_10 (Conv2D)           (None, 16, 16, 128)       73856     
_________________________________________________________________
conv2d_11 (Conv2D)           (None, 16, 16, 128)       147584    
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 8, 8, 128)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 8192)              0         
_________________________________________________________________
dense (Dense)                (None, 512)               4194816   
_________________________________________________________________
dense_1 (Dense)              (None, 256)               131328    
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 257       
=================================================================
Total params: 4,613,409
Trainable params: 4,613,409
Non-trainable params: 0
_________________________________________________________________
model.compile(loss='binary_crossentropy',optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),metrics=['acc'])

模型训练

history = model.fit(train_generator, steps_per_epoch=100, # 2000 images : = batch_size * stepsepochs=20,validation_data=validation_generator,validation_steps=50, # 1000 images = batch_size * steps)
Epoch 1/20
100/100 [==============================] - 4s 30ms/step - loss: 0.6933 - acc: 0.5003 - val_loss: 0.6881 - val_acc: 0.5060
Epoch 2/20
100/100 [==============================] - 3s 28ms/step - loss: 0.6768 - acc: 0.5654 - val_loss: 0.6393 - val_acc: 0.6350
Epoch 3/20
100/100 [==============================] - 3s 27ms/step - loss: 0.6194 - acc: 0.6684 - val_loss: 0.6204 - val_acc: 0.6710
Epoch 4/20
100/100 [==============================] - 3s 28ms/step - loss: 0.5548 - acc: 0.7294 - val_loss: 0.6026 - val_acc: 0.6830
Epoch 5/20
100/100 [==============================] - 3s 27ms/step - loss: 0.5452 - acc: 0.7311 - val_loss: 0.5963 - val_acc: 0.6780
Epoch 6/20
100/100 [==============================] - 3s 27ms/step - loss: 0.5030 - acc: 0.7309 - val_loss: 0.5598 - val_acc: 0.7350
Epoch 7/20
100/100 [==============================] - 3s 28ms/step - loss: 0.4529 - acc: 0.7920 - val_loss: 0.5633 - val_acc: 0.7250
Epoch 8/20
100/100 [==============================] - 3s 27ms/step - loss: 0.4246 - acc: 0.8073 - val_loss: 0.5689 - val_acc: 0.7230
Epoch 9/20
100/100 [==============================] - 3s 27ms/step - loss: 0.4018 - acc: 0.8248 - val_loss: 0.5549 - val_acc: 0.7270
Epoch 10/20
100/100 [==============================] - 3s 27ms/step - loss: 0.3472 - acc: 0.8424 - val_loss: 0.5491 - val_acc: 0.7370
Epoch 11/20
100/100 [==============================] - 3s 28ms/step - loss: 0.3243 - acc: 0.8573 - val_loss: 0.5775 - val_acc: 0.7280
Epoch 12/20
100/100 [==============================] - 3s 28ms/step - loss: 0.2770 - acc: 0.8870 - val_loss: 0.6722 - val_acc: 0.7200
Epoch 13/20
100/100 [==============================] - 3s 27ms/step - loss: 0.2264 - acc: 0.9046 - val_loss: 0.6584 - val_acc: 0.7470
Epoch 14/20
100/100 [==============================] - 3s 27ms/step - loss: 0.1956 - acc: 0.9247 - val_loss: 0.6828 - val_acc: 0.7400
Epoch 15/20
100/100 [==============================] - 3s 27ms/step - loss: 0.1288 - acc: 0.9508 - val_loss: 0.7735 - val_acc: 0.7290
Epoch 16/20
100/100 [==============================] - 3s 28ms/step - loss: 0.1085 - acc: 0.9670 - val_loss: 0.7551 - val_acc: 0.7400
Epoch 17/20
100/100 [==============================] - 3s 27ms/step - loss: 0.1228 - acc: 0.9540 - val_loss: 0.9157 - val_acc: 0.7300
Epoch 18/20
100/100 [==============================] - 3s 27ms/step - loss: 0.0789 - acc: 0.9710 - val_loss: 0.9311 - val_acc: 0.7560
Epoch 19/20
100/100 [==============================] - 3s 28ms/step - loss: 0.0217 - acc: 0.9979 - val_loss: 0.9941 - val_acc: 0.7270
Epoch 20/20
100/100 [==============================] - 3s 27ms/step - loss: 0.0207 - acc: 0.9946 - val_loss: 1.0781 - val_acc: 0.7470

可视化

pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid()
plt.gca().set_ylim(0, 1)
plt.show()

在这里插入图片描述

数据增强

ImageDataGenerator 提供了一种简单的方法来应用各种图像变换,以扩充训练数据集,从而提高模型的泛化能力。对于猫狗分类这样的二分类任务,适当的图像变换可以帮助模型学习到更多不变性特征。

  • rescale=1./255: 将所有像素值从0-255缩放到0-1之间,这是为了标准化输入数据,使得梯度下降更稳定。
  • rotation_range=40: 随机旋转图片的角度范围(单位是度),这里设置为40度,意味着图片可能会被随机旋转最多正负40度。
  • width_shift_range=0.2 和 height_shift_range=0.2: 宽度和高度方向上的随机平移范围,这里的值表示相对于总宽度或高度的比例,即图像可能在水平或垂直方向上移动最多20%。
  • shear_range=0.2: 斜切变换的程度,可以模拟一些透视效果。
  • zoom_range=0.2: 随机缩放范围,这里的值也表示比例,即图像可能会被放大或缩小最多20%。
  • horizontal_flip=True: 随机水平翻转图像,这对于左右对称的对象(如猫和狗)特别有用。
  • fill_mode=‘nearest’: 当应用上述变换时,如果图像超出原始边界,则用最邻近填充模式填补新产生的空白区域。

创建数据生成器

flow_from_directory 方法可以从文件夹中读取图像,并自动根据子文件夹的名字给图像打上标签。它会生成批量的图像数据,可以直接用于模型训练。

  • train_dir 和 validation_dir: 分别指定了训练集和验证集所在的目录路径。每个目录应该包含两个子目录,一个用于“猫”的图片,另一个用于“狗”的图片。
  • target_size=(64, 64): 所有加载的图片将被调整大小到64x64像素。这应该与CNN模型输入层定义的input_shape相匹配。
  • batch_size=20: 每次迭代返回的图片数量。在这个例子中,每次会生成20张图片作为一批。
  • class_mode=‘binary’: 因为这是一个二分类问题,所以这里指定为二元分类模式。如果是多分类问题,则应设置为’categorical’。

通过这种方式,你可以确保训练过程中不断有新的、经过变换的图像提供给模型,有助于提升模型的表现,特别是当可用的原始图像数量有限时。同时,验证集仅进行了简单的归一化处理,而没有进行其他变换,以保证评估结果的真实性。

# 数据增强
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,fill_mode='nearest')
valid_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir, # 文件夹路径target_size=(64, 64),  # 指定图片缩放之后的大小batch_size=20,# 默认是categorical,表示多分类, 二分类用binaryclass_mode='binary')validation_generator = valid_datagen.flow_from_directory(validation_dir, # 文件夹路径target_size=(64, 64),  # 指定图片缩放之后的大小batch_size=20,# 默认是categorical,表示多分类, 二分类用binaryclass_mode='binary')
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.

再次训练

# 搭建卷积神经网络
model = tf.keras.models.Sequential()
# 2次卷积一次池化, 3层, 2层全连接. 
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3,padding='same',activation='relu',input_shape=(64, 64, 3)))
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=2))model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=2))model.add(tf.keras.layers.Conv2D(filters=128, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.Conv2D(filters=128, kernel_size=3,padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=2))model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dense(256, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy',optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),metrics=['acc'])history = model.fit(train_generator, steps_per_epoch=100, # 2000 images : = batch_size * stepsepochs=20,validation_data=validation_generator,validation_steps=50, # 1000 images = batch_size * steps)
Epoch 1/20
100/100 [==============================] - 5s 47ms/step - loss: 0.6934 - acc: 0.4989 - val_loss: 0.6905 - val_acc: 0.5040
Epoch 2/20
100/100 [==============================] - 5s 47ms/step - loss: 0.6930 - acc: 0.5108 - val_loss: 0.6845 - val_acc: 0.5280
Epoch 3/20
100/100 [==============================] - 4s 44ms/step - loss: 0.6867 - acc: 0.5560 - val_loss: 0.6446 - val_acc: 0.6200
Epoch 4/20
100/100 [==============================] - 4s 45ms/step - loss: 0.6524 - acc: 0.6232 - val_loss: 0.6780 - val_acc: 0.5750
Epoch 5/20
100/100 [==============================] - 4s 44ms/step - loss: 0.6736 - acc: 0.5856 - val_loss: 0.6043 - val_acc: 0.6770
Epoch 6/20
100/100 [==============================] - 4s 44ms/step - loss: 0.6133 - acc: 0.6503 - val_loss: 0.5926 - val_acc: 0.6860
Epoch 7/20
100/100 [==============================] - 4s 44ms/step - loss: 0.6189 - acc: 0.6653 - val_loss: 0.6047 - val_acc: 0.6670
Epoch 8/20
100/100 [==============================] - 5s 46ms/step - loss: 0.6108 - acc: 0.6662 - val_loss: 0.5849 - val_acc: 0.6740
Epoch 9/20
100/100 [==============================] - 5s 46ms/step - loss: 0.5685 - acc: 0.6985 - val_loss: 0.5654 - val_acc: 0.7070
Epoch 10/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5980 - acc: 0.6622 - val_loss: 0.5646 - val_acc: 0.6970
Epoch 11/20
100/100 [==============================] - 5s 46ms/step - loss: 0.5759 - acc: 0.6879 - val_loss: 0.5836 - val_acc: 0.6910
Epoch 12/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5805 - acc: 0.6865 - val_loss: 0.5640 - val_acc: 0.7060
Epoch 13/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5733 - acc: 0.6967 - val_loss: 0.5808 - val_acc: 0.6820
Epoch 14/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5779 - acc: 0.6857 - val_loss: 0.6307 - val_acc: 0.6680
Epoch 15/20
100/100 [==============================] - 4s 45ms/step - loss: 0.5498 - acc: 0.7178 - val_loss: 0.5564 - val_acc: 0.7050
Epoch 16/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5561 - acc: 0.7016 - val_loss: 0.6625 - val_acc: 0.6450
Epoch 17/20
100/100 [==============================] - 4s 45ms/step - loss: 0.5513 - acc: 0.7060 - val_loss: 0.5414 - val_acc: 0.7160
Epoch 18/20
100/100 [==============================] - 4s 45ms/step - loss: 0.5293 - acc: 0.7339 - val_loss: 0.5329 - val_acc: 0.7300
Epoch 19/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5344 - acc: 0.7272 - val_loss: 0.5141 - val_acc: 0.7410
Epoch 20/20
100/100 [==============================] - 5s 48ms/step - loss: 0.5257 - acc: 0.7146 - val_loss: 0.5461 - val_acc: 0.7240

调参

history = model.fit(train_generator, steps_per_epoch=100, # 2000 images : = batch_size * stepsepochs=20,validation_data=validation_generator,validation_steps=50, # 1000 images = batch_size * steps)
Epoch 1/20
100/100 [==============================] - 5s 47ms/step - loss: 0.5291 - acc: 0.7345 - val_loss: 0.5312 - val_acc: 0.7310
Epoch 2/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5126 - acc: 0.7400 - val_loss: 0.5147 - val_acc: 0.7490
Epoch 3/20
100/100 [==============================] - 4s 45ms/step - loss: 0.5192 - acc: 0.7385 - val_loss: 0.4972 - val_acc: 0.7420
Epoch 4/20
100/100 [==============================] - 5s 45ms/step - loss: 0.5124 - acc: 0.7465 - val_loss: 0.5264 - val_acc: 0.7170
Epoch 5/20
100/100 [==============================] - 4s 45ms/step - loss: 0.5141 - acc: 0.7485 - val_loss: 0.4969 - val_acc: 0.7450
Epoch 6/20
100/100 [==============================] - 5s 46ms/step - loss: 0.5048 - acc: 0.7400 - val_loss: 0.5044 - val_acc: 0.7460
Epoch 7/20
100/100 [==============================] - 5s 46ms/step - loss: 0.4905 - acc: 0.7610 - val_loss: 0.5057 - val_acc: 0.7400
Epoch 8/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4864 - acc: 0.7620 - val_loss: 0.4977 - val_acc: 0.7380
Epoch 9/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4972 - acc: 0.7585 - val_loss: 0.5027 - val_acc: 0.7530
Epoch 10/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4959 - acc: 0.7660 - val_loss: 0.4850 - val_acc: 0.7570
Epoch 11/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4816 - acc: 0.7655 - val_loss: 0.4954 - val_acc: 0.7440
Epoch 12/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4731 - acc: 0.7750 - val_loss: 0.5530 - val_acc: 0.7060
Epoch 13/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4826 - acc: 0.7625 - val_loss: 0.4668 - val_acc: 0.7700
Epoch 14/20
100/100 [==============================] - 4s 45ms/step - loss: 0.4625 - acc: 0.7865 - val_loss: 0.4852 - val_acc: 0.7580
Epoch 15/20
100/100 [==============================] - 4s 45ms/step - loss: 0.4678 - acc: 0.7830 - val_loss: 0.4709 - val_acc: 0.7690
Epoch 16/20
100/100 [==============================] - 5s 46ms/step - loss: 0.4590 - acc: 0.7835 - val_loss: 0.4554 - val_acc: 0.7730
Epoch 17/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4528 - acc: 0.7985 - val_loss: 0.4717 - val_acc: 0.7680
Epoch 18/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4524 - acc: 0.7755 - val_loss: 0.4518 - val_acc: 0.7750
Epoch 19/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4543 - acc: 0.7825 - val_loss: 0.4612 - val_acc: 0.7780
Epoch 20/20
100/100 [==============================] - 5s 45ms/step - loss: 0.4376 - acc: 0.8035 - val_loss: 0.5148 - val_acc: 0.7710

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501265.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【pytorch-lightning】架构一览

pytorch-lightning是基于pytorch的一个套壳项目,适配pytorch的版本同步更新速度很快。 它将训练的几个主要流程模块化,减少重复工作,同时让支持分布式训练,不同平台的训练迁移变得更加简单。 官网链接

AWS K8s 部署架构

Amazon Web Services(AWS)提供了一种简化的Kubernetes(K8s)部署架构,使得在云环境中管理和扩展容器化应用变得更加容易。这个架构的核心是AWS EKS(Elastic Kubernetes Service),它是…

【Vue】vue项目中命名规范(结合上一篇项目结构)

组件命名规范: 多单词命名: 避免使用单个单词命名组件,因为这可能会导致命名冲突。相反,应该使用描述性的多单词命名,如 UserProfile、SettingsPanel 等。 使用帕斯卡命名法: 组件名称应该以大写字母开头&…

node.js之---事件循环机制

事件循环机制 Node.js 事件循环机制(Event Loop)是其核心特性之一,它使得 Node.js 能够高效地处理大量并发的 I/O 操作。Node.js 基于 非阻塞 I/O,使用事件驱动的模型来实现异步编程。事件循环是 Node.js 实现异步编程的基础&…

信息科技伦理与道德1:绪论

1 问题描述 1.1 信息科技的进步给人类生活带来的是什么呢? 功能?智能?陪伴?乐趣?幸福? 基于GPT-3的对话Demo DeepFake 深伪技术:通过神经网络技术进行大样本学习,将个人的声音、面…

uniapp 自定义类微信支付键盘 (微信小程序)

效果图 代码: <view class"popups popupsB"><view class"appreciatePrice"><view class"appreciatePriceTitle">赞赏金额</view><view class"appreciatePriceInput flex ac">&#xffe5;<input typ…

电子电气架构 --- 中央处理器HPC及软件架构

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…

大模型 LangChain 开发框架:Runable 与 LCEL 初探

大模型 LangChain 开发框架&#xff1a;Runable 与 LCEL 初探 一、引言 在大模型开发领域&#xff0c;LangChain 作为一款强大的开发框架&#xff0c;为开发者提供了丰富的工具和功能。其中&#xff0c;Runnable 接口和 LangChain 表达式语言&#xff08;LCEL&#xff09;是构…

Flash Attention V3使用

Flash Attention V3 概述 Flash Attention 是一种针对 Transformer 模型中注意力机制的优化实现&#xff0c;旨在提高计算效率和内存利用率。随着大模型的普及&#xff0c;Flash Attention V3 在 H100 GPU 上实现了显著的性能提升&#xff0c;相比于前一版本&#xff0c;V3 通…

《Vue3实战教程》34:Vue3状态管理

如果您有疑问&#xff0c;请观看视频教程《Vue3实战教程》 状态管理​ 什么是状态管理&#xff1f;​ 理论上来说&#xff0c;每一个 Vue 组件实例都已经在“管理”它自己的响应式状态了。我们以一个简单的计数器组件为例&#xff1a; vue <script setup> import { r…

电脑找不到mfc110.dll文件要如何解决?Windows缺失mfc110.dll文件快速解决方法

一、mfc110.dll文件的重要性 mfc110.dll&#xff0c;全称Microsoft Foundation Class Library 110&#xff0c;是Microsoft Visual C Redistributable for Visual Studio 2012的一部分。这个动态链接库&#xff08;DLL&#xff09;文件对于支持基于MFC&#xff08;Microsoft F…

OSPF特殊区域(open shortest path first LSA Type7)

一、区域介绍 1、Stub区域 Stub区域是一种可选的配置属性。通常来说&#xff0c;Stub区域位于自治系统的边界&#xff0c;例如&#xff0c;只有一 个ABR的非骨干区域。在这些区域中&#xff0c;设备的路由表规模以及路由信息传递的数量都会大量减少。 kill 4 5类type 传递1 …

浏览器选中文字样式

效果 学习 Chrome: 支持 ::selection。Firefox: 支持 :-moz-selection 和 ::selection。Safari: 支持 ::selection。Internet Explorer: 支持 :-ms-selection。Microsoft Edge: 支持 ::-ms-selection 和 ::selection。 代码 <!DOCTYPE html> <html lang"en&qu…

Rabbitmq追问1

如果消费端代码异常&#xff0c;未手动确认&#xff0c;那么这个消息去哪里 2024-12-31 21:19:12 如果消费端代码发生异常&#xff0c;未手动确认&#xff08;ACK&#xff09;的情况下&#xff0c;消息的处理行为取决于消息队列的实现和配置&#xff0c;以下是基于 RabbitMQ …

Ansys Discovery 中的网格划分方法:探索模式

本篇博客文章将介绍 Ansys Discovery 中可用于在探索模式下进行分析的网格划分方法。我们将在下一篇博客中介绍 Refine 模式下的网格划分技术。 了解 Discovery Explore 模式下的网格划分 网格划分是将几何模型划分为小单元以模拟系统在不同条件下的行为的过程。这是通过创建…

Golang的并发编程实战经验

## Golang的并发编程实战经验 并发编程是什么 并发编程是指程序的多个部分可以同时执行&#xff0c;这样可以提高程序的性能和效率。在Golang中&#xff0c;并发编程是通过goroutine来实现的&#xff0c;goroutine是一种轻量级线程&#xff0c;可以在一个程序中同时运行成千上万…

vue2实现excel文件预览

一、插件 通过xlsx插件解析excel数据&#xff0c;对解析后的html组件进行渲染展示。 npm install xlsx 二、完整代码 <template><!-- excel文件预览 --><divelement-loading-text"拼命加载中"element-loading-spinner"el-icon-loading"…

低代码引擎插件开发:开启开发的便捷与创新之路

OneCode授权演示 一、低代码引擎与插件开发的概述 在当今快节奏的软件开发领域&#xff0c;低代码引擎正逐渐崭露头角。低代码引擎旨在让开发人员能够以最少的代码量创建功能丰富的应用程序&#xff0c;而其中的关键组成部分便是插件开发。低代码引擎通过提供可视化的开发环境…

Golang的代码质量分析工具

Golang的代码质量分析工具 一、介绍 作为一种高效、简洁、可靠的编程语言&#xff0c;被越来越多的开发者所喜爱和采用。而随着项目规模的增长和团队人员的扩大&#xff0c;代码质量的管理变得尤为重要。为了保障代码的可维护性、健壮性和可扩展性&#xff0c;我们需要借助代码…

JVM实战—9.线上FGC的几种案例

大纲 1.如何优化每秒十万QPS的社交APP的JVM性能(增加S区大小 优化内存碎片) 2.如何对垂直电商APP后台系统的FGC进行深度优化(定制JVM参数模版) 3.不合理设置JVM参数可能导致频繁FGC(优化反射的软引用被每次YGC回收) 4.线上系统每天数十次FGC导致频繁卡顿的优化(大对象问题…