آموزش سفارشی: راهنما

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

این راهنما از یادگیری ماشینی برای دسته‌بندی گل‌های زنبق بر اساس گونه استفاده می‌کند. از TensorFlow برای موارد زیر استفاده می کند:

  1. یک مدل بسازید،
  2. این مدل را بر روی داده های مثال آموزش دهید و
  3. از مدل برای پیش بینی داده های ناشناخته استفاده کنید.

برنامه نویسی TensorFlow

این راهنما از این مفاهیم سطح بالا TensorFlow استفاده می کند:

این آموزش مانند بسیاری از برنامه های TensorFlow ساختار یافته است:

  1. وارد کردن و تجزیه مجموعه داده.
  2. نوع مدل را انتخاب کنید.
  3. مدل را آموزش دهید.
  4. کارایی مدل را ارزیابی کنید.
  5. از مدل آموزش دیده برای پیش بینی استفاده کنید.

برنامه راه اندازی

پیکربندی واردات

TensorFlow و سایر ماژول های پایتون مورد نیاز را وارد کنید. به طور پیش فرض، TensorFlow از اجرای مشتاق برای ارزیابی فوری عملیات استفاده می کند، به جای ایجاد یک نمودار محاسباتی که بعداً اجرا می شود، مقادیر مشخص را برمی گرداند. اگر به یک REPL یا کنسول تعاملی python عادت دارید، این به نظر آشنا است.

import os
import matplotlib.pyplot as plt
import tensorflow as tf
print("TensorFlow version: {}".format(tf.__version__))
print("Eager execution: {}".format(tf.executing_eagerly()))
TensorFlow version: 2.8.0-rc1
Eager execution: True

مشکل طبقه بندی عنبیه

تصور کنید یک گیاه شناس هستید که به دنبال روشی خودکار برای دسته بندی هر گل زنبق که پیدا می کنید هستید. یادگیری ماشین الگوریتم های زیادی را برای طبقه بندی آماری گل ها ارائه می دهد. به عنوان مثال، یک برنامه یادگیری ماشینی پیچیده می تواند گل ها را بر اساس عکس ها طبقه بندی کند. جاه طلبی های ما ساده تر است - ما گل های زنبق را بر اساس اندازه گیری طول و عرض کاسبرگ و گلبرگ آنها طبقه بندی می کنیم.

جنس زنبق شامل حدود 300 گونه است، اما برنامه ما فقط سه گونه زیر را طبقه بندی می کند:

  • زنبق ستوزا
  • زنبق ویرجینیکا
  • زنبق ورسیکالر
مقایسه هندسه گلبرگ برای سه گونه زنبق: زنبق ستوزا، زنبق ویرجینیکا و زنبق ورسیکالر
شکل 1. Iris setosa (توسط Radomil ، CC BY-SA 3.0)، Iris versicolor ، (توسط Dlanglois ، CC BY-SA 3.0)، و Iris virginica (توسط Frank Mayfield ، CC BY-SA 2.0).

خوشبختانه، شخصی قبلاً مجموعه داده ای از 120 گل زنبق را با اندازه های کاسبرگ و گلبرگ ایجاد کرده است. این یک مجموعه داده کلاسیک است که برای مشکلات طبقه بندی یادگیری ماشین مبتدی محبوب است.

مجموعه داده آموزشی را وارد و تجزیه کنید

فایل مجموعه داده را دانلود کنید و آن را به ساختاری تبدیل کنید که توسط این برنامه پایتون قابل استفاده باشد.

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

فایل مجموعه داده آموزشی را با استفاده از تابع tf.keras.utils.get_file کنید. این مسیر فایل فایل دانلود شده را برمی گرداند:

train_dataset_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv"

train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),
                                           origin=train_dataset_url)

print("Local copy of the dataset file: {}".format(train_dataset_fp))
Local copy of the dataset file: /home/kbuilder/.keras/datasets/iris_training.csv

داده ها را بررسی کنید

این مجموعه داده، iris_training.csv ، یک فایل متنی ساده است که داده های جدولی را به صورت مقادیر جدا شده با کاما (CSV) قالب بندی می کند. از دستور head -n5 برای نگاه کردن به پنج ورودی اول استفاده کنید:

head -n5 {train_dataset_fp}
120,4,setosa,versicolor,virginica
6.4,2.8,5.6,2.2,2
5.0,2.3,3.3,1.0,1
4.9,2.5,4.5,1.7,2
4.9,3.1,1.5,0.1,0

از این نمای مجموعه داده، به موارد زیر توجه کنید:

  1. خط اول هدر حاوی اطلاعاتی در مورد مجموعه داده است:
    • در مجموع 120 نمونه وجود دارد. هر نمونه دارای چهار ویژگی و یکی از سه نام برچسب ممکن است.
  2. ردیف های بعدی رکوردهای داده هستند، یک مثال در هر خط، که در آن:
    • چهار فیلد اول ویژگی‌ها هستند: اینها ویژگی‌های یک مثال است. در اینجا، فیلدها دارای اعداد شناور هستند که نشان دهنده اندازه گیری گل هستند.
    • آخرین ستون برچسب است : این مقداری است که می خواهیم پیش بینی کنیم. برای این مجموعه داده، یک مقدار صحیح 0، 1 یا 2 است که با نام گل مطابقت دارد.

بیایید آن را در کد بنویسیم:

# column order in CSV file
column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']

feature_names = column_names[:-1]
label_name = column_names[-1]

print("Features: {}".format(feature_names))
print("Label: {}".format(label_name))
Features: ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
Label: species

هر برچسب با نام رشته مرتبط است (به عنوان مثال، "setosa")، اما یادگیری ماشین معمولاً بر مقادیر عددی متکی است. اعداد برچسب به یک نمایش نامگذاری شده نگاشت می شوند، مانند:

  • 0 : زنبق ستوزا
  • 1 : زنبق رنگارنگ
  • 2 : زنبق ویرجینیکا

برای کسب اطلاعات بیشتر در مورد ویژگی‌ها و برچسب‌ها، به بخش اصطلاحات ML در دوره تصادف یادگیری ماشین مراجعه کنید.

class_names = ['Iris setosa', 'Iris versicolor', 'Iris virginica']

یک tf.data.Dataset ایجاد کنید

API داده‌های TensorFlow بسیاری از موارد رایج را برای بارگذاری داده‌ها در یک مدل مدیریت می‌کند. این یک API سطح بالا برای خواندن داده ها و تبدیل آن به فرمی است که برای آموزش استفاده می شود.

از آنجایی که مجموعه داده یک فایل متنی با فرمت CSV است، از تابع tf.data.experimental.make_csv_dataset برای تجزیه داده ها در قالب مناسب استفاده کنید. از آنجایی که این تابع داده‌ها را برای مدل‌های آموزشی تولید می‌کند، رفتار پیش‌فرض این است که داده‌ها را به هم بزند (shufle shuffle=True, shuffle_buffer_size=10000 )، و مجموعه داده را برای همیشه تکرار کنید ( num_epochs=None ). ما همچنین پارامتر batch_size را تنظیم می کنیم:

batch_size = 32

train_dataset = tf.data.experimental.make_csv_dataset(
    train_dataset_fp,
    batch_size,
    column_names=column_names,
    label_name=label_name,
    num_epochs=1)

تابع make_csv_dataset یک مجموعه tf.data.Dataset از جفت (features, label) را برمی گرداند، که در آن features ها یک فرهنگ لغت است: {'feature_name': value}

این اشیاء Dataset قابل تکرار هستند. بیایید به مجموعه ای از ویژگی ها نگاه کنیم:

features, labels = next(iter(train_dataset))

