先容
基于卷积神经网络(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,表示多分类, 二分类用binary
- class_mode='binary')
- validation_generator = valid_datagen.flow_from_directory(
- validation_dir, # 文件夹路径
- target_size=(64, 64), # 指定图片缩放之后的大小
- batch_size=20,
- # 默认是categorical,表示多分类, 二分类用binary
- class_mode='binary')
复制代码- Found 2000 images belonging to 2 classes.
- Found 1000 images belonging to 2 classes.
复制代码 构建CNN网络
网络结构
- 利用tf.keras.models.Sequential()创建一个线性堆叠的模型,意味着每一层都有一个输入张量和一个输出张量,并且这些层是序次毗连的。
- 第一个Conv2D层利用32个3x3的滤波器举行卷积操作,padding='same’保证了输出特征图与输入图像巨细一致,激活函数接纳ReLU。
- 输入形状被指定为(64, 64, 3),表示输入图片尺寸为64x64像素,具有3个颜色通道(RGB)。
- 第二个Conv2D层继续应用32个3x3的滤波器,进一步提取特征。
- MaxPool2D层通过2x2窗口的最大值池化减少特征图的空间维度,从而降低计算复杂度并控制过拟合。
- 接下来增长了两个Conv2D层,每个都利用64个3x3的滤波器,这有助于捕捉更复杂的模式。
- 再次应用MaxPool2D以减小空间维度。
- 类似地,这一部分包含两个Conv2D层,这次是128个3x3的滤波器,用于捕捉更加抽象的特征。
- 末了一个MaxPool2D再次缩小特征图。
- Flatten()将三维的特征图转换成一维向量,以便于后续的全毗连层处理。
- 第一个Dense层有512个神经元,并利用ReLU作为激活函数,提供非线性的映射本领。
- 第二个Dense层有256个神经元,同样利用ReLU激活。
- 输出层:
末了一层是一个具有单个神经元的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: "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 * steps
- epochs=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,表示多分类, 二分类用binary
- class_mode='binary')
- validation_generator = valid_datagen.flow_from_directory(
- validation_dir, # 文件夹路径
- target_size=(64, 64), # 指定图片缩放之后的大小
- batch_size=20,
- # 默认是categorical,表示多分类, 二分类用binary
- class_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 * steps
- epochs=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 * steps
- epochs=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
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |