امتیاز ادراکی (Inception Score) برای ارزیابی GAN‌ها — راهنمای کاربردی

۲۱۲ بازدید
آخرین به‌روزرسانی: ۰۳ تیر ۱۴۰۲
زمان مطالعه: ۱۶ دقیقه
امتیاز ادراکی (Inception Score) برای ارزیابی GAN‌ها — راهنمای کاربردی

در این مطلب، امتیاز ادراکی (Inception Score) برای ارزیابی GAN‌ها مورد بررسی قرار گرفته است. در این راستا، ابتدا مفهوم امتیاز ادراکی بیان و سپس، چگونگی محاسبه آن مورد بررسی قرار می‌گیرد. در ادامه مطلب، روش پیاده‌سازی امتیاز ادراکی با استفاده از کتابخانه‌های پایتون «نام‌پای» (NumPy) و «کرس» (Keras) بررسی و در نهایت، مشکلات امتیاز ادراکی بیان می‌شود.

امتیاز ادراکی (Inception Score) برای ارزیابی GAN‌ها

«شبکه‌های مولد تخاصمی» (Generative Adversarial Networks | GANs)، یک معماری «شبکه عصبی یادگیری عمیق» (Deep Learning Neural Network) برای آموزش دادن یک مدل مولد جهت تولید تصاویر مصنوعی است. مشکلی که پیرامون مدل‌های مولد وجود دارد آن است که هیچ راه هدفمندی برای ارزیابی کیفیت تصاویر تولید شده توسط آن‌ها، وجود ندارد. متداول است که تصاویر طی فرایند آموزش دادن مدل، به طور دوره‌ای تولید و ذخیره شوند و از عامل انسانی برای ارزیابی تصاویر تولید شده و انتخاب مدل نهایی استفاده می‌شود.

تاکنون، تلاش‌های زیادی برای ایجاد یک سنجه جهت ارزیابی تصاویر تولید شده انجام شده است. یک نمونه اولیه که توسط بخش زیادی نیز پذیرفته شده، «امتیاز ادراکی» (Inception Score | IS) است. در این راهنما، امتیاز ادراکی برای ارزیابی شبکه‌های مولد تخاصمی مورد بررسی قرار گرفته است. همانطور که پیش از این نیز بیان شد، از این امتیاز برای ارزیابی کیفیت تصاویر تولید شده توسط شبکه‌های مولد تخاصمی استفاده می‌شود. در این مطلب، مباحث زیر مورد بررسی قرار خواهند گرفت:

  • روش محاسبه امتیاز ادراکی و بینش نهفته در پس آنچه محاسبه می‌کند.
  • چگونگی پیاده‌سازی امتیاز ادراکی در پایتون با کتابخانه یادگیری عمیق «نام‌پای» (NumPy) و «کرس» (Keras)
  • روش محاسبه امتیاز ادراکی برای تصاویر کوچک مانند مواردی که در مجموعه داده CIFAR-10 وجود دارند.

برای مطالعه بیشتر پیرامون GAN‌ها، مطالعه مطلب «شبکه های مولد تخاصمی (Generative Adversarial Networks) — به زبان ساده» و «آموزش یادگیری ماشین با مثال‌های کاربردی ــ بخش هفتم» توصیه می‌شود. شایان ذکر است که این راهنما، به پنج بخش کلی تقسیم شده است؛ این بخش‌ها عبارتند از:

  • امتیاز ادراکی چیست؟
  • چگونه می‌توان امتیاز ادراکی را محاسبه کرد؟
  • چگونه می‌تواند امتیاز ادراکی را با کتابخانه «نام‌پای» (NumPy) محاسبه کرد؟
  • چگونه می‌توان امتیاز ادراکی را با کتابخانه «کرس» (Keras) پیاده‌سازی کرد؟
  • مشکلات امتیاز ادراکی

امتیاز ادراکی چیست؟

امتیاز ادراکی یا به طور خلاصه IS، یک سنجه - مفعولی - برای ارزیابی کیفیت تصاویر تولید شده، به ویژه تصاویر مصنوعی خروجی مدل‌های شبکه عصبی مولد است.

