Tensorflow learning notes (load pictures with tf.data)

Original code from t ensorflow

Tensorflow learning notes (load pictures with tf.data)

This tutorial provides an example of how to use TF Data loading a simple example of an image.

Importing modules, configuring

import tensorflow as tf

tf.data is used for data set construction and preprocessing

AUTOTUNE = tf.data.experimental.AUTOTUNE

Download and check the dataset

Download the file from the origin web site and name it 'flower'_ Photos', untar=True means decompressing the file.
Via pathlib Path (data_root_orig) obtains the path of the file (although data_root_orig also represents the path of the downloaded file, pathlib.Path can support different operating systems)

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

View data_ Files under root path

data_ There are 5 subfolders and 1txt files under the root path.

for item in data_root.iterdir():
  print(item)

data_root. There are 6 sub files under the path, data_root.glob('/') means to read all the pictures in the subfolder.

import random
all_image_paths = list(data_root.glob('*/*'))
all_image_paths

Some of the contents in the list are as follows
[WindowsPath('C:/Users/HUAWEI/.keras/datasets/flower_photos/daisy/100080576_f52e8ee070_n.jpg'),
WindowsPath('C:/Users/HUAWEI/.keras/datasets/flower_photos/daisy/10140303196_b88d3d6cec.jpg'),

Remove the windows path, leaving only the path of the picture

all_image_paths = [str(path) for path in all_image_paths]
all_image_paths


Disorder picture path order
See how many pictures there are

random.shuffle(all_image_paths)

image_count = len(all_image_paths)
image_count

Check the picture

Open data_ The "LICENSE.txt" file in the root path is encoded as' utf-8 ', and the contents after the fourth line of the file are read.
Separate each item in the list with 'CC-BY' as the separator.

import os
attributions = (data_root /"LICENSE.txt").open(encoding='utf-8').readlines()[4:]
attributions = [line.split(' CC-BY') for line in attributions]

Turn attributes into a dictionary

attributions = dict(attributions)
attributions

caption_image is a function to view the picture photographer. Input the path of the picture in the computer as a parameter, and use pathlib Path turns the path into a path suitable for the native system. image_ Path is equivalent to data_ A subset of root, pathlib Path(image_path). relative_ To (data_root) is equivalent to image_ Path minus data_ root. Examples are as follows

import IPython.display as display

def caption_image(image_path):
    image_rel = pathlib.Path(image_path).relative_to(data_root)
    return "Image (CC BY 2.0) " + ' - '.join(attributions[str(image_rel)].split(' - ')[:-1])

Randomly select 3 pictures, browse the pictures and print their photographers

for n in range(3):
  image_path = random.choice(all_image_paths)
  display.display(display.Image(image_path))
  print(caption_image(image_path))
   print()

Identify available labels

View data_ All files under the root path (5 folders, 1 txt file). If the file is a folder, select and sort the file name of the file.

label_names = sorted(item.name for item in data_root.glob('*/') if item.is_dir())
label_names

Each tag is assigned an index by enumerating.

label_to_index = dict((name, index) for index, name in enumerate(label_names))
label_to_index

Label all pictures. Via for path in all_image_paths gets the path of all pictures, such as' / home / kbuilder / keras/datasets/flower_ photos/tulips/8673416166_ 620fc18e2f_ n.jpg’,pathlib.Path(path).parent.name can get the name of the folder above the image, such as tulips.
Label all pictures by key value pair matching.

all_image_labels = [label_to_index[pathlib.Path(path).parent.name]
                    for path in all_image_paths]

print("First 10 labels indices: ", all_image_labels[:10])

Load and format pictures

Load and format the picture to make it suitable for model training.
Through TF io. read_ File() and the picture path read the original data, return it to image, and decode the original data image into image tensor

def load_and_preprocess_image(path):
  image = tf.io.read_file(path)
  return preprocess_image(image)

This function is used to decode the original data. Image is the original data. tf.image.decode_jpeg is used to decode pictures. channels=3 means to output RGB images. Finally, Tensor of uint8 type is returned.
Adjust the size of the image, [192, 192] represents the size of the new image.
Normalize the image.

def preprocess_image(image):
  image = tf.image.decode_jpeg(image, channels=3)
  image = tf.image.resize(image, [192, 192])
  image /= 255.0  # normalize to [0,1] range

  return image

View adjusted image
Do not display gridlines
Set abscissa
Set the title and capitalize the first letter

import matplotlib.pyplot as plt

image_path = all_image_paths[0]
label = all_image_labels[0]

plt.imshow(load_and_preprocess_image(img_path))
plt.grid(False)
plt.xlabel(caption_image(img_path))
plt.title(label_names[label].title())
print()

Build a TF data. Dataset

Build TF data. The simplest way to use a dataset is to use from_tensor_slices method.
Slice the string array to get a string dataset:

path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths)

