TensorFlow-similarity 学习笔记9
2021SC@SDUSC
在上一篇博客,已经实现了各种数据加载技术。 了解了如何将图像、文本、CSV 文件和 NumPy 数组加载到Keras 工作区中。
现在,为了使模型能够正确使用数据,必须将其转换为可理解的格式,然后可以由深度学习算法进行解释。 为此,必须对数据进行预处理。
导入 Keras
首先将 keras 库导入工作区。
from tensorflow import keras
现在了解如何预处理各种数据。 每个部分都有任务及其相关的解决方案。 在跳到解决方案之前,尝试解决给定的任务; 这样,就能够理解所涉及的预处理技术。
预处理文本数据
将文本转换为数字数据——即,矢量化文本,使每个单词都映射到一个数字。
第一件事。 从可用数据源获取并下载 IMDb 数据(或任何文本数据集)。
import os
from tensorflow import keras
url = "https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz"
dataset = keras.utils.get_file(
"aclImdb_v1.tar.gz", url, untar=True, cache_dir="", cache_subdir=""
)
dataset_dir = os.path.join(os.path.dirname(dataset), "aclImdb")
使用方法 text_dataset_from_directory() 将给定的文本目录转换为 tf.data.Dataset。
batch_size = 32
seed = 42
raw_train_ds = keras.preprocessing.text_dataset_from_directory(
os.path.join(dataset_dir, "train"),
batch_size=batch_size,
validation_split=0.2,
subset="training",
seed=seed,
)
运行此代码时,将获得以下输出:
Found 75000 files belonging to 3 classes.
Using 60000 files for training.
您可以根据要获取的数据集设置超参数。
要矢量化文本,使用 TextVectorization() 方法。
from keras.layers.experimental.preprocessing import TextVectorization
max_features = 10000
sequence_length = 250
vectorize_layer = TextVectorization(
max_tokens=max_features,
output_mode='int',
output_sequence_length=sequence_length)
max_features 是假设构成语料库的单词总数的暂定计数,sequence_length 指定每个输出序列的长度(这是填充发生的地方)。
注意:在 TextVectorization 中将 output_mode 设置为 binary 输出单热编码向量。
在语料库上应用vectorize_layer,
Make a text-only dataset (without labels), then call adapt
train_text = raw_train_ds.map(lambda x, y: x)
vectorize_layer.adapt(train_text)
并输出得到的数值表示。
import tensorflow as tf
def vectorize_text(text, label):
text = tf.expand_dims(text, -1)
return vectorize_layer(text), label
text_batch, label_batch = next(iter(raw_train_ds))
first_review, first_label = text_batch[0], label_batch[0]
print("Review", first_review)
print("Label", raw_train_ds.class_names[first_label])
print("Vectorized review", vectorize_text(first_review, first_label))
在运行此代码时,将获得文本及其编码表示。
Review tf.Tensor(b'As I\'ve said before I\'m a cheapskate and I\'ll pretty much watch anything I rent but even I couldn\'t endure this piece of junk.I\'ve seen some terrible zombie films ...', shape=(), dtype=string)
Label unsup
Vectorized review (<tf.Tensor: shape=(1, 250), dtype=int64, numpy=
array([[ 15, 199, 292, 163, 144, 4, 1, 3, 543, 181, 72, 104, 235, 11, 820, 19, 56, 11, 397, 4322, 10, 435, 5, 1, 112, 47, 381, 1038, 91, 8, 59, 150, 5, 148, 191, 91, 3, 10, 14, 29, 5, 2, 243, 5, 2, 1, 13, 2, 20, 7, 1442, ...]])>, <tf.Tensor: shape=(), dtype=int32, numpy=2>)
填充序列
将序列列表转换为等量填充的序列,所有序列都具有相同的长度。
初始化一个随机序列列表并使用 tf.keras.preprocessing.sequence.pad_sequences 来填充你的序列。
from keras.preprocessing.sequence import pad_sequences
vectorized_review = [[1, 2, 3], [4, 5], [7]]
cap_vector = pad_sequences(vectorized_review, padding="post")
print(cap_vector)
运行此代码时,将获得以下输出:
[[1 2 3]
[4 5 0]
[7 0 0]]
预处理图像
对从任何数据集获取的图像进行中心裁剪、重新缩放和分配随机旋转。
获取图像并将其转换为 tf.data.Dataset。
import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = keras.utils.get_file(origin=dataset_url, fname="flower_photos", untar=True)
dataset = keras.preprocessing.image_dataset_from_directory(data_dir, batch_size=64)
运行此代码时,将获得以下输出:
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
228818944/228813984 [==============================] - 1s 0us/step
Found 3670 files belonging to 5 classes.
执行所需的操作并显示转换后的图像。
from tensorflow import keras
import matplotlib.pyplot as plt
from keras.layers.experimental.preprocessing import CenterCrop
from keras.layers.experimental.preprocessing import Rescaling
from keras.layers.experimental.preprocessing import RandomRotation
cropper = CenterCrop(height=150, width=150)
scaler = Rescaling(scale=1.0 / 255)
rotater = RandomRotation(factor=(-0.2, 0.5))
for images, labels in dataset.take(1):
output_data = rotater(scaler(cropper(images.numpy().astype("uint8"))))
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(output_data[i])
plt.title(dataset.class_names[labels[i]])
plt.axis("off")
运行此代码时,将获得一组九张图像。
数据增强
使用任何数据增强技术生成图像的多个版本。
使用 ImageDataGenerator 类水平和垂直移动图像。
import pathlib
import numpy as np
from tensorflow import keras
from keras.preprocessing.image import ImageDataGenerator
dataset_url = \
'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz'
data_dir = keras.utils.get_file(origin=dataset_url,
fname='flower_photos', untar=True)
dataset = keras.preprocessing.image_dataset_from_directory(data_dir,
image_size=(180, 180), batch_size=64)
img_gen = \
tf.keras.preprocessing.image.ImageDataGenerator(width_shift_range=0.4,
height_shift_range=0.2)
for (images, labels) in dataset.take(1):
iter = img_gen.flow(np.expand_dims(images[0].numpy(), 0))
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
batch = iter.next()
image = batch[0].astype('uint8')
plt.imshow(image)
plt.axis('off')
运行此代码时,将获得以下输出(可以选择任何随机图像):
预处理 CSV 数据
获取 CSV 数据并执行特征归一化以将数据插入正态分布。
tf.keras.layers.experimental.preprocessing.Normalization 类有助于规范化数据集。
import pandas as pd
import numpy as np
from keras.layers.experimental.preprocessing import Normalization
abalone_train = \
pd.read_csv('https://storage.googleapis.com/download.tensorflow.org/data/abalone_train.csv'
, names=[
'Length',
'Diameter',
'Height',
'Whole weight',
'Shucked weight',
'Viscera weight',
'Shell weight',
'Age',
])
normalize = Normalization()
normalize.adapt(np.array(abalone_train))
normalized_data = normalize(abalone_train)
print 'var: %.4f' % np.var(normalized_data)
print 'mean: %.4f' % np.mean(normalized_data)
运行此代码时,将获得以下输出:
var: 1.0000
mean: -0.0000
结论
数据预处理是一个重要的步骤,有助于根据想要构建的网络处理数据。 它有助于处理任何类型的数据,而实际上不必担心它与模型的兼容性。
在本文学习了如何预处理文本、图像和 CSV 数据。
在接下来的两篇博客中,将学习使用 Keras API 构建模型。