امتیاز ادراکی اولین بار توسط «تیم سالیمانز» (Tim Salimans) و همکاران در  سال ۲۰۱۶، در مقاله‌ای با عنوان «روش‌های بهبود یافته برای آموزش دادن شبکه‌های مولد تخاصمی» (Improved Techniques for Training GANs) منتشر شد. در مقاله مذکور، نویسنده از یک پلتفرم جمع‌سپاری شده (Crowd-Sourcing Platform)، یعنی «Amazon Mechanical Turk» برای ارزیابی تعداد زیادی از تصاویر تولید شده توسط GAN‌ها استفاده کرده است. آن‌ها، امتیاز ادراکی را طی تلاش‌های خود برای حذف ارزیابی عامل انسانی معرفی کردند. نویسندگان این مقاله کشف کرده‌اند که امتیاز به دست آمده توسط آن‌ها، با ارزیابی فاعلی مرتبط است. در کتاب «روش‌های بهبود یافته برای آموزش دادن شبکه‌های مولد تخاصمی» (چاپ ۲۰۱۶)، در این رابطه چنین آمده است:

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

امتیاز ادراکی شامل استفاده از مدل شبکه عصبی یادگیری عمیق از پیش آموزش داده شده برای دسته‌بندی تصاویر، به منظور دسته‌بندی تصاویر تولید شده توسط GAN‌ها می‌شود. به طور مشخص، مدل Inception v3 توسط «کریستین سزگدی» (Christian Szegedy) و همکاران در مقاله‌ای در سال ۲۰۱۵ با عنوان «بازنگری معماری ادراکی برای بینایی کامپیوتری» (Rethinking the Inception Architecture for Computer Vision) معرفی شد. با تکیه بر «مدل ادراکی»، نام «امتیاز ادراکی» نیز برای آن برگزیده شد. تعداد زیادی از تصاویر تولید شده با استفاده از مدل، دسته‌بندی شده‌اند. به طور ویژه، احتمال آنکه یک تصویر به هر کلاس تعلق داشته باشد، پیش‌بینی می‌شود. سپس، این پیش‌بینی‌ها در امتیاز ادراکی خلاصه شده‌اند.

  • کیفیت تصاویر: آیا تصاویر شبیه یه یک شی خاص هستند؟
  • گوناگونی تصویر: آیا طیف وسیعی از اشیا تولید شده‌اند؟

کمترین تعداد کلاس‌هایی که توسط امتیاز ادراکی پشتیبانی می‌شود ۱.۰ و بیشترین میزان آن تعداد کلاس‌هایی است که توسط مدل دسته‌بندی پشتیبانی می‌شود. در این مثال، مدل Inception v3 از ۱۰۰۰ کلاس از مجموعه داده ILSVRC 2012 پشتیبانی می‌کند و بر همین اساس، امتیاز ادراک بالایی برابر ۱,۰۰۰ است. مجموعه داده  CIFAR-10 مجموعه‌ای از ۵۰,۰۰۰ تصویر است که به ۱۰ کلاس از اشیا تقسیم شده‌اند. مقاله اصلی که ادراک را معرفی می‌کند، امتیازی را معرفی می‌کند که روی مجموعه داده آموزش CIFAR-10 محاسبه شده و مقدار آن برابر با 11.24 +/- 0.12 است. با استفاده از مدل GAN، که در این مطلب نیز معرفی شده است، آن‌ها هنگام تولید تصاویر مصنوعی برای این مجموعه داده، به امتیاز ادراکی 8.09 +/- .07 رسیدند.

روش محاسبه امتیاز ادراکی

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

به همین ترتیب، احتمال شرطی همه تصاویر تولید شده در مجموعه باید دارای «آنتروپی پایین» (Low Entropy) باشد. در کتاب «روش‌های بهبود یافته برای آموزش دادن شبکه‌های مولد تخاصمی» (Improved Techniques for Training GANs)، چاپ سال ۲۰۱۶، در این رابطه چنین آمده است:

تصاویری که حاوی شی معنادار هستند، باید یک توزیع برچسب شرطی (p(y|x با آنتروپی پایین داشته باشند.

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

  • entropy = -sum(p_i * log(p_i))‎

احتمال شرطی، interest کاربر در کیفیت تصویر را محاسبه می‌کند.

برای ثبت interest کاربر به تصاویر گوناگون، از «احتمال حاشیه‌ای» (Marginal Probability) استفاده می‌شود. این توزیع احتمال همه تصاویر تولید شده است. بنابراین، برای داشتن آنتروپی بالا، «انتگرال توزیع احتمال حاشیه‌ای» (Integral Of The Marginal Probability Distribution) ترجیح داده می‌شود. در کتاب روش‌های بهبود یافته برای آموزش شبکه‌های مولد تخاصمی،‌ در این رابطه چنین آمده است:

علاوه بر این، از مدل انتظار می‌رود که تصاویر متنوعی تولید کند؛ بنابراین، انتگرال حاشیه‌ای p(y|x = G(z))dz باید آنتروپی بالایی داشته باشد.

این عناصر با محاسبه «معیار واگرایی کولبک-لیبلر» (Kullback-Leibler Divergence) یا «واگرایی KL» (آنتروپی نسبی)، بین توزیع احتمال شرطی و احتمال حاشیه‌ای محاسبه می‌شوند.

محاسبه واگرایی بین دو توزیع، با استفاده از عملگر «||» محاسبه می‌شود، بنابراین می‌تواند گفت که interest بر واگرایی بین C برای شرطی و M برای توزیع حاشیه‌ای یا KL (C || M)‎ است. به طور خاص، interest بر میانگین واگرایی KL برای همه تصاویر تولید شده است. در کتابی که پیش‌تر به ان اشاره شد، در این رابطه، چنین بیان شده است:

با ترکیب این دو نیازمندی، سنجه‌ای که معرفی می‌شود exp(Ex KL(p(y|x)||p(y)))‎ است.

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

کد پیاده‌سازی امتیاز ادراکی

1# Code derived from tensorflow/tensorflow/models/image/imagenet/classify_image.py
2from __future__ import absolute_import
3from __future__ import division
4from __future__ import print_function
5
6import os.path
7import sys
8import tarfile
9
10import numpy as np
11from six.moves import urllib
12import tensorflow as tf
13import glob
14import scipy.misc
15import math
16import sys
17
18MODEL_DIR = '/tmp/imagenet'
19DATA_URL = 'http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz'
20softmax = None
21
22# Call this function with list of images. Each of elements should be a 
23# numpy array with values ranging from 0 to 255.
24def get_inception_score(images, splits=10):
25  assert(type(images) == list)
26  assert(type(images[0]) == np.ndarray)
27  assert(len(images[0].shape) == 3)
28  assert(np.max(images[0]) > 10)
29  assert(np.min(images[0]) >= 0.0)
30  inps = []
31  for img in images:
32    img = img.astype(np.float32)
33    inps.append(np.expand_dims(img, 0))
34  bs = 1
35  with tf.Session() as sess:
36    preds = []
37    n_batches = int(math.ceil(float(len(inps)) / float(bs)))
38    for i in range(n_batches):
39        sys.stdout.write(".")
40        sys.stdout.flush()
41        inp = inps[(i * bs):min((i + 1) * bs, len(inps))]
42        inp = np.concatenate(inp, 0)
43        pred = sess.run(softmax, {'ExpandDims:0': inp})
44        preds.append(pred)
45    preds = np.concatenate(preds, 0)
46    scores = []
47    for i in range(splits):
48      part = preds[(i * preds.shape[0] // splits):((i + 1) * preds.shape[0] // splits), :]
49      kl = part * (np.log(part) - np.log(np.expand_dims(np.mean(part, 0), 0)))
50      kl = np.mean(np.sum(kl, 1))
51      scores.append(np.exp(kl))
52    return np.mean(scores), np.std(scores)
53
54# This function is called automatically.
55def _init_inception():
56  global softmax
57  if not os.path.exists(MODEL_DIR):
58    os.makedirs(MODEL_DIR)
59  filename = DATA_URL.split('/')[-1]
60  filepath = os.path.join(MODEL_DIR, filename)
61  if not os.path.exists(filepath):
62    def _progress(count, block_size, total_size):
63      sys.stdout.write('\r>> Downloading %s %.1f%%' % (
64          filename, float(count * block_size) / float(total_size) * 100.0))
65      sys.stdout.flush()
66    filepath, _ = urllib.request.urlretrieve(DATA_URL, filepath, _progress)
67    print()
68    statinfo = os.stat(filepath)
69    print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.')
70  tarfile.open(filepath, 'r:gz').extractall(MODEL_DIR)
71  with tf.gfile.FastGFile(os.path.join(
72      MODEL_DIR, 'classify_image_graph_def.pb'), 'rb') as f:
73    graph_def = tf.GraphDef()
74    graph_def.ParseFromString(f.read())
75    _ = tf.import_graph_def(graph_def, name='')
76  # Works with an arbitrary minibatch size.
77  with tf.Session() as sess:
78    pool3 = sess.graph.get_tensor_by_name('pool_3:0')
79    ops = pool3.graph.get_operations()
80    for op_idx, op in enumerate(ops):
81        for o in op.outputs:
82            shape = o.get_shape()
83            shape = [s.value for s in shape]
84            new_shape = []
85            for j, s in enumerate(shape):
86                if s == 1 and j == 0:
87                    new_shape.append(None)
88                else:
89                    new_shape.append(s)
90            o.set_shape(tf.TensorShape(new_shape))
91    w = sess.graph.get_operation_by_name("softmax/logits/MatMul").inputs[1]
92    logits = tf.matmul(tf.squeeze(pool3, [1, 2]), w)
93    softmax = tf.nn.softmax(logits)
94
95if softmax is None:
96  _init_inception()

در محاسبه امتیاز، تعداد زیادی از تصاویر برای رنجی از اشیا، مثلا ۵۰,۰۰۰ محاسبه می‌شوند. تصاویر به ۱۰ دسته، برای مثال ۵,۰۰۰ تصویر به ازای هر گروه، تقسیم می‌شوند و امتیاز ادراکی روی هر گروه از تصاویر محاسبه می‌شود. سپس، انحراف میانگین و استاندارد از امتیاز، محاسبه می‌شود. محاسبه امتیاز ادراکی روی گروهی از تصاویر، شامل استفاده از مدل inception v3 برای محاسبه احتمال شرطی برای هر تصویر می‌شود ((p(y). سپس، واگرایی KL برای هر تصویر به صورتی که در رابطه زیر آمده است، محاسبه می‌شود.

KL divergence = p(y|x) * (log(p(y|x)) – log(p(y)))‎

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

روش پیاده‌سازی امتیاز ادراکی با نام‌پای

پیاده‌سازی محاسبه امتیاز ادراکی در پایتون با استفاده از آرایه‌های نام‌پای (NumPy) کار ساده‌ای است. ابتدا، تابعی تعریف می‌شود که مجموعه‌ای از احتمال‌های شرطی را دریافت و امتیاز ادراکی را محاسبه می‌کند. تابع calculate_inception_score()‎ که در ادامه آمده است، این روال را پیاده‌سازی می‌کند. یک تغییر کوچک، تعریف یک اپسیلون (یک عدد کوچک نزدیک به صفر) برای هنگامی است که احتمال‌های لگاریتمی محاسبه می‌شوند.

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

1# calculate the inception score for p(y|x)
2def calculate_inception_score(p_yx, eps=1E-16):
3	# calculate p(y)
4	p_y = expand_dims(p_yx.mean(axis=0), 0)
5	# kl divergence for each image
6	kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps))
7	# sum over classes
8	sum_kl_d = kl_d.sum(axis=1)
9	# average over images
10	avg_kl_d = mean(sum_kl_d)
11	# undo the logs
12	is_score = exp(avg_kl_d)
13	return is_score

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

1# conditional probabilities for high quality images
2p_yx = asarray([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])

انتظار می‌رود که امتیاز ادراکی برای این مثال برابر با 3.0 (یا بسیار نزدیک به آن) باشد. این امر بدین دلیل است که عدد مشابهی از تصاویر برای هر کلاس وجود دارد (یک تصویر برای هر سه کلاس) و هر احتمال شرطی به طور بیشینه‌ای مطمئن است. مثال کامل برای محاسبه امتیاز ادراکی برای این احتمال‌ها در ادامه آمده است.

1# calculate inception score in numpy
2from numpy import asarray
3from numpy import expand_dims
4from numpy import log
5from numpy import mean
6from numpy import exp
7 
8# calculate the inception score for p(y|x)
9def calculate_inception_score(p_yx, eps=1E-16):
10	# calculate p(y)
11	p_y = expand_dims(p_yx.mean(axis=0), 0)
12	# kl divergence for each image
13	kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps))
14	# sum over classes
15	sum_kl_d = kl_d.sum(axis=1)
16	# average over images
17	avg_kl_d = mean(sum_kl_d)
18	# undo the logs
19	is_score = exp(avg_kl_d)
20	return is_score
21 
22# conditional probabilities for high quality images
23p_yx = asarray([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])
24score = calculate_inception_score(p_yx)
25print(score)

با اجرای مثال بالا، امتیاز ادراکی ۳.۰ (یا عددی بسیار نزدیک به آن) در خروجی چاپ می‌شود.

2.999999999999999

می‌توان بدترین شرایط را نیز آزمود. این، همان جایی است که همچنان عدد مشابهی از تصاویر برای هر کلاس وجود دارد (یکی برای هر یک از این سه کلاس)، اما اشیا ناشناخته هستند، و یک توزیع احتمال پیش‌بینی شده یکنواخت برای هر کلاس به دست می‌دهد.

1# conditional probabilities for low quality images
2p_yx = asarray([[0.33, 0.33, 0.33], [0.33, 0.33, 0.33], [0.33, 0.33, 0.33]])
3score = calculate_inception_score(p_yx)
4print(score)

در این شرایط، انتظار می‌رود که امتیاز ادراکی بدترین حالت ممکن باشد که در آن هیچ تفاوتی بین توزیع‌های شرطی و حاشیه‌ای نباشد؛ برای مثال، امتیاز ادراکی 1.0. با یکپارچه کردن همه این موارد در کنار هم، مثال کامل به صورت زیر خواهد بود.

1# calculate inception score in numpy
2from numpy import asarray
3from numpy import expand_dims
4from numpy import log
5from numpy import mean
6from numpy import exp
7 
8# calculate the inception score for p(y|x)
9def calculate_inception_score(p_yx, eps=1E-16):
10	# calculate p(y)
11	p_y = expand_dims(p_yx.mean(axis=0), 0)
12	# kl divergence for each image
13	kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps))
14	# sum over classes
15	sum_kl_d = kl_d.sum(axis=1)
16	# average over images
17	avg_kl_d = mean(sum_kl_d)
18	# undo the logs
19	is_score = exp(avg_kl_d)
20	return is_score
21 
22# conditional probabilities for low quality images
23p_yx = asarray([[0.33, 0.33, 0.33], [0.33, 0.33, 0.33], [0.33, 0.33, 0.33]])
24score = calculate_inception_score(p_yx)
25print(score)