print(features)
OrderedDict([('sepal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([5. , 7.4, 6. , 7.2, 5.9, 5.8, 5. , 5. , 7.7, 5.7, 6.3, 5.8, 5. ,
       4.8, 6.6, 6.3, 5.4, 6.9, 4.8, 6.6, 5.8, 7.7, 6.7, 7.6, 5.5, 6.4,
       5.6, 6.4, 4.4, 4.5, 6.5, 6.3], dtype=float32)>), ('sepal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([3.5, 2.8, 2.7, 3.2, 3. , 2.6, 2. , 3.4, 3. , 2.8, 2.3, 2.7, 3.6,
       3.1, 2.9, 3.3, 3. , 3.1, 3. , 3. , 4. , 2.6, 3. , 3. , 2.4, 2.7,
       2.7, 2.8, 3. , 2.3, 2.8, 2.5], dtype=float32)>), ('petal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([1.6, 6.1, 5.1, 6. , 5.1, 4. , 3.5, 1.6, 6.1, 4.5, 4.4, 5.1, 1.4,
       1.6, 4.6, 4.7, 4.5, 5.1, 1.4, 4.4, 1.2, 6.9, 5. , 6.6, 3.7, 5.3,
       4.2, 5.6, 1.3, 1.3, 4.6, 5. ], dtype=float32)>), ('petal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([0.6, 1.9, 1.6, 1.8, 1.8, 1.2, 1. , 0.4, 2.3, 1.3, 1.3, 1.9, 0.2,
       0.2, 1.3, 1.6, 1.5, 2.3, 0.3, 1.4, 0.2, 2.3, 1.7, 2.1, 1. , 1.9,
       1.3, 2.1, 0.2, 0.3, 1.5, 1.9], dtype=float32)>)])

توجه داشته باشید که ویژگی‌های مشابه با هم گروه‌بندی یا دسته‌بندی می‌شوند. فیلدهای هر ردیف نمونه به آرایه ویژگی مربوطه اضافه می شوند. برای تنظیم تعداد نمونه های ذخیره شده در این آرایه های ویژگی، batch_size را تغییر دهید.

می‌توانید با ترسیم چند ویژگی از دسته، شروع به دیدن برخی خوشه‌ها کنید:

plt.scatter(features['petal_length'],
            features['sepal_length'],
            c=labels,
            cmap='viridis')

plt.xlabel("Petal length")
plt.ylabel("Sepal length")
plt.show()

png

برای ساده‌سازی مرحله ساخت مدل، تابعی ایجاد کنید تا فرهنگ لغت ویژگی‌ها را در یک آرایه واحد با شکل: (batch_size, num_features) کند.

این تابع از متد tf.stack استفاده می کند که مقادیر را از لیست تانسورها می گیرد و یک تانسور ترکیبی در بعد مشخص شده ایجاد می کند:

def pack_features_vector(features, labels):
  """Pack the features into a single array."""
  features = tf.stack(list(features.values()), axis=1)
  return features, labels

سپس از روش tf.data.Dataset#map برای بسته‌بندی features هر جفت (features,label) در مجموعه داده آموزشی استفاده کنید:

train_dataset = train_dataset.map(pack_features_vector)

عنصر ویژگی های Dataset اکنون آرایه هایی با شکل (batch_size, num_features) هستند. بیایید به چند مثال اول نگاه کنیم:

features, labels = next(iter(train_dataset))

print(features[:5])
tf.Tensor(
[[4.9 3.  1.4 0.2]
 [6.1 3.  4.9 1.8]
 [6.1 2.6 5.6 1.4]
 [6.9 3.2 5.7 2.3]
 [6.7 3.1 4.4 1.4]], shape=(5, 4), dtype=float32)

نوع مدل را انتخاب کنید

چرا مدل؟

مدل یک رابطه بین ویژگی ها و برچسب است. برای مسئله طبقه‌بندی زنبق، مدل رابطه بین اندازه‌گیری‌های کاسبرگ و گلبرگ و گونه‌های عنبیه پیش‌بینی‌شده را تعریف می‌کند. برخی از مدل‌های ساده را می‌توان با چند خط جبر توصیف کرد، اما مدل‌های یادگیری ماشینی پیچیده دارای تعداد زیادی پارامتر هستند که خلاصه کردن آنها دشوار است.

