کمک به حفاظت از دیواره بزرگ مرجانی با TensorFlow در Kaggle اضافه کردن چالش

از TPU استفاده کنید

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

قبل از شما اجرا این نوت بوک COLAB، مطمئن شوید که شتاب دهنده سخت افزار خود را TPU با چک کردن تنظیمات نوت بوک خود را است: در زمان اجرا> تغییر نوع زمان اجرا> شتاب دهنده سخت افزار> TPU.

برپایی

import tensorflow as tf

import os
import tensorflow_datasets as tfds
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/requests/__init__.py:104: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (2.3.0)/charset_normalizer (2.0.8) doesn't match a supported version!
  RequestsDependencyWarning)

مقداردهی اولیه TPU

TPU ها معمولاً کارگران Cloud TPU هستند که با فرآیند محلی اجرای برنامه پایتون کاربر متفاوت هستند. بنابراین، برای اتصال به خوشه راه دور و مقداردهی اولیه TPU ها باید مقداری کار اولیه را انجام دهید. توجه داشته باشید که tpu آرگومان به tf.distribute.cluster_resolver.TPUClusterResolver یک آدرس خاص فقط برای COLAB است. اگر کد خود را در موتور محاسباتی Google (GCE) اجرا می‌کنید، در عوض باید نام Cloud TPU خود را ارسال کنید.

resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='')
tf.config.experimental_connect_to_cluster(resolver)
# This is the TPU initialization code that has to be at the beginning.
tf.tpu.experimental.initialize_tpu_system(resolver)
print("All devices: ", tf.config.list_logical_devices('TPU'))
INFO:tensorflow:Clearing out eager caches
INFO:tensorflow:Clearing out eager caches
INFO:tensorflow:Initializing the TPU system: grpc://10.240.1.2:8470
INFO:tensorflow:Initializing the TPU system: grpc://10.240.1.2:8470
INFO:tensorflow:Finished initializing TPU system.
INFO:tensorflow:Finished initializing TPU system.
All devices:  [LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:0', device_type='TPU'), LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:1', device_type='TPU'), LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:2', device_type='TPU'), LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:3', device_type='TPU'), LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:4', device_type='TPU'), LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:5', device_type='TPU'), LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:6', device_type='TPU'), LogicalDevice(name='/job:worker/replica:0/task:0/device:TPU:7', device_type='TPU')]

قرار دادن دستگاه به صورت دستی

پس از مقداردهی اولیه TPU، می توانید از قرار دادن دستی دستگاه برای قرار دادن محاسبات روی یک دستگاه TPU استفاده کنید:

a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])

with tf.device('/TPU:0'):
  c = tf.matmul(a, b)

print("c device: ", c.device)
print(c)
c device:  /job:worker/replica:0/task:0/device:TPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

استراتژی های توزیع

معمولاً شما مدل خود را روی چندین TPU به صورت موازی داده اجرا می کنید. برای توزیع مدل خود بر روی چندین TPU (یا سایر شتاب دهنده ها)، TensorFlow چندین استراتژی توزیع ارائه می دهد. شما می توانید استراتژی توزیع خود را جایگزین کنید و مدل بر روی هر دستگاه (TPU) مشخصی اجرا می شود. بررسی راهنمای استراتژی توزیع برای اطلاعات بیشتر.

برای نشان دادن این کار، ایجاد tf.distribute.TPUStrategy شی:

strategy = tf.distribute.TPUStrategy(resolver)
INFO:tensorflow:Found TPU system:
INFO:tensorflow:Found TPU system:
INFO:tensorflow:*** Num TPU Cores: 8
INFO:tensorflow:*** Num TPU Cores: 8
INFO:tensorflow:*** Num TPU Workers: 1
INFO:tensorflow:*** Num TPU Workers: 1
INFO:tensorflow:*** Num TPU Cores Per Worker: 8
INFO:tensorflow:*** Num TPU Cores Per Worker: 8
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:CPU:0, CPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:localhost/replica:0/task:0/device:CPU:0, CPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:CPU:0, CPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:CPU:0, CPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:0, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:0, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:1, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:1, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:2, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:2, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:3, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:3, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:4, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:4, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:5, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:5, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:6, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:6, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:7, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU:7, TPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU_SYSTEM:0, TPU_SYSTEM, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:TPU_SYSTEM:0, TPU_SYSTEM, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:XLA_CPU:0, XLA_CPU, 0, 0)
INFO:tensorflow:*** Available Device: _DeviceAttributes(/job:worker/replica:0/task:0/device:XLA_CPU:0, XLA_CPU, 0, 0)

به تکرار یک محاسبه بنابراین می تواند در تمام هسته TPU اجرا شود، شما می توانید آن را به تصویب strategy.run API. در زیر یک مثال که نشان می دهد تمام هسته ها دریافت ورودیهای مشابه است (a, b) و انجام ضرب ماتریس روی هر هسته به طور مستقل. خروجی ها مقادیر همه کپی ها خواهند بود.

@tf.function
def matmul_fn(x, y):
  z = tf.matmul(x, y)
  return z

z = strategy.run(matmul_fn, args=(a, b))
print(z)
PerReplica:{
  0: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32),
  1: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32),
  2: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32),
  3: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32),
  4: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32),
  5: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32),
  6: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32),
  7: tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)
}

طبقه بندی در TPU ها

پس از پوشش مفاهیم اساسی، یک مثال ملموس تر را در نظر بگیرید. این بخش نشان می دهد که چگونه به استفاده از توزیع استراتژی tf.distribute.TPUStrategy بیفزائید آموزش یک مدل Keras در TPU ابر.

مدل کراس را تعریف کنید

شروع با یک تعریف یک Sequential مدل Keras برای طبقه بندی تصویر بر روی مجموعه داده MNIST با استفاده از Keras. تفاوتی با آنچه که در صورت آموزش روی CPU یا GPU استفاده می کردید، ندارد. توجه داشته باشید که نیازهای ایجاد مدل Keras به داخل strategy.scope ، به طوری که متغیرها را می توان در هر دستگاه TPU ایجاد شده است. سایر بخش‌های کد لازم نیست در محدوده استراتژی قرار گیرند.

def create_model():
  return tf.keras.Sequential(
      [tf.keras.layers.Conv2D(256, 3, activation='relu', input_shape=(28, 28, 1)),
       tf.keras.layers.Conv2D(256, 3, activation='relu'),
       tf.keras.layers.Flatten(),
       tf.keras.layers.Dense(256, activation='relu'),
       tf.keras.layers.Dense(128, activation='relu'),
       tf.keras.layers.Dense(10)])

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

استفاده کارآمد از tf.data.Dataset API که با استفاده از یک ابر TPU، به عنوان آن غیر ممکن است به استفاده از ابر TPU ها مگر اینکه شما می توانید آنها را داده با سرعت کافی تغذیه حیاتی است. شما می توانید اطلاعات بیشتر در مورد مجموعه داده عملکرد در یاد راهنمای عملکرد خط لوله ورودی .

برای همه اما ساده ترین آزمایش (با استفاده از tf.data.Dataset.from_tensor_slices یا دیگر در نمودار داده ها)، شما نیاز به ذخیره تمام فایل های داده توسط مجموعه داده در Google Cloud Storage (GCS) سطل به عنوان خوانده شده.

برای بسیاری از موارد استفاده، توصیه می شود برای تبدیل داده های خود را به TFRecord فرمت و استفاده از یک tf.data.TFRecordDataset آن را بخوانید. را بررسی کنید آموزش TFRecord و tf.Example برای جزئیات بیشتر در مورد چگونه به انجام این کار. این یک نیاز سخت نیست و شما می توانید دیگر خوانندگان مجموعه داده، از جمله استفاده tf.data.FixedLengthRecordDataset یا tf.data.TextLineDataset .

شما می توانید تمام مجموعه داده های کوچک را به حافظه با استفاده از بار tf.data.Dataset.cache .

صرف نظر از فرمت داده استفاده شده، اکیداً توصیه می شود از فایل های حجیم در حد 100 مگابایت استفاده کنید. این به ویژه در این تنظیمات شبکه ای مهم است، زیرا هزینه باز کردن یک فایل به طور قابل توجهی بالاتر است.

همانطور که در کد زیر نشان داده شده است، شما باید با استفاده از tensorflow_datasets ماژول برای دریافت یک کپی از آموزش MNIST و داده ها از آزمون. توجه داشته باشید که try_gcs مشخص شده است به استفاده از یک کپی است که در یک سطل GCS عمومی در دسترس است. اگر این مورد را مشخص نکنید، TPU نمی تواند به داده های دانلود شده دسترسی پیدا کند.

def get_dataset(batch_size, is_training=True):
  split = 'train' if is_training else 'test'
  dataset, info = tfds.load(name='mnist', split=split, with_info=True,
                            as_supervised=True, try_gcs=True)

  # Normalize the input data.
  def scale(image, label):
    image = tf.cast(image, tf.float32)
    image /= 255.0
    return image, label

  dataset = dataset.map(scale)

  # Only shuffle and repeat the dataset in training. The advantage of having an
  # infinite dataset for training is to avoid the potential last partial batch
  # in each epoch, so that you don't need to think about scaling the gradients
  # based on the actual batch size.
  if is_training:
    dataset = dataset.shuffle(10000)
    dataset = dataset.repeat()

  dataset = dataset.batch(batch_size)

  return dataset

مدل را با استفاده از APIهای سطح بالای Keras آموزش دهید

شما می توانید مدل خود را با Keras آموزش fit و compile رابط های برنامه کاربردی. هیچ چیز TPU خاص در این گام به شما ارسال کد به عنوان اگر شما با استفاده از پردازنده های mutliple و یک بودند MirroredStrategy به جای TPUStrategy . شما می توانید در یاد آموزش توزیع شده با Keras آموزش.

with strategy.scope():
  model = create_model()
  model.compile(optimizer='adam',
                loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                metrics=['sparse_categorical_accuracy'])

batch_size = 200
steps_per_epoch = 60000 // batch_size
validation_steps = 10000 // batch_size

train_dataset = get_dataset(batch_size, is_training=True)
test_dataset = get_dataset(batch_size, is_training=False)

model.fit(train_dataset,
          epochs=5,
          steps_per_epoch=steps_per_epoch,
          validation_data=test_dataset, 
          validation_steps=validation_steps)
Epoch 1/5
300/300 [==============================] - 18s 32ms/step - loss: 0.1291 - sparse_categorical_accuracy: 0.9590 - val_loss: 0.0410 - val_sparse_categorical_accuracy: 0.9871
Epoch 2/5
300/300 [==============================] - 6s 22ms/step - loss: 0.0335 - sparse_categorical_accuracy: 0.9892 - val_loss: 0.0492 - val_sparse_categorical_accuracy: 0.9847
Epoch 3/5
300/300 [==============================] - 6s 21ms/step - loss: 0.0205 - sparse_categorical_accuracy: 0.9941 - val_loss: 0.0457 - val_sparse_categorical_accuracy: 0.9868
Epoch 4/5
300/300 [==============================] - 7s 22ms/step - loss: 0.0115 - sparse_categorical_accuracy: 0.9960 - val_loss: 0.0428 - val_sparse_categorical_accuracy: 0.9891
Epoch 5/5
300/300 [==============================] - 6s 21ms/step - loss: 0.0110 - sparse_categorical_accuracy: 0.9965 - val_loss: 0.0592 - val_sparse_categorical_accuracy: 0.9853
<keras.callbacks.History at 0x7f25fc108a58>