با اجرای مثال بالا، امتیاز ادراکی ۱.۰ حاصل می‌شود.

1.0

مخاطبان می‌توانند در صورت تمایل، این روش محاسبه امتیاز ادراکی را مورد بررسی بیشتر قرار دهند و آزمون‌های آسیب‌شناسی را روی آن انجام دهند.

روش پیاده‌سازی امتیاز ادراکی با Keras

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

ابتدا، می‌توان مدل Inception v3 را به طور مستقیم در Keras بارگذاری کرد.

1...
2# load inception v3 model
3model = InceptionV3()

مدل، انتظار دارد که تصاویر رنگی و دارای ابعاد 299×299 پیکسل باشند. علاوه بر آن، مقادیر پیکسل باید به شیوه‌ای مشابه با روش مورد استفاده برای داده‌های آموزش، مقایس‌دهی شوند. این مورد با تبدیل مقادیر پیکسل‌ها از عدد صحیح به مقادیر اعشاری و سپس، فراخوانی تابع preprocess_input()‎ برای تصاویر، قابل حصول است.

1...
2# convert from uint8 to float32
3processed = images.astype('float32')
4# pre-process raw images for inception v3 model
5processed = preprocess_input(processed)

سپس، احتمال شرطی برای هر یک از ۱,۰۰۰ دسته تصویر، ممکن است برای این تصاویر پیش‌بینی شود.

