این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

بارگیری تصاویر

مشاهده در TensorFlow.org در Google Colab اجرا کنید مشاهده منبع در GitHub بارگیری نوت بوک

این آموزش نحوه بارگیری و پردازش مجموعه داده های تصویری را از دو طریق نشان می دهد. ابتدا از ابزارها و لایه های پیش پردازش Keras استفاده می کنید. بعد ، خط لوله ورودی خود را از ابتدا با استفاده از tf.data می نویسید .

برپایی

 import numpy as np
import os
import PIL
import PIL.Image
import tensorflow as tf
 
 print(tf.__version__)
 
2.3.0

مجموعه داده های گل را بارگیری کنید

در این آموزش از مجموعه ای از چند هزار عکس گل استفاده شده است. مجموعه داده های گل شامل 5 زیر فهرست ، یک در هر کلاس:

 flowers_photos/
  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(origin=dataset_url, 
                                   fname='flower_photos', 
                                   untar=True)
data_dir = pathlib.Path(data_dir)
 

پس از بارگیری (218MB) ، اکنون باید نسخه ای از عکس های گل موجود را در اختیار داشته باشید. تعداد کل 3670 تصویر:

 image_count = len(list(data_dir.glob('*/*.jpg')))
print(image_count)
 
3670

هر فهرست شامل تصاویر از آن نوع گل است. در اینجا چند گل رز آورده شده است:

 roses = list(data_dir.glob('roses/*'))
PIL.Image.open(str(roses[0]))
 

png

 roses = list(data_dir.glob('roses/*'))
PIL.Image.open(str(roses[1]))
 

png

با استفاده از پردازش keras.preup بارگیری کنید

بیایید با استفاده از image_dataset_from_directory این تصاویر را از روی دیسک بارگذاری کنیم .

ایجاد یک مجموعه داده

برخی از پارامترها را برای لودر تعریف کنید:

 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)
 
Found 3670 files belonging to 5 classes.
Using 2936 files for training.

 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 734 files for validation.

در این مجموعه داده ها می توانید نام کلاس را در ویژگی class_names بیابید.

 class_names = train_ds.class_names
print(class_names)
 
['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']

داده ها را تجسم کنید

در اینجا 9 تصویر اول از مجموعه داده های آموزش آورده شده است.

 import matplotlib.pyplot as plt

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")
 

png

با انتقال آنها به model.fit می توانید با استفاده از این مجموعه داده ها ، مدل را آموزش model.fit (که در ادامه در این آموزش آورده شده است). اگر دوست دارید ، می توانید به طور دستی از مجموعه داده تکرار کرده و دسته هایی از تصاویر را بازیابی کنید:

 for image_batch, labels_batch in train_ds:
  print(image_batch.shape)
  print(labels_batch.shape)
  break
 
(32, 180, 180, 3)
(32,)

image_batch یک image_batch شکل است (32, 180, 180, 3) . این مجموعه ای از 32 تصویر به شکل 180x180x3 (آخرین بعد مربوط به کانال های رنگی RGB است). label_batch یک label_batch از شکل (32,) ، این برچسب های مربوط به 32 تصویر هستند.

داده ها را استاندارد سازی کنید

مقادیر کانال RGB در محدوده [0, 255] . این برای شبکه عصبی ایده آل نیست؛ به طور کلی باید به دنبال کوچک کردن مقادیر ورودی خود باشید. در اینجا ، ما با استفاده از یک لایه Rescaling مقادیر استاندارد را در [0, 1] قرار می دهیم.

 from tensorflow.keras import layers

normalization_layer = tf.keras.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 0.96902645

یا می توانید برای ساده کردن استقرار ، لایه ای را در تعریف مدل خود قرار دهید. ما در اینجا از رویکرد دوم استفاده خواهیم کرد.

مجموعه داده برای عملکرد پیکربندی کنید

بیایید مطمئن شوید که از پیش تنظیم شده بافر استفاده می کنیم بنابراین می توانیم داده ها را از دیسک حاصل کنیم بدون اینکه I / O به مسدود شود. این دو روش مهمی هستند که باید هنگام بارگیری داده ها از آنها استفاده کنید.

.cache() تصاویر را بعد از بارگیری دیسک در اولین دوره ، در حافظه نگه می دارد. با این کار اطمینان حاصل می شود که در هنگام آموزش مدل ، مجموعه داده تبدیل به تنگنا نشود. اگر مجموعه داده شما برای جا به جایی حافظه بسیار بزرگ است ، می توانید از این روش برای ایجاد حافظه پنهان روی دیسک نیز استفاده کنید.

.prefetch() پردازش داده ها و اجرای مدل را در هنگام آموزش همپوشانی می کند.

خوانندگان علاقه مند می توانند اطلاعات بیشتری در مورد هر دو روش و همچنین نحوه ذخیره داده ها برای دیسک در راهنمای عملکرد داده ها کسب کنند .

 AUTOTUNE = tf.data.experimental.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
 

آموزش یک مدل

برای کامل بودن ، ما نحوه آموزش یک مدل ساده را با استفاده از مجموعه داده هایی که تازه آماده کرده ایم نشان خواهیم داد. این مدل به هیچ وجه تنظیم نشده است - هدف این است که مکانیک را با استفاده از مجموعه داده هایی که اخیراً ایجاد کرده اید به شما نشان دهد. برای کسب اطلاعات بیشتر در مورد طبقه بندی تصویر ، به این آموزش مراجعه کنید.

 num_classes = 5

model = tf.keras.Sequential([
  layers.experimental.preprocessing.Rescaling(1./255),
  layers.Conv2D(32, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(num_classes)
])
 
 model.compile(
  optimizer='adam',
  loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
  metrics=['accuracy'])
 
 model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=3
)
 
Epoch 1/3
92/92 [==============================] - 6s 66ms/step - loss: 1.3282 - accuracy: 0.4240 - val_loss: 1.1035 - val_accuracy: 0.5804
Epoch 2/3
92/92 [==============================] - 1s 11ms/step - loss: 1.0304 - accuracy: 0.5913 - val_loss: 0.9515 - val_accuracy: 0.6267
Epoch 3/3
92/92 [==============================] - 1s 11ms/step - loss: 0.8712 - accuracy: 0.6689 - val_loss: 0.9268 - val_accuracy: 0.6471

<tensorflow.python.keras.callbacks.History at 0x7f86d80ad128>

ممکن است دقت کنید که صحت اعتبار آن در مقایسه با دقت آموزش کم است ، و این نشان می دهد که مدل ما بیش از حد است. در این آموزش می توانید در مورد چربی بیش از حد و چگونگی کاهش آن اطلاعات بیشتری کسب کنید.

استفاده از tf.data برای کنترل دقیق تر

ابزارهای فوق پردازش keras.pre روشی مناسب برای ایجاد یک tf.data.Dataset از یک فهرست از تصاویر است. برای کنترل دقیق تر دانه ها ، می توانید خط لوله ورودی خود را با استفاده از tf.data . در این بخش نحوه انجام درست کار ، با شروع مسیر پرونده از پستی که قبلاً بارگیری کرده ایم ، نشان داده شده است.

 list_ds = tf.data.Dataset.list_files(str(data_dir/'*/*'), shuffle=False)
list_ds = list_ds.shuffle(image_count, reshuffle_each_iteration=False)
 
 for f in list_ds.take(5):
  print(f.numpy())
 
b'/home/kbuilder/.keras/datasets/flower_photos/roses/1445228333_59a07e0801.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/dandelion/14128835667_b6a916222c.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/roses/7551637034_55ae047756_n.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/dandelion/4574736702_b15ecf97d0_m.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/roses/6867597533_d65d1c39fb_n.jpg'

از ساختار درختی پرونده ها می توان برای تهیه لیست class_names .

 class_names = np.array(sorted([item.name for item in data_dir.glob('*') if item.name != "LICENSE.txt"]))
print(class_names)
 
['daisy' 'dandelion' 'roses' 'sunflowers' 'tulips']

تقسیم مجموعه داده ها به قطار و اعتبار سنجی:

 val_size = int(image_count * 0.2)
train_ds = list_ds.skip(val_size)
val_ds = list_ds.take(val_size)
 

می توانید طول هر مجموعه داده را به شرح زیر مشاهده کنید:

 print(tf.data.experimental.cardinality(train_ds).numpy())
print(tf.data.experimental.cardinality(val_ds).numpy())
 
2936
734

یک عملکرد کوتاه بنویسید که یک مسیر پرونده را به یک جفت (img, label) :

 def get_label(file_path):
  # convert the path to a list of path components
  parts = tf.strings.split(file_path, os.path.sep)
  # The second to last is the class-directory
  one_hot = parts[-2] == class_names
  # Integer encode the label
  return tf.argmax(one_hot)
 
 def decode_img(img):
  # convert the compressed string to a 3D uint8 tensor
  img = tf.image.decode_jpeg(img, channels=3)
  # resize the image to the desired size
  return tf.image.resize(img, [img_height, img_width])
 
 def process_path(file_path):
  label = get_label(file_path)
  # load the raw data from the file as a string
  img = tf.io.read_file(file_path)
  img = decode_img(img)
  return img, label
 

برای ایجاد یک مجموعه داده از image, label جفت های image, label از Dataset.map استفاده کنید:

 # Set `num_parallel_calls` so multiple images are loaded/processed in parallel.
train_ds = train_ds.map(process_path, num_parallel_calls=AUTOTUNE)
val_ds = val_ds.map(process_path, num_parallel_calls=AUTOTUNE)
 
 for image, label in train_ds.take(1):
  print("Image shape: ", image.numpy().shape)
  print("Label: ", label.numpy())
 
Image shape:  (180, 180, 3)
Label:  2

پیکربندی مجموعه داده برای عملکرد

برای آموزش یک مدل با این مجموعه داده می خواهید:

  • تا خوب جابجا شود.
  • برای دسته دار شدن
  • دسته ها در اسرع وقت در دسترس هستند.

این ویژگی ها را می توان با استفاده از API tf.data اضافه کرد. برای اطلاعات بیشتر ، به راهنمای عملکرد لوله کشی ورودی مراجعه کنید.

 def configure_for_performance(ds):
  ds = ds.cache()
  ds = ds.shuffle(buffer_size=1000)
  ds = ds.batch(batch_size)
  ds = ds.prefetch(buffer_size=AUTOTUNE)
  return ds

train_ds = configure_for_performance(train_ds)
val_ds = configure_for_performance(val_ds)
 

داده ها را تجسم کنید

شما می توانید این مجموعه داده را به طور مشابه با موردی که قبلاً ایجاد کرده اید تجسم کنید.

 image_batch, label_batch = next(iter(train_ds))

plt.figure(figsize=(10, 10))
for i in range(9):
  ax = plt.subplot(3, 3, i + 1)
  plt.imshow(image_batch[i].numpy().astype("uint8"))
  label = label_batch[i]
  plt.title(class_names[label])
  plt.axis("off")
 

png

آموزش مدل را ادامه دهید

اکنون tf.data.Dataset مشابهی را ایجاد کرده اید که توسط keras.preprocessing فوق ایجاد شده است. می توانید آموزش آن را با آن ادامه دهید. مانند گذشته ، ما فقط برای چند دوره آموزش خواهیم داد تا زمان اجرای آن کوتاه باشد.

 model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=3
)
 
Epoch 1/3
92/92 [==============================] - 2s 19ms/step - loss: 0.7267 - accuracy: 0.7272 - val_loss: 0.7963 - val_accuracy: 0.7098
Epoch 2/3
92/92 [==============================] - 1s 11ms/step - loss: 0.5384 - accuracy: 0.7987 - val_loss: 0.8067 - val_accuracy: 0.6894
Epoch 3/3
92/92 [==============================] - 1s 11ms/step - loss: 0.3382 - accuracy: 0.8770 - val_loss: 1.0317 - val_accuracy: 0.6662

<tensorflow.python.keras.callbacks.History at 0x7f87cd496320>

مراحل بعدی

در این آموزش دو روش بارگذاری تصاویر در دیسک نشان داده شده است. ابتدا ، شما یاد گرفتید که چگونه با استفاده از لایه ها و برنامه های پیش پردازش Keras ، مجموعه داده های تصویری را بارگیری و پردازش کنید. بعد ، شما یاد گرفتید که چگونه خط لوله ورودی را از ابتدا با استفاده از tf.data بنویسید. به عنوان مرحله بعدی ، می توانید با مراجعه به این آموزش نحوه افزودن افزودن داده را بیاموزید. برای کسب اطلاعات بیشتر در مورد tf.data ، می توانید به این راهنمای مراجعه کنید.