Now create a new dataset by mapping preprocess on the path dataset_ Image to dynamically load and format images and return an iterator. That is, through load_and_preprocess_image path_ds map to image_ds, dynamically load and format pictures.

image_ds = path_ds.map(load_and_preprocess_image, num_parallel_calls=AUTOTUNE)

Browse pictures

import matplotlib.pyplot as plt

plt.figure(figsize=(8,8))
for n, image in enumerate(image_ds.take(4)):
  plt.subplot(2,2,n+1)
  plt.imshow(image)
  plt.grid(False)
  plt.xticks([])
  plt.yticks([])
  plt.xlabel(caption_image(all_image_paths[n]))
  plt.show()

Use the same from_tensor_slices method you can create a label dataset

label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(all_image_labels, tf.int64))

Since these datasets are in the same order, you can package them together to get a (picture, label) pair of datasets:

image_label_ds = tf.data.Dataset.zip((image_ds, label_ds))


ds = tf.data.Dataset.from_tensor_slices((all_image_paths, all_image_labels))

Tuples are decompressed into the location parameters of the mapping function

def load_and_preprocess_from_path_label(path, label):
  return load_and_preprocess_image(path), label

image_label_ds = ds.map(load_and_preprocess_from_path_label)
image_label_ds

During training, the data shall be fully disrupted, divided into batches, always through repetition, and batch shall be provided as much as possible

BATCH_SIZE = 32

Set a shuffle buffer size consistent with the data set size to ensure that the data is fully disrupted.

ds = image_label_ds.shuffle(buffer_size=image_count)
ds = ds.repeat()
ds = ds.batch(BATCH_SIZE)

When the model is training, prefetch enables the data set to obtain batch in the background.

ds = ds.prefetch(buffer_size=AUTOTUNE)
ds
ds = image_label_ds.apply(
  tf.data.experimental.shuffle_and_repeat(buffer_size=image_count))
ds = ds.batch(BATCH_SIZE)
ds = ds.prefetch(buffer_size=AUTOTUNE)
ds

Transfer data to model

mobile_net = tf.keras.applications.MobileNetV2(input_shape=(192, 192, 3), include_top=False)
mobile_net.trainable=False

The model expects its output to be standardized to the range of [- 1,1]. Before you pass the output to the MobilNet model, you need to convert its range from [0,1] to [- 1,1]:

def change_range(image,label):
  return 2*image-1, label

keras_ds = ds.map(change_range)

Build a model wrapped with MobileNet and use it in TF keras. layers. Use TF. Before the dense output layer keras. layers. Globalaveragepooling2d to average those spatial vectors:

model = tf.keras.Sequential([
  mobile_net,
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(len(label_names), activation = 'softmax')])
logit_batch = model(image_batch).numpy()

print("min logit:", logit_batch.min())
print("max logit:", logit_batch.max())
print()

print("Shape:", logit_batch.shape)

Compilation model

model.compile(optimizer=tf.keras.optimizers.Adam(),
              loss='sparse_categorical_crossentropy',
              metrics=["accuracy"])

View the number of variables that can be trained in the sense layer

len(model.trainable_variables)

model.summary()

Note that for demonstration purposes, you will only run 3 step s in each epoch, but generally it is passed to model You will specify the actual number of steps before fit()

steps_per_epoch=tf.math.ceil(len(all_image_paths)/BATCH_SIZE).numpy()
steps_per_epoch

model.fit(ds, epochs=1, steps_per_epoch=3)

Keywords: Python TensorFlow Deep Learning

Added by Viola on Fri, 17 Dec 2021 11:31:04 +0200