آیا می توانید بدون استفاده از یادگیری ماشینی رابطه بین چهار ویژگی و گونه عنبیه را تعیین کنید؟ یعنی آیا می توانید از تکنیک های برنامه نویسی سنتی (مثلاً بسیاری از دستورات شرطی) برای ایجاد یک مدل استفاده کنید؟ شاید اگر مجموعه داده را به اندازه کافی برای تعیین روابط بین اندازه گیری گلبرگ و کاسبرگ با یک گونه خاص تجزیه و تحلیل کنید. و این در مجموعه داده‌های پیچیده‌تر دشوار – شاید غیرممکن – می‌شود. یک رویکرد یادگیری ماشین خوب ، مدل را برای شما تعیین می کند . اگر نمونه‌های معرف کافی را به نوع مدل یادگیری ماشینی مناسب وارد کنید، برنامه روابط را برای شما مشخص خواهد کرد.

مدل را انتخاب کنید

ما باید نوع مدلی را برای آموزش انتخاب کنیم. انواع مختلفی از مدل ها وجود دارد و انتخاب یک مدل خوب نیاز به تجربه دارد. این آموزش از یک شبکه عصبی برای حل مشکل طبقه بندی عنبیه استفاده می کند. شبکه های عصبی می توانند روابط پیچیده ای بین ویژگی ها و برچسب پیدا کنند. این یک نمودار بسیار ساختار یافته است که در یک یا چند لایه پنهان سازماندهی شده است. هر لایه پنهان از یک یا چند نورون تشکیل شده است. چندین دسته از شبکه های عصبی وجود دارد و این برنامه از یک شبکه عصبی متراکم یا کاملاً متصل استفاده می کند : نورون های یک لایه اتصالات ورودی را از هر نورون در لایه قبلی دریافت می کنند. به عنوان مثال، شکل 2 یک شبکه عصبی متراکم متشکل از یک لایه ورودی، دو لایه پنهان و یک لایه خروجی را نشان می دهد:

نموداری از معماری شبکه: ورودی ها، 2 لایه پنهان و خروجی ها
شکل 2. یک شبکه عصبی با ویژگی ها، لایه های پنهان و پیش بینی ها.

هنگامی که مدل شکل 2 آموزش داده می شود و با یک مثال بدون برچسب تغذیه می شود، سه پیش بینی به دست می دهد: احتمال اینکه این گل گونه عنبیه داده شده باشد. این پیش بینی استنتاج نامیده می شود. برای این مثال، مجموع پیش‌بینی‌های خروجی 1.0 است. در شکل 2، این پیش بینی به صورت زیر تقسیم می شود: 0.02 برای Iris setosa ، 0.95 برای Iris versicolor ، و 0.03 برای Iris virginica . این به این معنی است که مدل پیش‌بینی می‌کند - با احتمال 95٪ - که یک گل نمونه بدون برچسب رنگ زنبق است.

با استفاده از Keras یک مدل ایجاد کنید

tf.keras API بهترین راه برای ایجاد مدل‌ها و لایه‌ها است. این کار ساخت مدل‌ها و آزمایش‌ها را آسان می‌کند در حالی که Keras پیچیدگی اتصال همه چیز را با هم انجام می‌دهد.

مدل tf.keras.Sequential یک پشته خطی از لایه ها است. سازنده آن فهرستی از نمونه های لایه را می گیرد، در این مورد، دو لایه tf.keras.layers.Dense لایه های متراکم با هر کدام 10 گره، و یک لایه خروجی با 3 گره که نشان دهنده پیش بینی های برچسب ما هستند. پارامتر input_shape لایه اول با تعداد ویژگی های مجموعه داده مطابقت دارد و لازم است:

model = tf.keras.Sequential([
  tf.keras.layers.Dense(10, activation=tf.nn.relu, input_shape=(4,)),  # input shape required
  tf.keras.layers.Dense(10, activation=tf.nn.relu),
  tf.keras.layers.Dense(3)
])

تابع فعال سازی شکل خروجی هر گره در لایه را تعیین می کند. این غیر خطی ها مهم هستند - بدون آنها مدل معادل یک لایه خواهد بود. tf.keras.activations زیادی وجود دارد، اما ReLU برای لایه های پنهان رایج است.

تعداد ایده آل لایه ها و نورون های پنهان به مشکل و مجموعه داده بستگی دارد. مانند بسیاری از جنبه های یادگیری ماشینی، انتخاب بهترین شکل شبکه عصبی مستلزم آمیزه ای از دانش و آزمایش است. به عنوان یک قاعده کلی، افزایش تعداد لایه‌های پنهان و نورون‌ها معمولاً مدل قدرتمندتری ایجاد می‌کند که برای آموزش مؤثر به داده‌های بیشتری نیاز دارد.

با استفاده از مدل

بیایید نگاهی گذرا به عملکرد این مدل با مجموعه ای از ویژگی ها بیندازیم:

predictions = model(features)
predictions[:5]
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[-4.0874639e+00,  1.5199981e-03, -9.9991310e-01],
       [-5.3246369e+00, -1.8366380e-01, -1.3161827e+00],
       [-5.1154275e+00, -2.8129923e-01, -1.3305402e+00],
       [-6.0694785e+00, -2.1251860e-01, -1.5091233e+00],
       [-5.6730523e+00, -1.4321266e-01, -1.4437559e+00]], dtype=float32)>

در اینجا، هر مثال یک logit برای هر کلاس برمی گرداند.

برای تبدیل این logit ها به یک احتمال برای هر کلاس، از تابع softmax استفاده کنید:

tf.nn.softmax(predictions[:5])
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[0.01210616, 0.7224865 , 0.26540732],
       [0.00440638, 0.75297093, 0.24262273],
       [0.00585618, 0.7362918 , 0.25785193],
       [0.00224076, 0.7835035 , 0.21425581],
       [0.00310779, 0.7834839 , 0.21340834]], dtype=float32)>

در نظر گرفتن tf.argmax در بین کلاس ها، شاخص کلاس پیش بینی شده را به ما می دهد. اما، این مدل هنوز آموزش ندیده است، بنابراین این ها پیش بینی های خوبی نیستند:

print("Prediction: {}".format(tf.argmax(predictions, axis=1)))
print("    Labels: {}".format(labels))
Prediction: [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
    Labels: [0 2 2 2 1 1 0 1 1 2 2 1 0 2 2 2 1 0 2 2 1 0 2 1 2 0 1 1 2 2 1 2]

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

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

مسئله طبقه‌بندی عنبیه نمونه‌ای از یادگیری ماشینی نظارت شده است : این مدل از نمونه‌هایی که حاوی برچسب هستند آموزش داده می‌شود. در یادگیری ماشینی بدون نظارت ، نمونه ها دارای برچسب نیستند. در عوض، مدل معمولاً الگوهایی را در میان ویژگی‌ها پیدا می‌کند.

تابع افت و گرادیان را تعریف کنید

هر دو مرحله آموزش و ارزیابی نیاز به محاسبه ضرر مدل دارند. این نشان می‌دهد که پیش‌بینی‌های یک مدل چقدر از برچسب مورد نظر دور هستند، به عبارت دیگر، عملکرد مدل چقدر بد است. ما می خواهیم این مقدار را به حداقل برسانیم یا بهینه کنیم.

مدل ما تلفات خود را با استفاده از تابع tf.keras.losses.SparseCategoricalCrossentropy محاسبه می‌کند که پیش‌بینی‌های احتمال کلاس مدل و برچسب مورد نظر را می‌گیرد و میانگین تلفات را در بین مثال‌ها برمی‌گرداند.

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
def loss(model, x, y, training):
  # training=training is needed only if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  y_ = model(x, training=training)

  return loss_object(y_true=y, y_pred=y_)


l = loss(model, features, labels, training=False)
print("Loss test: {}".format(l))
Loss test: 1.6059828996658325

از زمینه tf.GradientTape برای محاسبه گرادیان های مورد استفاده برای بهینه سازی مدل خود استفاده کنید:

def grad(model, inputs, targets):
  with tf.GradientTape() as tape:
    loss_value = loss(model, inputs, targets, training=True)
  return loss_value, tape.gradient(loss_value, model.trainable_variables)

یک بهینه ساز ایجاد کنید

یک بهینه ساز ، گرادیان های محاسبه شده را بر روی متغیرهای مدل اعمال می کند تا تابع loss را به حداقل برساند. می‌توانید تابع تلفات را به عنوان یک سطح منحنی در نظر بگیرید (شکل 3 را ببینید) و ما می‌خواهیم با قدم زدن در اطراف، پایین‌ترین نقطه آن را پیدا کنیم. شیب ها در جهت شیب دارترین صعود قرار دارند—بنابراین مسیر مخالف را طی می کنیم و به سمت پایین تپه حرکت می کنیم. با محاسبه مکرر تلفات و گرادیان برای هر دسته، مدل را در طول آموزش تنظیم می کنیم. به تدریج، مدل بهترین ترکیب وزن و سوگیری را برای به حداقل رساندن کاهش پیدا می کند. و هرچه ضرر کمتر باشد، پیش‌بینی مدل بهتر است.

الگوریتم های بهینه سازی در طول زمان در فضای سه بعدی تجسم شده اند.
شکل 3. الگوریتم های بهینه سازی که در طول زمان در فضای سه بعدی تجسم شده اند.
(منبع: Stanford class CS231n ، مجوز MIT، اعتبار تصویر: Alec Radford )

TensorFlow الگوریتم های بهینه سازی زیادی برای آموزش در دسترس دارد. این مدل از tf.keras.optimizers.SGD استفاده می کند که الگوریتم گرادیان تصادفی (SGD) را پیاده سازی می کند. learning_rate اندازه گام را برای هر تکرار در پایین تپه تعیین می کند. این یک فراپارامتر است که معمولاً برای دستیابی به نتایج بهتر آن را تنظیم می کنید.

بیایید بهینه ساز را راه اندازی کنیم:

optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)