1...
2# predict class probabilities for images
3yhat = model.predict(images)

امتیاز ادراکی به طور مستقیم و به روشی که در بخش پیشین انجام شد، روی آرایه نام‌پای از احتمال‌ها قابل محاسبه است. پیش از انجام این کار، باید احتمال‌های شرطی را در گروه‌هایی تقسیم کرد که به وسیله آرگومان n_split کنترل می‌شود و روی مقدار پیش‌فرض ۱۰ که در مقاله اصلی نیز استفاده شده بود، تنظیم می‌شود.

1...
2n_part = floor(images.shape[0] / n_split)

می‌توان احتمال شرطی را در بلوک‌هایی از تصاویر یا پیش‌بینی‌های n_part برشمرد و امتیاز ادراکی را محاسبه کرد.

1...
2# retrieve p(y|x)
3ix_start, ix_end = i * n_part, (i+1) * n_part
4p_yx = yhat[ix_start:ix_end]

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

1...
2# average across images
3is_avg, is_std = mean(scores), std(scores)

با کنار هم قرار دادن همه این موارد، تابع calculate_inception_score()‎ که در ادامه آمده است، یک آرایه از تصاویر را با سایز و مقدار پیکسل مورد انتظار در [0,255] می‌گیرد و امتیاز ادراکی انحراف معیار و میانگین را با استفاده از مدل inception v3 در کرس محاسبه می‌کند.