برای کاهش پایتون سربار و به حداکثر رساندن عملکرد TPU خود را، عبور در argument- steps_per_execution بیفزائید Model.compile . در این مثال، توان عملیاتی را حدود 50٪ افزایش می دهد:

with strategy.scope():
  model = create_model()
  model.compile(optimizer='adam',
                # Anything between 2 and `steps_per_epoch` could help here.
                steps_per_execution = 50,
                loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                metrics=['sparse_categorical_accuracy'])

model.fit(train_dataset,
          epochs=5,
          steps_per_epoch=steps_per_epoch,
          validation_data=test_dataset,
          validation_steps=validation_steps)
Epoch 1/5
300/300 [==============================] - 13s 42ms/step - loss: 0.1343 - sparse_categorical_accuracy: 0.9594 - val_loss: 0.0487 - val_sparse_categorical_accuracy: 0.9837
Epoch 2/5
300/300 [==============================] - 3s 10ms/step - loss: 0.0348 - sparse_categorical_accuracy: 0.9891 - val_loss: 0.0401 - val_sparse_categorical_accuracy: 0.9876
Epoch 3/5
300/300 [==============================] - 3s 10ms/step - loss: 0.0187 - sparse_categorical_accuracy: 0.9940 - val_loss: 0.0517 - val_sparse_categorical_accuracy: 0.9844
Epoch 4/5
300/300 [==============================] - 3s 10ms/step - loss: 0.0123 - sparse_categorical_accuracy: 0.9963 - val_loss: 0.0506 - val_sparse_categorical_accuracy: 0.9860
Epoch 5/5
300/300 [==============================] - 3s 10ms/step - loss: 0.0080 - sparse_categorical_accuracy: 0.9974 - val_loss: 0.0456 - val_sparse_categorical_accuracy: 0.9878
<keras.callbacks.History at 0x7f23ac7782b0>

مدل را با استفاده از یک حلقه آموزشی سفارشی آموزش دهید

شما همچنین می توانید ایجاد و آموزش مدل خود را با استفاده از tf.function و tf.distribute رابط های برنامه کاربردی به طور مستقیم. شما می توانید با استفاده از strategy.experimental_distribute_datasets_from_function API برای توزیع مجموعه داده با توجه به تابع مجموعه داده. توجه داشته باشید که در مثال زیر، اندازه دسته‌ای که به مجموعه داده ارسال می‌شود، به‌جای اندازه دسته کلی، اندازه دسته‌ای در هر نسخه است. برای کسب اطلاعات بیشتر، لطفا از آموزش سفارشی با tf.distribute.Strategy آموزش.

ابتدا مدل، مجموعه داده ها و tf.functions را ایجاد کنید:

# Create the model, optimizer and metrics inside the strategy scope, so that the
# variables can be mirrored on each device.
with strategy.scope():
  model = create_model()
  optimizer = tf.keras.optimizers.Adam()
  training_loss = tf.keras.metrics.Mean('training_loss', dtype=tf.float32)
  training_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
      'training_accuracy', dtype=tf.float32)

# Calculate per replica batch size, and distribute the datasets on each TPU
# worker.
per_replica_batch_size = batch_size // strategy.num_replicas_in_sync

train_dataset = strategy.experimental_distribute_datasets_from_function(
    lambda _: get_dataset(per_replica_batch_size, is_training=True))

@tf.function
def train_step(iterator):
  """The step function for one training step."""

  def step_fn(inputs):
    """The computation to run on each TPU device."""
    images, labels = inputs
    with tf.GradientTape() as tape:
      logits = model(images, training=True)
      loss = tf.keras.losses.sparse_categorical_crossentropy(
          labels, logits, from_logits=True)
      loss = tf.nn.compute_average_loss(loss, global_batch_size=batch_size)
    grads = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(list(zip(grads, model.trainable_variables)))
    training_loss.update_state(loss * strategy.num_replicas_in_sync)
    training_accuracy.update_state(labels, logits)

  strategy.run(step_fn, args=(next(iterator),))