ما از این برای محاسبه یک مرحله بهینه سازی استفاده می کنیم:

loss_value, grads = grad(model, features, labels)

print("Step: {}, Initial Loss: {}".format(optimizer.iterations.numpy(),
                                          loss_value.numpy()))

optimizer.apply_gradients(zip(grads, model.trainable_variables))

print("Step: {},         Loss: {}".format(optimizer.iterations.numpy(),
                                          loss(model, features, labels, training=True).numpy()))
Step: 0, Initial Loss: 1.6059828996658325
Step: 1,         Loss: 1.3759253025054932

حلقه آموزشی

با تمام قطعات در جای خود، مدل آماده آموزش است! یک حلقه آموزشی، نمونه های مجموعه داده را به مدل تغذیه می کند تا به پیش بینی های بهتر کمک کند. بلوک کد زیر این مراحل آموزشی را تنظیم می کند:

  1. هر دوره را تکرار کنید. یک دوره یک گذر از مجموعه داده است.
  2. در یک دوره، روی هر مثال در Dataset آموزشی تکرار کنید و ویژگی‌های ( x ) و برچسب ( y ) آن را در نظر بگیرید.
  3. با استفاده از ویژگی های مثال، یک پیش بینی انجام دهید و آن را با برچسب مقایسه کنید. عدم دقت پیش‌بینی را اندازه‌گیری کنید و از آن برای محاسبه تلفات و گرادیان‌های مدل استفاده کنید.
  4. از یک optimizer برای به روز رسانی متغیرهای مدل استفاده کنید.
  5. برخی از آمارها را برای تجسم پیگیری کنید.
  6. برای هر دوره تکرار کنید.

متغیر num_epochs تعداد دفعاتی است که روی مجموعه داده ها حلقه زده می شود. برخلاف شهود، آموزش طولانی‌تر یک مدل، مدل بهتر را تضمین نمی‌کند. num_epochs یک هایپرپارامتر است که می توانید آن را تنظیم کنید. انتخاب عدد مناسب معمولاً به تجربه و آزمایش نیاز دارد:

## Note: Rerunning this cell uses the same model variables