1# assumes images have the shape 299x299x3, pixels in [0,255]
2def calculate_inception_score(images, n_split=10, eps=1E-16):
3	# load inception v3 model
4	model = InceptionV3()
5	# convert from uint8 to float32
6	processed = images.astype('float32')
7	# pre-process raw images for inception v3 model
8	processed = preprocess_input(processed)
9	# predict class probabilities for images
10	yhat = model.predict(processed)
11	# enumerate splits of images/predictions
12	scores = list()
13	n_part = floor(images.shape[0] / n_split)
14	for i in range(n_split):
15		# retrieve p(y|x)
16		ix_start, ix_end = i * n_part, i * n_part + n_part
17		p_yx = yhat[ix_start:ix_end]
18		# calculate p(y)
19		p_y = expand_dims(p_yx.mean(axis=0), 0)
20		# calculate KL divergence using log probabilities
21		kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps))
22		# sum over classes
23		sum_kl_d = kl_d.sum(axis=1)
24		# average over images
25		avg_kl_d = mean(sum_kl_d)
26		# undo the log
27		is_score = exp(avg_kl_d)
28		# store
29		scores.append(is_score)
30	# average across images
31	is_avg, is_std = mean(scores), std(scores)
32	return is_avg, is_std

این تابع را می‌توان با ۵۰ تصویر مصنوعی با مقدار 1.0 برای همه پیکسل‌ها، آزمود.

1...
2# pretend to load images
3images = ones((50, 299, 299, 3))
4print('loaded', images.shape)

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

1# calculate inception score with Keras
2from math import floor
3from numpy import ones
4from numpy import expand_dims
5from numpy import log
6from numpy import mean
7from numpy import std
8from numpy import exp
9from keras.applications.inception_v3 import InceptionV3
10from keras.applications.inception_v3 import preprocess_input
11 
12# assumes images have the shape 299x299x3, pixels in [0,255]
13def calculate_inception_score(images, n_split=10, eps=1E-16):
14	# load inception v3 model
15	model = InceptionV3()
16	# convert from uint8 to float32
17	processed = images.astype('float32')
18	# pre-process raw images for inception v3 model
19	processed = preprocess_input(processed)
20	# predict class probabilities for images
21	yhat = model.predict(processed)
22	# enumerate splits of images/predictions
23	scores = list()
24	n_part = floor(images.shape[0] / n_split)
25	for i in range(n_split):
26		# retrieve p(y|x)
27		ix_start, ix_end = i * n_part, i * n_part + n_part
28		p_yx = yhat[ix_start:ix_end]
29		# calculate p(y)
30		p_y = expand_dims(p_yx.mean(axis=0), 0)
31		# calculate KL divergence using log probabilities
32		kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps))
33		# sum over classes
34		sum_kl_d = kl_d.sum(axis=1)
35		# average over images
36		avg_kl_d = mean(sum_kl_d)
37		# undo the log
38		is_score = exp(avg_kl_d)
39		# store
40		scores.append(is_score)
41	# average across images
42	is_avg, is_std = mean(scores), std(scores)
43	return is_avg, is_std
44 
45# pretend to load images
46images = ones((50, 299, 299, 3))
47print('loaded', images.shape)
48# calculate inception score
49is_avg, is_std = calculate_inception_score(images)
50print('score', is_avg, is_std)

پس از اجرای مثال بالا، ابتدا ۵۰ تصویر جعلی تعریف می‌شوند؛ سپس، امتیاز ادراکی برای هر دسته محاسبه می‌شود و امتیاز ادراکی مورد انتظار 1.0 و انحراف معیار 0.0 ارائه می‌شود.