WARNING:tensorflow:From <ipython-input-1-5625c2a14441>:15: StrategyBase.experimental_distribute_datasets_from_function (from tensorflow.python.distribute.distribute_lib) is deprecated and will be removed in a future version.
Instructions for updating:
rename to distribute_datasets_from_function
WARNING:tensorflow:From <ipython-input-1-5625c2a14441>:15: StrategyBase.experimental_distribute_datasets_from_function (from tensorflow.python.distribute.distribute_lib) is deprecated and will be removed in a future version.
Instructions for updating:
rename to distribute_datasets_from_function

سپس حلقه آموزشی را اجرا کنید:

steps_per_eval = 10000 // batch_size

train_iterator = iter(train_dataset)
for epoch in range(5):
  print('Epoch: {}/5'.format(epoch))

  for step in range(steps_per_epoch):
    train_step(train_iterator)
  print('Current step: {}, training loss: {}, accuracy: {}%'.format(
      optimizer.iterations.numpy(),
      round(float(training_loss.result()), 4),
      round(float(training_accuracy.result()) * 100, 2)))
  training_loss.reset_states()
  training_accuracy.reset_states()
Epoch: 0/5
Current step: 300, training loss: 0.1436, accuracy: 95.42%
Epoch: 1/5
Current step: 600, training loss: 0.0342, accuracy: 98.94%
Epoch: 2/5
Current step: 900, training loss: 0.0205, accuracy: 99.36%
Epoch: 3/5
Current step: 1200, training loss: 0.0123, accuracy: 99.59%
Epoch: 4/5
Current step: 1500, training loss: 0.0089, accuracy: 99.68%

بهبود عملکرد با مراحل متعدد در داخل tf.function

شما می توانید عملکرد های در حال اجرا مراحل متعدد در داخل یک بهبود tf.function . این است که با بسته بندی به دست آورد strategy.run پاسخ با tf.range داخل tf.function ، و دستخط آن را به یک تبدیل خواهد tf.while_loop در کارگر TPU است.

با وجود بهبود عملکرد، مبادلات با این روش در مقایسه با در حال اجرا یک قدم در داخل وجود دارد tf.function . در حال اجرا مراحل متعدد در یک tf.function کمتر انعطاف پذیر-شما می توانید همه چیز است اجرا نمی مشتاقانه و یا کد پایتون دلخواه در مراحل.

@tf.function
def train_multiple_steps(iterator, steps):
  """The step function for one training step."""

  def step_fn(inputs):
    """The computation to run on each TPU device."""
    images, labels = inputs
    with tf.GradientTape() as tape:
      logits = model(images, training=True)
      loss = tf.keras.losses.sparse_categorical_crossentropy(
          labels, logits, from_logits=True)
      loss = tf.nn.compute_average_loss(loss, global_batch_size=batch_size)
    grads = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(list(zip(grads, model.trainable_variables)))
    training_loss.update_state(loss * strategy.num_replicas_in_sync)
    training_accuracy.update_state(labels, logits)

  for _ in tf.range(steps):
    strategy.run(step_fn, args=(next(iterator),))

# Convert `steps_per_epoch` to `tf.Tensor` so the `tf.function` won't get 
# retraced if the value changes.
train_multiple_steps(train_iterator, tf.convert_to_tensor(steps_per_epoch))

print('Current step: {}, training loss: {}, accuracy: {}%'.format(
      optimizer.iterations.numpy(),
      round(float(training_loss.result()), 4),
      round(float(training_accuracy.result()) * 100, 2)))
Current step: 1800, training loss: 0.0093, accuracy: 99.68%

مراحل بعدی