# Keep results for plotting
train_loss_results = []
train_accuracy_results = []

num_epochs = 201

for epoch in range(num_epochs):
  epoch_loss_avg = tf.keras.metrics.Mean()
  epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()

  # Training loop - using batches of 32
  for x, y in train_dataset:
    # Optimize the model
    loss_value, grads = grad(model, x, y)
    optimizer.apply_gradients(zip(grads, model.trainable_variables))

    # Track progress
    epoch_loss_avg.update_state(loss_value)  # Add current batch loss
    # Compare predicted label to actual label
    # training=True is needed only if there are layers with different
    # behavior during training versus inference (e.g. Dropout).
    epoch_accuracy.update_state(y, model(x, training=True))

  # End epoch
  train_loss_results.append(epoch_loss_avg.result())
  train_accuracy_results.append(epoch_accuracy.result())

  if epoch % 50 == 0:
    print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch,
                                                                epoch_loss_avg.result(),
                                                                epoch_accuracy.result()))
Epoch 000: Loss: 1.766, Accuracy: 43.333%
Epoch 050: Loss: 0.579, Accuracy: 71.667%
Epoch 100: Loss: 0.398, Accuracy: 82.500%
Epoch 150: Loss: 0.307, Accuracy: 92.500%
Epoch 200: Loss: 0.224, Accuracy: 95.833%

عملکرد ضرر را در طول زمان تجسم کنید

در حالی که چاپ کردن پیشرفت آموزشی مدل مفید است، مشاهده این پیشرفت اغلب مفیدتر است. TensorBoard یک ابزار تجسم سازی خوب است که با TensorFlow بسته بندی شده است، اما ما می توانیم نمودارهای اولیه را با استفاده از ماژول matplotlib ایجاد کنیم.

تفسیر این نمودارها به تجربه کمی نیاز دارد، اما شما واقعاً می خواهید شاهد کاهش ضرر و افزایش دقت باشید:

fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
fig.suptitle('Training Metrics')

axes[0].set_ylabel("Loss", fontsize=14)
axes[0].plot(train_loss_results)

axes[1].set_ylabel("Accuracy", fontsize=14)
axes[1].set_xlabel("Epoch", fontsize=14)
axes[1].plot(train_accuracy_results)
plt.show()

png

کارایی مدل را ارزیابی کنید

اکنون که مدل آموزش دیده است، می توانیم آماری از عملکرد آن به دست آوریم.

ارزیابی به معنای تعیین میزان مؤثر پیش بینی های مدل است. برای تعیین اثربخشی مدل در طبقه‌بندی عنبیه، اندازه‌گیری‌های کاسبرگ و گلبرگ را به مدل منتقل کنید و از مدل بخواهید تا پیش‌بینی کند که چه گونه‌های زنبق را نشان می‌دهند. سپس پیش بینی های مدل را با برچسب واقعی مقایسه کنید. به عنوان مثال، مدلی که گونه های صحیح را روی نیمی از نمونه های ورودی انتخاب کرده است، دقت 0.5 دارد. شکل 4 یک مدل کمی موثرتر را نشان می دهد که 4 مورد از 5 پیش بینی را با دقت 80 درصد درست می کند:

ویژگی های نمونه برچسب پیش بینی مدل
5.9 3.0 4.3 1.5 1 1
6.9 3.1 5.4 2.1 2 2
5.1 3.3 1.7 0.5 0 0
6.0 3.4 4.5 1.6 1 2
5.5 2.5 4.0 1.3 1 1
شکل 4. طبقه بندی کننده عنبیه که 80 درصد دقت دارد.

مجموعه داده آزمایشی را تنظیم کنید

ارزیابی مدل مشابه آموزش مدل است. بزرگترین تفاوت این است که نمونه ها از یک مجموعه تست جداگانه به جای مجموعه آموزشی آمده اند. برای ارزیابی منصفانه اثربخشی یک مدل، مثال‌هایی که برای ارزیابی یک مدل استفاده می‌شوند باید متفاوت از نمونه‌های مورد استفاده برای آموزش مدل باشند.

راه‌اندازی Dataset آزمایشی مشابه راه‌اندازی Dataset آموزشی است. فایل متنی CSV را دانلود کنید و مقادیر آن را تجزیه کنید، سپس کمی آن را به هم بزنید:

test_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv"

test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),
                                  origin=test_url)
test_dataset = tf.data.experimental.make_csv_dataset(
    test_fp,
    batch_size,
    column_names=column_names,
    label_name='species',
    num_epochs=1,
    shuffle=False)

test_dataset = test_dataset.map(pack_features_vector)

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

برخلاف مرحله آموزش، مدل فقط یک دوره واحد از داده های آزمون را ارزیابی می کند. در سلول کد زیر، روی هر مثال در مجموعه آزمایشی تکرار می‌کنیم و پیش‌بینی مدل را با برچسب واقعی مقایسه می‌کنیم. این برای اندازه گیری دقت مدل در کل مجموعه تست استفاده می شود:

test_accuracy = tf.keras.metrics.Accuracy()

for (x, y) in test_dataset:
  # training=False is needed only if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  logits = model(x, training=False)
  prediction = tf.argmax(logits, axis=1, output_type=tf.int32)
  test_accuracy(prediction, y)

print("Test set accuracy: {:.3%}".format(test_accuracy.result()))
Test set accuracy: 96.667%

برای مثال می‌توانیم در آخرین دسته ببینیم که مدل معمولاً درست است:

tf.stack([y,prediction],axis=1)
<tf.Tensor: shape=(30, 2), dtype=int32, numpy=
array([[1, 1],
       [2, 2],
       [0, 0],
       [1, 1],
       [1, 1],
       [1, 1],
       [0, 0],
       [2, 2],
       [1, 1],
       [2, 2],
       [2, 2],
       [0, 0],
       [2, 2],
       [1, 1],
       [1, 1],
       [0, 0],
       [1, 1],
       [0, 0],
       [0, 0],
       [2, 2],
       [0, 0],
       [1, 1],
       [2, 2],
       [1, 2],
       [1, 1],
       [1, 1],
       [0, 0],
       [1, 1],
       [2, 2],
       [1, 1]], dtype=int32)>

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

ما مدلی را آموزش داده‌ایم و "اثبات" کرده‌ایم که در طبقه‌بندی گونه‌های زنبق خوب - اما نه کامل است. حال بیایید از مدل آموزش‌دیده برای پیش‌بینی نمونه‌های بدون برچسب استفاده کنیم. یعنی روی نمونه هایی که دارای ویژگی هستند اما برچسب ندارند.

در زندگی واقعی، نمونه‌های بدون برچسب می‌توانند از بسیاری از منابع مختلف از جمله برنامه‌ها، فایل‌های CSV و فیدهای داده آمده باشند. در حال حاضر، ما به صورت دستی سه نمونه بدون برچسب را برای پیش‌بینی برچسب‌های آنها ارائه می‌کنیم. به یاد بیاورید، اعداد برچسب به یک نمایش نامگذاری شده به صورت زیر نگاشت می شوند:

  • 0 : زنبق ستوزا
  • 1 : زنبق رنگارنگ
  • 2 : زنبق ویرجینیکا
predict_dataset = tf.convert_to_tensor([
    [5.1, 3.3, 1.7, 0.5,],
    [5.9, 3.0, 4.2, 1.5,],
    [6.9, 3.1, 5.4, 2.1]
])

# training=False is needed only if there are layers with different
# behavior during training versus inference (e.g. Dropout).
predictions = model(predict_dataset, training=False)

for i, logits in enumerate(predictions):
  class_idx = tf.argmax(logits).numpy()
  p = tf.nn.softmax(logits)[class_idx]
  name = class_names[class_idx]
  print("Example {} prediction: {} ({:4.1f}%)".format(i, name, 100*p))
Example 0 prediction: Iris setosa (97.6%)
Example 1 prediction: Iris versicolor (82.0%)
Example 2 prediction: Iris virginica (56.4%)