نکته: اولین باری که مدل InceptionV3 استفاده شده است، کرس، وزن‌های مدل را دانلود و آن‌ها را در پوشهkeras/models/ ‎./~ در ایستگاه کاری کاربر ذخیره می‌کند. وزن‌ها در حدود ۱۰۰ مگابایت هستند و ممکن است دانلود آن‌ها بسته به سرعت اینترنت کاربر، دقایقی طول بکشد.

1loaded (50, 299, 299, 3)
2score 1.0 0.0

می‌توان محاسبه امتیاز ادراکی را روی داده‌های واقعی نیز آزمود. «رابط برنامه‌نویسی کاربردی کرس» (Keras API) امکان دسترسی به مجموعه داده CIFAR-10 را فراهم می‌کند. این موارد، تصاویر رنگی با سایز کوچک و 32×32 پیکسل هستند. ابتدا، می‌توان تصاویر را به گروه‌هایی تقسیم کرد. سپس، تصاویر به ابعاد مورد انتظار 299×299 «بزرگ‌نمایی» (Upsample) می‌شود؛ مقادیر پیکسل‌ها پیش‌پردازش می‌شوند، احتمال کلاس پیش‌بینی می‌شود و سپس، امتیاز ادراکی محاسبه می‌شود. این یک مثال مفید برای محاسبه امتیاز ادراکی روی تصاویر تولید شده خود کاربر است؛ زیرا کاربر باید تصاویر را به اندازه مورد انتظار برای مدل inception v3 مقیاس‌دهی کند یا مدل را به صورتی تغییر دهد که کار بزرگ‌نمایی را انجام دهد. ابتدا، تصاویر را می‌توان بارگذاری و مخلوط کرد تا اطمینان حاصل شود که هر بخش یک مجموعه از کلاس‌ها را پوشش می‌دهد.

1...
2# load cifar10 images
3(images, _), (_, _) = cifar10.load_data()
4# shuffle images
5shuffle(images)

سپس، نیاز به راهی برای مقیاس‌دهی به تصاویر است. از کتابخانه «سایکیت-ایمیج» (Scikit-Image) برای تغییر اندازه آرایه نام‌پای برای مقادیر پیکسل‌ها به اندازه مورد انتظار، استفاده می‌شود. تابع scale_images()‎ که در زیر آمده است، این کار را پیاده‌سازی می‌کند.

1# scale an array of images to a new size
2def scale_images(images, new_shape):
3	images_list = list()
4	for image in images:
5		# resize with nearest neighbor interpolation
6		new_image = resize(image, new_shape, 0)
7		# store
8		images_list.append(new_image)
9	return asarray(images_list)

شایان توجه است که کاربر ممکن است کتابخانه «سایکیت‌لرن» (Scikit-Learn) را در صورتی که پیش از این نصب نشده باشد، نصب کند. این کار با استفاده از دستور زیر قابل انجام است. سپس، می‌توان تعداد دسته‌ها را شمرد، یک زیرمجموعه از تصاویر را انتخاب کرد، آن‌ها را مقیاس و پیش‌پردازش کرد و از آن‌ها برای پیش‌بینی احتمال‌های کلاس شرطی استفاده کرد.

1...
2# retrieve images
3ix_start, ix_end = i * n_part, (i+1) * n_part
4subset = images[ix_start:ix_end]
5# convert from uint8 to float32
6subset = subset.astype('float32')
7# scale images to the required size
8subset = scale_images(subset, (299,299,3))
9# pre-process images, scale to [-1,1]
10subset = preprocess_input(subset)
11# predict p(y|x)
12p_yx = model.predict(subset)

سایر محاسبات لازم برای امتیاز ادراکی، مشابه موارد پیشین است. با آزمودن همه این موارد در کنار هم، مثال کامل برای محاسبه امتیاز ادراکی روی مجموعه داده CIFAR واقعی، در زیر آمده است. بر اساس محاسبات مشابهی که در مقاله امتیاز ادراکی پایه گزارش شده است، انتظار می‌رود که امتیاز گزارش شده روی این مجموعه داده، تقریبا ۱۱ باشد. به طور جالبی، بهترین امتیاز ادراکی برای CIFAR-10 با تصاویر تولید شده، نزدیک به 8.8 برای تصاویر تولید شده با یک GAN در حال رشد مترقی است.

