目录

1、基本步骤

2.1 环境

2.2 数据说明

2.3 数据查看代码

3.创建数据集

3.1 数据集创建函数

3.2 创建数据集

4.数据可视化

5.模型训练

5.1 配置数据集

5.2 数据标准化

6.模型创建

6.1 创建模型

6.2 编译模型

6.3 总结模型

6.4 模型训练

6.5 训练结果可视化及分析

6.6 数据增强

​7.Dropout

7.1 重建模型

7.2 对新数据进行预测

8.最后 完整代码



1、基本步骤

(1) 检查和熟悉数据

(2) 构建输入管道

(3) 构建模型

(4) 训练模型

(5) 测试模型

(6) 改进模型并重复此过程

 2.数据下载

2.1 环境

需要使用到的库如下:

import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
import tensorflow as tffrom tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential

2.2 数据说明

下载flowers样本数据,该样本数据包含以下类别数据:

flower_photo/
  daisy/菊花/
  dandelion/蒲公英/
  roses/玫瑰/
  sunflowers/向日葵/
  tulips/郁金香/

数据下载源代码如下:

import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file('flower_photos', origin=dataset_url, untar=True)
data_dir = pathlib.Path(data_dir)

以上这段代码中函数的完整参数如下:

参考原文:https://blog.csdn.net/qq_39507748/article/details/104997553

tf.keras.utils.get_file(fname, origin, untar=False, md5_hash=None, file_hash=None,cache_subdir='datasets', hash_algorithm='auto', extract=False,archive_format='auto', cache_dir=None
)
参数说明--
fname:文件名,如果指定了绝对路径"/path/to/file.txt",则文件将会保存到该位置origin:文件的URLuntar:boolean,文件是否需要解压缩md5_hash:MD5哈希值,用于数据校验,支持sha256和md5哈希cache_subdir:用于缓存数据的文件夹,若指定绝对路径"/path/to/folder"则将存放在该路径下hash_algorithm:选择文件校验的哈希算法,可选项有'md5', 'sha256', 和'auto'.
默认'auto'自动检测使用的哈希算法extract:若为True则试图提取文件,例如tar或zip archive_format:试图提取的文件格式,可选为'auto', 'tar', 'zip',
和None. 'tar' 包括tar, tar.gz, tar.bz文件. 默认'auto'是['tar', 'zip']. None或空列表将返回没有匹配cache_dir:文件缓存后的地址,若为None,则默认存放在根目录的.keras文件夹中

运行结果如下:

pathlib.Path(data_dir)函数路径转换说明:

import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file('flower_photos', origin=dataset_url, untar=True)
print(data_dir)
print(type(data_dir))
data_dir = pathlib.Path(data_dir)
print(data_dir)
print(type(data_dir))
C:\Users\Administrator\.keras\datasets\flower_photos
<class 'str'>
C:\Users\Administrator\.keras\datasets\flower_photos
<class 'pathlib.WindowsPath'>

我们在路径下查看该数据:数据已经被解压出来。

daisy/菊花/                    数量:633
  dandelion/蒲公英/         数量:898
  roses/玫瑰/                    数量:641
  sunflowers/向日葵/        数量:699
  tulips/郁金香/                 数量:799

共计:3670

LICENSE.txt 中包含了图片作者和网址信息:

打开一些数据查看图片的大小,发现图片的像素大小,形状都不一样。部分图片如下:

2.3 数据查看代码

源代码:str类型的data_dir没有glob函数,因此上文中转化为“pathlib.WindowsPath”类型

image_count = len(list(data_dir.glob('*/*.jpg')))
print(image_count)
roses = list(data_dir.glob('roses/*'))
img0=PIL.Image.open(str(roses[0]))
plt.imshow(img0)
plt.show()

3.创建数据集

从上文中我们知道,以上图片数据集的大小尺寸都不一样,因此,我们需要创建一组具有相同大小尺寸的数据集,即将以上所有图片转化为像素大小相同的图片数据集。

3.1 数据集创建函数

使用的函数:

tf.keras.preprocessing.image_dataset_from_directory()

函数详解:完整参数


tf.keras.preprocessing.image_dataset_from_directory(directory,labels="inferred",label_mode="int",class_names=None,color_mode="rgb",batch_size=32,image_size=(256, 256),shuffle=True,seed=None,validation_split=None,subset=None,interpolation="bilinear",follow_links=False,
)

参数说明:

  • directory: 数据所在目录。如果标签是“inferred”(默认),则它应该包含子目录,每个目录包含一个类的图像。否则,将忽略目录结构。
  • labels: “inferred”(标签从目录结构生成),或者是整数标签的列表/元组,其大小与目录中找到的图像文件的数量相同。标签应根据图像文件路径的字母顺序排序(通过Python中的os.walk(directory)获得)。
  • label_mode: 'int':表示标签被编码成整数(例如:sparse_categorical_crossentropy loss)。‘categorical’指标签被编码为分类向量(例如:categorical_crossentropy loss)。‘binary’意味着标签(只能有2个)被编码为值为0或1的float32标量(例如:binary_crossentropy)。None(无标签)。
  • class_names: 仅当“labels”为“inferred”时有效。这是类名称的明确列表(必须与子目录的名称匹配)。用于控制类的顺序(否则使用字母数字顺序)。
  • color_mode: "grayscale"、"rgb"、"rgba"之一。默认值:"rgb"。图像将被转换为1、3或者4通道。
  • batch_size: 数据批次的大小。默认值:32
  • image_size: 从磁盘读取数据后将其重新调整大小。默认:(256,256)。由于管道处理的图像批次必须具有相同的大小,因此该参数必须提供。
  • shuffle: 是否打乱数据。默认值:True。如果设置为False,则按字母数字顺序对数据进行排序。
  • seed: 用于shuffle和转换的可选随机种子。
  • validation_split: 0和1之间的可选浮点数,可保留一部分数据用于验证。
  • subset: "training"或"validation"之一。仅在设置validation_split时使用。
  • interpolation: 字符串,当调整图像大小时使用的插值方法。默认为:bilinear。支持bilinearnearestbicubicarealanczos3lanczos5gaussianmitchellcubic.。
  • follow_links: 是否访问符号链接指向的子目录。默认:False。

 Returns

一个tf.data.Dataset对象。

  • 如果label_mode为None,它将生成float32张量,其shape(batch_size, image_size[0], image_size(1), num_channels),并对图像进行编码(有关num_channels的规则,参见下文)。
  • 否则,将生成一个元组(images, labels),其中图像的shape(batch_size, image_size[0], image_size(1), num_channels),并且labels遵循下面描述的格式。

关于labels格式规则:

  • 如果label_mode 是 int, labels是形状为(batch_size, )int32张量
  • 如果label_mode 是 binarylabels是形状为(batch_size, 1)的1和0的float32张量。
  • 如果label_mode 是 categoriallabels是形状为(batch_size, num_classes)float32张量,表示类索引的one-hot编码。

有关生成图像中通道数量的规则:

如果color_mode 是 grayscale, 图像张量有1个通道。

如果color_mode 是 rgb, 图像张量有3个通道。

如果color_mode 是 rgba, 图像张量有4个通道。

参考:https://blog.csdn.net/qq_40108803/article/details/110408217

3.2 创建数据集

参数设置如下:

batch_size = 32
img_height = 180
img_width = 180

在开发模型时使用验证分割是一个很好的实践。我们使用80%的图像进行训练,20%进行验证。

train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="training",seed=123,image_size=(img_height, img_width),batch_size=batch_size)val_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="validation",seed=123,image_size=(img_height, img_width),batch_size=batch_size)
Found 3670 files belonging to 5 classes.
Using 2936 files for training.
2021-07-01 22:37:26.205600: 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:  AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Found 3670 files belonging to 5 classes.
Using 734 files for validation.
['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']

4.数据可视化

接下来我们对数据进行可视化:

plt.figure(figsize=(10, 10))
for images, labels in train_ds.take(1):for i in range(9):ax = plt.subplot(3, 3, i + 1)plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[labels[i]])plt.axis("off")
plt.show()

显示结果如下:

plt.figure()

figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)

num:图像编号或名称,数字为编号 ,字符串为名称
figsize:指定figure的宽和高,单位为英寸;
dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80      1英寸等于2.5cm,A4纸是 21*30cm的纸张 
facecolor:背景颜色
edgecolor:边框颜色
frameon:是否显示边框
原文链接:https://blog.csdn.net/m0_37362454/article/details/81511427

tranin_ds.take()

tranin_ds是一个dataset对象,即dataset.take()方法

dataset.take(1)取第一个元素构建dataset(是第一个元素,不是随机的一个)

每组中应该有30张图,最多可以显示30张图,可以设置为3行,10列都显示出来

plt.figure(figsize=(10, 10))
for images, labels in train_ds.take(1):for i in range(30):ax = plt.subplot(3, 10, i + 1)plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[labels[i]])plt.axis("off")
plt.show()

大于30就超限了。

plt.subplot()

plt.subplot(nrows, ncols, index, **kwargs)

第一个参数:*args (官网文档描述)
Either a 3-digit integer or three separate integers describing the position of the subplot. If the three integers are nrows, ncols, and index in order, the subplot will take the index position on a grid with nrows rows and ncols columns. index starts at 1 in the upper left corner and increases to the right.
可以使用三个整数,或者三个独立的整数来描述子图的位置信息。如果三个整数是行数、列数和索引值,子图将分布在行列的索引位置上。索引从1开始,从右上角增加到右下角。
pos is a three digit integer, where the first digit is the number of rows, the second the number of columns, and the third the index of the subplot. i.e. fig.add_subplot(235) is the same as fig.add_subplot(2, 3, 5). Note that all integers must be less than 10 for this form to work.
位置是由三个整型数值构成,第一个代表行数,第二个代表列数,第三个代表索引位置。举个列子:plt.subplot(2, 3, 5) 和 plt.subplot(235) 是一样一样的。需要注意的是所有的数字不能超过10。

第二个参数:projection : {None, ‘aitoff’, ‘hammer’, ‘lambert’, ‘mollweide’, ‘polar’, ‘rectilinear’, str}, optional
The projection type of the subplot (Axes). str is the name of a costum projection, see projections. The default None results in a ‘rectilinear’ projection.
可选参数:可以选择子图的类型,比如选择polar,就是一个极点图。默认是none就是一个线形图。

第三个参数:polar : boolean, optional
If True, equivalent to projection=‘polar’. 如果选择true,就是一个极点图,上一个参数也能实现该功能。
原文链接:https://blog.csdn.net/missyougoon/article/details/90543210

 plt.axis()

  1. plt.axis(‘square’)
    作图为正方形,并且x,y轴范围相同,即y m a x − y m i n = x m a x − x m i n y_{max}-y_{min} = x_{max}-x_{min}y

  2. plt.axis(‘equal’)      x,y轴刻度等长

  3. plt.axis(‘off’)   关闭坐标轴

  4. plt.axis([a, b, c, d])
    设置x轴的范围为[a, b],y轴的范围为[c, d]

5.模型训练

5.1 配置数据集

我们通过将这些数据集传递给模型来训练模型,我们也可以手动遍历数据集和检索一批图像。

Dataset.cache()将图像在第一个epoch期间从磁盘上加载后保存在内存中。这将确保数据集在训练模型时不会成为瓶颈。如果数据集太大,无法装入内存,也可以使用此方法创建一个性能磁盘缓存。

dataset.prefetch() 在训练过程中重叠数据预处理和模型执行。这里自动翻译的。

data performance guide.

AUTOTUNE = tf.data.AUTOTUNEtrain_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

待补充详细说明……

5.2 数据标准化

normalization_layer = layers.experimental.preprocessing.Rescaling(1./255)
normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(normalized_ds))
first_image = image_batch[0]
# Notice the pixels values are now in `[0,1]`.
print(np.min(first_image), np.max(first_image))
0.0 1.0

将数据处理为[0,1]之间。

补充详细说明……

6.模型创建

6.1 创建模型

该模型由三个卷积块组成,每个卷积块中有一个最大池层。有一个完全连接的层,上面有128个单元,由一个relu激活功能激活。这个模型还没有进行高精度的调整,目标是展示一种标准的方法。

num_classes = 5model = Sequential([layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)),layers.Conv2D(16, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(32, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(64, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Flatten(),layers.Dense(128, activation='relu'),layers.Dense(num_classes)
])

补充说明……

6.2 编译模型

model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])

模型说明……

6.3 总结模型

model.summary()

以上三小结输出结果:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
rescaling_1 (Rescaling)      (None, 180, 180, 3)       0
_________________________________________________________________
conv2d (Conv2D)              (None, 180, 180, 16)      448
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 90, 90, 16)        0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 90, 90, 32)        4640
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 45, 45, 32)        0
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 45, 45, 64)        18496
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 22, 22, 64)        0
_________________________________________________________________
flatten (Flatten)            (None, 30976)             0
_________________________________________________________________
dense (Dense)                (None, 128)               3965056
_________________________________________________________________
dense_1 (Dense)              (None, 5)                 645
=================================================================
Total params: 3,989,285
Trainable params: 3,989,285
Non-trainable params: 0
_________________________________________________________________

6.4 模型训练

epochs=10
history = model.fit(train_ds,validation_data=val_ds,epochs=epochs
)

函数说明……

6.5 训练结果可视化及分析

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']loss = history.history['loss']
val_loss = history.history['val_loss']epochs_range = range(epochs)plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
_________________________________________________________________
Epoch 1/10
92/92 [==============================] - 61s 656ms/step - loss: 1.3780 - accuracy: 0.4118 - val_loss: 1.0661 - val_accuracy: 0.5722
Epoch 2/10
92/92 [==============================] - 58s 633ms/step - loss: 1.0134 - accuracy: 0.5988 - val_loss: 1.0202 - val_accuracy: 0.5858
Epoch 3/10
92/92 [==============================] - 67s 731ms/step - loss: 0.8491 - accuracy: 0.6730 - val_loss: 1.0023 - val_accuracy: 0.6076
Epoch 4/10
92/92 [==============================] - 59s 641ms/step - loss: 0.6457 - accuracy: 0.7582 - val_loss: 0.9318 - val_accuracy: 0.6458
Epoch 5/10
92/92 [==============================] - 62s 676ms/step - loss: 0.4351 - accuracy: 0.8464 - val_loss: 1.0414 - val_accuracy: 0.6362
Epoch 6/10
92/92 [==============================] - 76s 832ms/step - loss: 0.2478 - accuracy: 0.9200 - val_loss: 1.3063 - val_accuracy: 0.6199
Epoch 7/10
92/92 [==============================] - 66s 716ms/step - loss: 0.1642 - accuracy: 0.9496 - val_loss: 1.5034 - val_accuracy: 0.6403
Epoch 8/10
92/92 [==============================] - 65s 707ms/step - loss: 0.0777 - accuracy: 0.9799 - val_loss: 1.6238 - val_accuracy: 0.6403
Epoch 9/10
92/92 [==============================] - 66s 714ms/step - loss: 0.0382 - accuracy: 0.9915 - val_loss: 1.7345 - val_accuracy: 0.6362
Epoch 10/10
92/92 [==============================] - 71s 771ms/step - loss: 0.0608 - accuracy: 0.9843 - val_loss: 1.8870 - val_accuracy: 0.6362

从图中可以看到,训练精度和验证精度相差很大,模型在验证集上仅实现了约60%的准确性。

让我们看看哪里出了问题,并尝试提高模型的整体性能。

在上面的图中,训练精度随时间线性增加,而验证精度在训练过程中停滞在60%左右。此外,训练和验证准确性之间的差异是明显的——这是过度拟合的迹象。

当训练样本数量很少时,模型有时会从训练样本的噪声或不需要的细节中学习,这在一定程度上会对模型在新样本上的性能产生负面影响。这种现象被称为过拟合。这意味着模型在新的数据集中泛化时会有困难。

在训练过程中有多种方法可以对抗过拟合。可以使用数据增强并将Dropout添加到我们的模型中。

6.6 数据增强

data_augmentation = keras.Sequential([layers.experimental.preprocessing.RandomFlip("horizontal", input_shape=(img_height, img_width,3)),layers.experimental.preprocessing.RandomRotation(0.1),layers.experimental.preprocessing.RandomZoom(0.1),]
)

数据增强主要用来防止过拟合,用于dataset较小的时候。
之前对神经网络有过了解的人都知道,虽然一个两层网络在理论上可以拟合所有的分布,但是并不容易学习得到。因此在实际中,我们通常会增加神经网络的深度和广度,从而让神经网络的学习能力增强,便于拟合训练数据的分布情况。在卷积神经网络中,有人实验得到,深度比广度更重要。

然而随着神经网络的加深,需要学习的参数也会随之增加,这样就会更容易导致过拟合,当数据集较小的时候,过多的参数会拟合数据集的所有特点,而非数据之间的共性。那什么是过拟合呢,之前的博客有提到,指的就是神经网络可以高度拟合训练数据的分布情况,但是对于测试数据来说准确率很低,缺乏泛化能力。

因此在这种情况下,为了防止过拟合现象,数据增强应运而生。当然除了数据增强,还有正则项/dropout等方式可以防止过拟合。那接下来讨论下常见的数据增强方法。

1)随机旋转
随机旋转一般情况下是对输入图像随机旋转[0,360)
2)随机裁剪
随机裁剪是对输入图像随机切割掉一部分
3)色彩抖动
色彩抖动指的是在颜色空间如RGB中,每个通道随机抖动一定的程度。在实际的使用中,该方法不常用,在很多场景下反而会使实验结果变差
4)高斯噪声
是指在图像中随机加入少量的噪声。该方法对防止过拟合比较有效,这会让神经网络不能拟合输入图像的所有特征
5)水平翻转
6)竖直翻转

随机裁剪/随机旋转/水平反转/竖直反转都是为了增加图像的多样性。并且在某些算法中,如faster RCNN中,自带了图像的翻转。
原文链接:https://blog.csdn.net/lanmengyiyu/article/details/79658545

增强数据可视化:

plt.figure(figsize=(10, 10))
for images, _ in train_ds.take(1):for i in range(9):augmented_images = data_augmentation(images)ax = plt.subplot(3, 3, i + 1)plt.imshow(augmented_images[0].numpy().astype("uint8"))plt.axis("off")

7.Dropout

7.1 重建模型

在机器学习的模型中,如果模型的参数太多,而训练样本又太少,训练出来的模型很容易产生过拟合的现象。在训练神经网络的时候经常会遇到过拟合的问题,过拟合具体表现在:模型在训练数据上损失函数较小,预测准确率较高;但是在测试数据上损失函数比较大,预测准确率较低。

过拟合是很多机器学习的通病。如果模型过拟合,那么得到的模型几乎不能用。为了解决过拟合问题,一般会采用模型集成的方法,即训练多个模型进行组合。此时,训练模型费时就成为一个很大的问题,不仅训练多个模型费时,测试多个模型也是很费时。

综上所述,训练深度神经网络的时候,总是会遇到两大缺点:

(1)容易过拟合

(2)费时

Dropout可以比较有效的缓解过拟合的发生,在一定程度上达到正则化的效果。

原理参考:深度学习中Dropout原理解析

model = Sequential([data_augmentation,layers.experimental.preprocessing.Rescaling(1./255),layers.Conv2D(16, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(32, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(64, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Dropout(0.2),layers.Flatten(),layers.Dense(128, activation='relu'),layers.Dense(num_classes)
])
model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])model.summary()epochs=15
history = model.fit(train_ds,validation_data=val_ds,epochs=epochs
)

数据可视化:

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']loss = history.history['loss']
val_loss = history.history['val_loss']epochs_range = range(epochs)plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

7.2 对新数据进行预测

sunflower_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/592px-Red_sunflower.jpg"
sunflower_path = tf.keras.utils.get_file('Red_sunflower', origin=sunflower_url)img = keras.preprocessing.image.load_img(sunflower_path, target_size=(img_height, img_width)
)
img_array = keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batchpredictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])print("This image most likely belongs to {} with a {:.2f} percent confidence.".format(class_names[np.argmax(score)], 100 * np.max(score))
)

重新运行代码,疯狂计算中……

_________________________________________________________________
Epoch 1/15
92/92 [==============================] - 73s 791ms/step - loss: 1.3521 - accuracy: 0.4019 - val_loss: 1.0953 - val_accuracy: 0.5559
Epoch 2/15
92/92 [==============================] - 69s 748ms/step - loss: 1.0640 - accuracy: 0.5719 - val_loss: 0.9975 - val_accuracy: 0.6063
Epoch 3/15
92/92 [==============================] - 82s 896ms/step - loss: 1.0002 - accuracy: 0.6104 - val_loss: 0.9629 - val_accuracy: 0.6322
Epoch 4/15
92/92 [==============================] - 87s 945ms/step - loss: 0.9113 - accuracy: 0.6434 - val_loss: 0.9085 - val_accuracy: 0.6444
Epoch 5/15
92/92 [==============================] - 86s 929ms/step - loss: 0.8446 - accuracy: 0.6737 - val_loss: 0.9270 - val_accuracy: 0.6444
Epoch 6/15
92/92 [==============================] - 77s 833ms/step - loss: 0.8044 - accuracy: 0.6860 - val_loss: 0.8783 - val_accuracy: 0.6608
Epoch 7/15
92/92 [==============================] - 68s 738ms/step - loss: 0.7580 - accuracy: 0.7040 - val_loss: 0.7989 - val_accuracy: 0.6839
Epoch 8/15
92/92 [==============================] - 67s 734ms/step - loss: 0.7278 - accuracy: 0.7207 - val_loss: 0.8172 - val_accuracy: 0.6894
Epoch 9/15
92/92 [==============================] - 68s 743ms/step - loss: 0.7242 - accuracy: 0.7197 - val_loss: 0.7696 - val_accuracy: 0.6894
Epoch 10/15
92/92 [==============================] - 74s 808ms/step - loss: 0.6596 - accuracy: 0.7476 - val_loss: 0.8035 - val_accuracy: 0.6839
Epoch 11/15
92/92 [==============================] - 73s 799ms/step - loss: 0.6510 - accuracy: 0.7497 - val_loss: 0.7912 - val_accuracy: 0.7016
Epoch 12/15
92/92 [==============================] - 78s 852ms/step - loss: 0.6036 - accuracy: 0.7681 - val_loss: 0.7417 - val_accuracy: 0.7248
Epoch 13/15
92/92 [==============================] - 75s 818ms/step - loss: 0.5839 - accuracy: 0.7759 - val_loss: 0.6985 - val_accuracy: 0.7221
Epoch 14/15
92/92 [==============================] - 68s 736ms/step - loss: 0.5630 - accuracy: 0.7878 - val_loss: 0.8848 - val_accuracy: 0.6839
Epoch 15/15
92/92 [==============================] - 87s 950ms/step - loss: 0.5393 - accuracy: 0.7963 - val_loss: 0.7374 - val_accuracy: 0.7098
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/592px-Red_sunflower.jpg
122880/117948 [===============================] - 1s 7us/step
This image most likely belongs to sunflowers with a 97.72 percent confidence.

8.最后 完整代码

import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
import tensorflow as tffrom tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential"""flower_photo/daisy/dandelion/roses/sunflowers/tulips/"""
import pathlibdataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file('flower_photos', origin=dataset_url, untar=True)
print(data_dir)
print(type(data_dir))
data_dir = pathlib.Path(data_dir)
print(data_dir)
print(type(data_dir))image_count = len(list(data_dir.glob('*/*.jpg')))
print(image_count)
roses = list(data_dir.glob('roses/*'))
img0=PIL.Image.open(str(roses[0]))
plt.imshow(img0)
plt.show()batch_size = 32
img_height = 180
img_width = 180#It's good practice to use a validation split when developing your model.
# Let's use 80% of the images for training, and 20% for validation.
train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="training",seed=123,image_size=(img_height, img_width),batch_size=batch_size)val_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="validation",seed=123,image_size=(img_height, img_width),batch_size=batch_size)class_names = train_ds.class_names
print(class_names)#图片可视化
plt.figure(figsize=(10, 10))
for images, labels in train_ds.take(1):for i in range(30):ax = plt.subplot(3, 10, i + 1)plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[labels[i]])plt.axis("off")
plt.show()for image_batch, labels_batch in train_ds:print(image_batch.shape)print(labels_batch.shape)breakAUTOTUNE = tf.data.AUTOTUNEtrain_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)normalization_layer = layers.experimental.preprocessing.Rescaling(1./255)
normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(normalized_ds))
first_image = image_batch[0]
# Notice the pixels values are now in `[0,1]`.
print(np.min(first_image), np.max(first_image))"""
num_classes = 5model = Sequential([layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)),layers.Conv2D(16, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(32, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(64, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Flatten(),layers.Dense(128, activation='relu'),layers.Dense(num_classes)
])
"""
data_augmentation = keras.Sequential([layers.experimental.preprocessing.RandomFlip("horizontal",input_shape=(img_height,img_width,3)),layers.experimental.preprocessing.RandomRotation(0.1),layers.experimental.preprocessing.RandomZoom(0.1),]
)
plt.figure(figsize=(10, 10))
for images, _ in train_ds.take(1):for i in range(9):augmented_images = data_augmentation(images)ax = plt.subplot(3, 3, i + 1)plt.imshow(augmented_images[0].numpy().astype("uint8"))plt.axis("off")num_classes = 5
model = Sequential([data_augmentation,layers.experimental.preprocessing.Rescaling(1./255),layers.Conv2D(16, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(32, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Conv2D(64, 3, padding='same', activation='relu'),layers.MaxPooling2D(),layers.Dropout(0.2),layers.Flatten(),layers.Dense(128, activation='relu'),layers.Dense(num_classes)
])model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])model.summary()epochs=15
history = model.fit(train_ds,validation_data=val_ds,epochs=epochs
)"""
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']loss = history.history['loss']
val_loss = history.history['val_loss']epochs_range = range(epochs)plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
"""
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']loss = history.history['loss']
val_loss = history.history['val_loss']epochs_range = range(epochs)plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()sunflower_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/592px-Red_sunflower.jpg"
sunflower_path = tf.keras.utils.get_file('Red_sunflower', origin=sunflower_url)img = keras.preprocessing.image.load_img(sunflower_path, target_size=(img_height, img_width)
)
img_array = keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batchpredictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])print("This image most likely belongs to {} with a {:.2f} percent confidence.".format(class_names[np.argmax(score)], 100 * np.max(score))
)

Tensorflow2 图像分类-Flowers数据及分类代码详解相关推荐

  1. Tensorflow2 图像分类-Flowers数据深度学习模型保存、读取、参数查看和图像预测

    目录 1.原文完整代码 1.1 模型运行参数总结 1.2模型训练效果 ​编辑2.模型的保存 3.读取模型model 4.使用模型进行图片预测 5.补充 如何查看保存模型参数 5.1 model_wei ...

  2. Android实战:CoolWeather酷欧天气(加强版数据接口)代码详解(上)

    -----------------------------------该文章代码已停更,可参考浩比天气(更新于2019/6/25)----------------------------------- ...

  3. 电商产品评论数据情感分析代码详解

    本章代码建议在linux下面运行,windows下安装gensim会比较麻烦. 我是在python3.5.2的pycharm下运行的 下面代码的意思是从评论数据中抽取品牌是美的的数据(15-1) #- ...

  4. PHP JSON格式数据交互实例代码详解_php技巧_脚本之家

    http://www.jb51.net/article/26007.htm 此前我写了不少在PHP网站开发中应用XML进行数据交互的实例,这两天通过PHP解析JSON并进行交互的实例学习和了解了JSO ...

  5. python处理表格数据教程_代码详解:使用Python从不同表格中提取数据

    常用的表格数据存储文件格式--CSV,Microsoft Excel,Google Excel . Python通常称为粘合语言.这个名称归因于人们逐渐开发出的大量接口库和特征,也得益于广泛的使用和良 ...

  6. pytorch 搭建cnn resnet50网络进行图片分类 代码详解

    数据样式: 直接上代码: import pathlib import tensorflow as tf import matplotlib.pyplot as plt import os, PIL, ...

  7. [Pytorch系列-61]:循环神经网络 - 中文新闻文本分类详解-3-CNN网络训练与评估代码详解

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

  8. 数学建模_随机森林分类模型详解Python代码

    数学建模_随机森林分类模型详解Python代码 随机森林需要调整的参数有: (1) 决策树的个数 (2) 特征属性的个数 (3) 递归次数(即决策树的深度)''' from numpy import ...

  9. java编程数据溢出问题_Java数据溢出代码详解

    Java数据溢出代码详解 发布时间:2020-10-05 15:08:31 来源:脚本之家 阅读:103 作者:Pony小马 java是一门相对安全的语言,那么数据溢出时它是如何处理的呢? 看一段代码 ...

最新文章

  1. Android runOnUiThread() 方法的使用
  2. Linux(三) 运行级别
  3. java 注释 depredated_depredated是什么意思_depredated怎么读_depredated翻译_用法_发音_词组_同反义词-新东方在线英语词典...
  4. oracle连接操作符,Oracle操作符,函数
  5. 路由器再度躺枪:主流厂商设备中被发现后门
  6. ShardingSphere JDBC 语句执行初探
  7. 显示所有大写字母python_python 输出所有大小写字母的方法
  8. 连文件搜索都不会用,也不自己反省一下?
  9. Java使用文本编写源代码
  10. ATX电源接口定义及颜色定义 (转载)
  11. 社会学概论(本专)【2】
  12. 看呐!一群方言在舌尖跳舞
  13. Ubuntu 20.04系统安装及初始配置
  14. JSON解析基础使用知识-Java
  15. tcping检查服务器端口是否开放
  16. CF - 794B. Cutting Carrot - 数学
  17. 数据链路层的有那三个基本问题?为什么都必须加以解决?
  18. SUMO利用转弯率构建车流rou文件
  19. 基于javaSpringboot的装修验收管理系统设计和实现
  20. 用python画太阳花原理_Python——教你画朵太阳花

热门文章

  1. PXC 避免加入集群时发生SST
  2. 黑苹果核心显卡clover驱动教程
  3. Ant Design of Vue +TS 表单动态增加数据验证卧坑姿势
  4. android 环信客服修改自己的头像
  5. matlab中unifrnd函数用法,概率和统计的MATLAB指令
  6. 用事实说话,我们的数据库应选择RAID几?
  7. 三星性能测试软件,三星T7 性能测试
  8. AKM项目轶事之与高中同学徐挺会见
  9. nabc模型_团队开发-极速蜗牛-NABC模型
  10. 一种改进的天鹰优化算法和非洲秃鹫混合优化算法(Matlab代码实现)