import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow.keras import layers
from tensorflow import keras
train_ds, validation_ds, test_ds = tfds.load(
"tf_flowers",
split=["train[:80%]", "train[80%:90%]", "train[90%:100%]"],
as_supervised=True, # Include labels
)
print("Number of training samples: %d" % tf.data.experimental.cardinality(train_ds))
print(
"Number of validation samples: %d" % tf.data.experimental.cardinality(validation_ds)
)
print("Number of test samples: %d" % tf.data.experimental.cardinality(test_ds))
Number of training samples: 2936 Number of validation samples: 367 Number of test samples: 367
标准化数据
我们的原始图像有各种大小。另外,每个像素由 0 到 255 之间的 3 个整数值(RGB 色阶值)组成。这不太适合馈送神经网络。我们需要做下面两件事:
- 标准化为固定图像大小。我们选择 224x224。
- 在 -1 至 1 之间归一化像素值。我们将使用
Normalization
层作为模型本身的一部分来进行此操作。
一般而言,与采用已预处理数据的模型相反,开发以原始数据作为输入的模型是一种良好的做法。原因在于,如果模型需要预处理的数据,则每次导出模型以在其他地方(在网络浏览器、移动应用中)使用时,都需要重新实现完全相同的预处理流水线。这很快就会变得非常棘手。因此,在命中模型之前,我们应当尽可能少地进行预处理。
在这里,我们将在数据流水线中进行图像大小调整(因为深度神经网络只能处理连续的数据批次),并在创建模型时将其作为模型的一部分进行输入值缩放。
我们将图像的大小调整为 224x224:
size = (224, 224)
train_ds = train_ds.map(lambda x, y: (tf.image.resize(x, size), y))
validation_ds = validation_ds.map(lambda x, y: (tf.image.resize(x, size), y))
test_ds = test_ds.map(lambda x, y: (tf.image.resize(x, size), y))
batch_size = 64
train_ds = train_ds.cache().batch(batch_size).prefetch(buffer_size=10)
validation_ds = validation_ds.cache().batch(batch_size).prefetch(buffer_size=10)
test_ds = test_ds.cache().batch(batch_size).prefetch(buffer_size=10)
使用随机数据扩充
当您没有较大的图像数据集时,通过将随机但现实的转换(例如随机水平翻转或小幅随机旋转)应用于训练图像来人为引入样本多样性是一种良好的做法。这有助于使模型暴露于训练数据的不同方面,同时减慢过拟合的速度。
data_augmentation = keras.Sequential(
[layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),]
)
inputs = keras.Input(shape