1# calculate inception score for cifar-10 in Keras
2from math import floor
3from numpy import ones
4from numpy import expand_dims
5from numpy import log
6from numpy import mean
7from numpy import std
8from numpy import exp
9from numpy.random import shuffle
10from keras.applications.inception_v3 import InceptionV3
11from keras.applications.inception_v3 import preprocess_input
12from keras.datasets import cifar10
13from skimage.transform import resize
14from numpy import asarray
15 
16# scale an array of images to a new size
17def scale_images(images, new_shape):
18	images_list = list()
19	for image in images:
20		# resize with nearest neighbor interpolation
21		new_image = resize(image, new_shape, 0)
22		# store
23		images_list.append(new_image)
24	return asarray(images_list)
25 
26# assumes images have any shape and pixels in [0,255]
27def calculate_inception_score(images, n_split=10, eps=1E-16):
28	# load inception v3 model
29	model = InceptionV3()
30	# enumerate splits of images/predictions
31	scores = list()
32	n_part = floor(images.shape[0] / n_split)
33	for i in range(n_split):
34		# retrieve images
35		ix_start, ix_end = i * n_part, (i+1) * n_part
36		subset = images[ix_start:ix_end]
37		# convert from uint8 to float32
38		subset = subset.astype('float32')
39		# scale images to the required size
40		subset = scale_images(subset, (299,299,3))
41		# pre-process images, scale to [-1,1]
42		subset = preprocess_input(subset)
43		# predict p(y|x)
44		p_yx = model.predict(subset)
45		# calculate p(y)
46		p_y = expand_dims(p_yx.mean(axis=0), 0)
47		# calculate KL divergence using log probabilities
48		kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps))
49		# sum over classes
50		sum_kl_d = kl_d.sum(axis=1)
51		# average over images
52		avg_kl_d = mean(sum_kl_d)
53		# undo the log
54		is_score = exp(avg_kl_d)
55		# store
56		scores.append(is_score)
57	# average across images
58	is_avg, is_std = mean(scores), std(scores)
59	return is_avg, is_std
60 
61# load cifar10 images
62(images, _), (_, _) = cifar10.load_data()
63# shuffle images
64shuffle(images)
65print('loaded', images.shape)
66# calculate inception score
67is_avg, is_std = calculate_inception_score(images)
68print('score', is_avg, is_std)

با اجرای مثال بالا، مجموعه داده بارگذاری و مدل آماده می‌شود. همچنین، امتیاز ادراکی روی مجموعه داده تست CIFAR-10 محاسبه می‌شود. می‌توان مشاهده کرد که امتیاز 11.3 است که بسیار نزدیک به انتظار مورد انتظار 11.24 است.

تذکر: اولین باری که مجموعه داده CIFAR-10 مورد استفاده قرار بگیرد، کرس تصاویر را در قالب فشرده شده محاسبه و آن‌ها را در پوشه /keras/datasets./~ ذخیره می‌کند. دانلود در حدود ۱۶۱ مگابایت است و ممکن است بر مبنای سرعت اینترنت، دقایقی طول بکشد.

1loaded (50000, 32, 32, 3)
2score 11.317895 0.14821531

مشکلات موجود پیرامون امتیاز ادراکی

امتیاز ادراکی مفید است، اما عالی نیست. به طور کلی، امتیاز ادراکی برای تصاویر تولید شده از یک شی شناخته شده برای مدل مفید است تا احتمال کلاس شرطی محاسبه شود. در این شرایط، به دلیل آنکه مدل ادراکی V3 استفاده شده است، این یعنی برای ۱,۰۰۰ نوع شی استفاده شده در مجموعه داده  ILSVRC 2012 [+] مفید است. این تعداد کلاس بسیار زیاد است، اما همه شی‌هایی که ممکن است برای کاربر interest داشته باشند نیست. می‌توان لیست کامل کلاس‌ها را از اینجا [+] مشاهده کرد.

همچنین، نیازمند آن است که تصاویر مربعی و دارای سایز نسبتا کوچکی در حدود 300×300 پیکسل باشند و شامل هر مقایسی است که برای بردن تصاویر مورد نظر به آن سایز نیاز می‌شود. یک امتیاز خوب، نیاز به داشتن توزیع خوبی از تصاویر تولید شده در سراسر اشیای پشتیبانی شده توسط مدل است و به یک عدد از نمونه‌ها برای هر کلاس نیاز دارد. این امر می‌تواند کنترل این موضوع برای بسیاری از مدل‌های GAN که کنترل برای انواع اشیای تولید شده ارائه نمی‌کنند، ممکن است دشوار باشد.

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *