امتیاز ادراکی (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))) است.
نیازی به ترجمه محاسبات امتیاز ادراکی نیست. خوشبختانه، نویسندگان مقاله کد منبع این مورد را نیز منتشر کردهاند که حاوی پیادهسازی امتیاز ادراکی نیز هست.
کد پیادهسازی امتیاز ادراکی
# Code derived from tensorflow/tensorflow/models/image/imagenet/classify_image.py from __future__ import absolute_import from __future__ import division from __future__ import print_function import os.path import sys import tarfile import numpy as np from six.moves import urllib import tensorflow as tf import glob import scipy.misc import math import sys MODEL_DIR = '/tmp/imagenet' DATA_URL = 'http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz' softmax = None # Call this function with list of images. Each of elements should be a # numpy array with values ranging from 0 to 255. def get_inception_score(images, splits=10): assert(type(images) == list) assert(type(images[0]) == np.ndarray) assert(len(images[0].shape) == 3) assert(np.max(images[0]) > 10) assert(np.min(images[0]) >= 0.0) inps = [] for img in images: img = img.astype(np.float32) inps.append(np.expand_dims(img, 0)) bs = 1 with tf.Session() as sess: preds = [] n_batches = int(math.ceil(float(len(inps)) / float(bs))) for i in range(n_batches): sys.stdout.write(".") sys.stdout.flush() inp = inps[(i * bs):min((i + 1) * bs, len(inps))] inp = np.concatenate(inp, 0) pred = sess.run(softmax, {'ExpandDims:0': inp}) preds.append(pred) preds = np.concatenate(preds, 0) scores = [] for i in range(splits): part = preds[(i * preds.shape[0] // splits):((i + 1) * preds.shape[0] // splits), :] kl = part * (np.log(part) - np.log(np.expand_dims(np.mean(part, 0), 0))) kl = np.mean(np.sum(kl, 1)) scores.append(np.exp(kl)) return np.mean(scores), np.std(scores) # This function is called automatically. def _init_inception(): global softmax if not os.path.exists(MODEL_DIR): os.makedirs(MODEL_DIR) filename = DATA_URL.split('/')[-1] filepath = os.path.join(MODEL_DIR, filename) if not os.path.exists(filepath): def _progress(count, block_size, total_size): sys.stdout.write('\r>> Downloading %s %.1f%%' % ( filename, float(count * block_size) / float(total_size) * 100.0)) sys.stdout.flush() filepath, _ = urllib.request.urlretrieve(DATA_URL, filepath, _progress) print() statinfo = os.stat(filepath) print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.') tarfile.open(filepath, 'r:gz').extractall(MODEL_DIR) with tf.gfile.FastGFile(os.path.join( MODEL_DIR, 'classify_image_graph_def.pb'), 'rb') as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) _ = tf.import_graph_def(graph_def, name='') # Works with an arbitrary minibatch size. with tf.Session() as sess: pool3 = sess.graph.get_tensor_by_name('pool_3:0') ops = pool3.graph.get_operations() for op_idx, op in enumerate(ops): for o in op.outputs: shape = o.get_shape() shape = [s.value for s in shape] new_shape = [] for j, s in enumerate(shape): if s == 1 and j == 0: new_shape.append(None) else: new_shape.append(s) o.set_shape(tf.TensorShape(new_shape)) w = sess.graph.get_operation_by_name("softmax/logits/MatMul").inputs[1] logits = tf.matmul(tf.squeeze(pool3, [1, 2]), w) softmax = tf.nn.softmax(logits) if softmax is None: _init_inception()
در محاسبه امتیاز، تعداد زیادی از تصاویر برای رنجی از اشیا، مثلا ۵۰,۰۰۰ محاسبه میشوند. تصاویر به ۱۰ دسته، برای مثال ۵,۰۰۰ تصویر به ازای هر گروه، تقسیم میشوند و امتیاز ادراکی روی هر گروه از تصاویر محاسبه میشود. سپس، انحراف میانگین و استاندارد از امتیاز، محاسبه میشود. محاسبه امتیاز ادراکی روی گروهی از تصاویر، شامل استفاده از مدل inception v3 برای محاسبه احتمال شرطی برای هر تصویر میشود ((p(y). سپس، واگرایی KL برای هر تصویر به صورتی که در رابطه زیر آمده است، محاسبه میشود.
KL divergence = p(y|x) * (log(p(y|x)) – log(p(y)))
در رابطه بالا، احتمال شرطی در لگاریتم احتمال شرطی ضرب شده و لگاریتم احتمال حاشیهای از آن تفریق شده است. سپس، واگرایی KL برای همه تصاویر محاسبه شده و میانگین آن برای همه کلاسها محاسبه میشود و توان دو نتیجه برای دادن نتیجه نهایی محاسبه میشود. این، پیادهسازی رسمی امتیاز ادراکی رسمی را تعریف میکند که در اغلب مقالات از آن استفاده شده است. هر چند، تنوعی در روش محاسبه این امتیاز وجود دارد و در برخی از مقالات، از روشهای دیگری برای محاسبه آن استفاده شده است.
روش پیادهسازی امتیاز ادراکی با نامپای
پیادهسازی محاسبه امتیاز ادراکی در پایتون با استفاده از آرایههای نامپای (NumPy) کار سادهای است. ابتدا، تابعی تعریف میشود که مجموعهای از احتمالهای شرطی را دریافت و امتیاز ادراکی را محاسبه میکند. تابع calculate_inception_score() که در ادامه آمده است، این روال را پیادهسازی میکند. یک تغییر کوچک، تعریف یک اپسیلون (یک عدد کوچک نزدیک به صفر) برای هنگامی است که احتمالهای لگاریتمی محاسبه میشوند. این کار برای جلوگیری از مشکل، در هنگام محاسبه لگاریتم احتمال صفر انجام میشود. این احتمال در عمل مورد نیاز نیست (برای مثال، با دادههای تولید شده واقعی)، اما در اینجا مفید است و اقدام خوبی هنگام کار با احتمالهای لگاریتمی محسوب میشود.
# calculate the inception score for p(y|x) def calculate_inception_score(p_yx, eps=1E-16): # calculate p(y) p_y = expand_dims(p_yx.mean(axis=0), 0) # kl divergence for each image kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps)) # sum over classes sum_kl_d = kl_d.sum(axis=1) # average over images avg_kl_d = mean(sum_kl_d) # undo the logs is_score = exp(avg_kl_d) return is_score
میتوان این تابع را برای محاسبه امتیاز ادراکی برای برخی از احتمالات شرطی تعبیه شده، استفاده کرد. همچنین، میتوان شرایطی را تصور کرد که سه کلاس از تصاویر و یک پیشبینی مطمئن کامل برای هر کلاس برای سه تصویر وجود دارد.
# conditional probabilities for high quality images p_yx = asarray([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])
انتظار میرود که امتیاز ادراکی برای این مثال برابر با 3.0 (یا بسیار نزدیک به آن) باشد. این امر بدین دلیل است که عدد مشابهی از تصاویر برای هر کلاس وجود دارد (یک تصویر برای هر سه کلاس) و هر احتمال شرطی به طور بیشینهای مطمئن است. مثال کامل برای محاسبه امتیاز ادراکی برای این احتمالها در ادامه آمده است.
# calculate inception score in numpy from numpy import asarray from numpy import expand_dims from numpy import log from numpy import mean from numpy import exp # calculate the inception score for p(y|x) def calculate_inception_score(p_yx, eps=1E-16): # calculate p(y) p_y = expand_dims(p_yx.mean(axis=0), 0) # kl divergence for each image kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps)) # sum over classes sum_kl_d = kl_d.sum(axis=1) # average over images avg_kl_d = mean(sum_kl_d) # undo the logs is_score = exp(avg_kl_d) return is_score # conditional probabilities for high quality images p_yx = asarray([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]) score = calculate_inception_score(p_yx) print(score)
با اجرای مثال بالا، امتیاز ادراکی ۳.۰ (یا عددی بسیار نزدیک به آن) در خروجی چاپ میشود.
2.999999999999999
میتوان بدترین شرایط را نیز آزمود. این، همان جایی است که همچنان عدد مشابهی از تصاویر برای هر کلاس وجود دارد (یکی برای هر یک از این سه کلاس)، اما اشیا ناشناخته هستند، و یک توزیع احتمال پیشبینی شده یکنواخت برای هر کلاس به دست میدهد.
# conditional probabilities for low quality images p_yx = asarray([[0.33, 0.33, 0.33], [0.33, 0.33, 0.33], [0.33, 0.33, 0.33]]) score = calculate_inception_score(p_yx) print(score)
در این شرایط، انتظار میرود که امتیاز ادراکی بدترین حالت ممکن باشد که در آن هیچ تفاوتی بین توزیعهای شرطی و حاشیهای نباشد؛ برای مثال، امتیاز ادراکی 1.0. با یکپارچه کردن همه این موارد در کنار هم، مثال کامل به صورت زیر خواهد بود.
# calculate inception score in numpy from numpy import asarray from numpy import expand_dims from numpy import log from numpy import mean from numpy import exp # calculate the inception score for p(y|x) def calculate_inception_score(p_yx, eps=1E-16): # calculate p(y) p_y = expand_dims(p_yx.mean(axis=0), 0) # kl divergence for each image kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps)) # sum over classes sum_kl_d = kl_d.sum(axis=1) # average over images avg_kl_d = mean(sum_kl_d) # undo the logs is_score = exp(avg_kl_d) return is_score # conditional probabilities for low quality images p_yx = asarray([[0.33, 0.33, 0.33], [0.33, 0.33, 0.33], [0.33, 0.33, 0.33]]) score = calculate_inception_score(p_yx) print(score)
با اجرای مثال بالا، امتیاز ادراکی ۱.۰ حاصل میشود.
1.0
مخاطبان میتوانند در صورت تمایل، این روش محاسبه امتیاز ادراکی را مورد بررسی بیشتر قرار دهند و آزمونهای آسیبشناسی را روی آن انجام دهند.
روش پیادهسازی امتیاز ادراکی با کرس
اکنون که روش محاسبه امتیاز ادراکی و چگونگی پیادهسازی آن در نامپای مشخص است، میتوان پیادهسازی را در کرس توسعه داد. این کار شامل استفاده از مدل Inception v3 برای دستهبندی تصاویر و محاسبه میانگین امتیاز در بخشهای مختلف مجموعه تصاویر است. ابتدا، میتوان مدل Inception v3 را به طور مستقیم در Keras بارگذاری کرد.
... # load inception v3 model model = InceptionV3()
مدل، انتظار دارد که تصاویر رنگی و دارای ابعاد 299×299 پیکسل باشند. علاوه بر آن، مقادیر پیکسل باید به شیوهای مشابه با روش مورد استفاده برای دادههای آموزش، مقایسدهی شوند. این مورد با تبدیل مقادیر پیکسلها از عدد صحیح به مقادیر اعشاری و سپس، فراخوانی تابع preprocess_input() برای تصاویر، قابل حصول است.
... # convert from uint8 to float32 processed = images.astype('float32') # pre-process raw images for inception v3 model processed = preprocess_input(processed)
سپس، احتمال شرطی برای هر یک از ۱,۰۰۰ دسته تصویر، ممکن است برای این تصاویر پیشبینی شود.
... # predict class probabilities for images yhat = model.predict(images)
امتیاز ادراکی به طور مستقیم و به روشی که در بخش پیشین انجام شد، روی آرایه نامپای از احتمالها قابل محاسبه است. پیش از انجام این کار، باید احتمالهای شرطی را در گروههایی تقسیم کرد که به وسیله آرگومان n_split کنترل میشود و روی مقدار پیشفرض ۱۰ که در مقاله اصلی نیز استفاده شده بود، تنظیم میشود.
... n_part = floor(images.shape[0] / n_split)
میتوان احتمال شرطی را در بلوکهایی از تصاویر یا پیشبینیهای n_part برشمرد و امتیاز ادراکی را محاسبه کرد.
... # retrieve p(y|x) ix_start, ix_end = i * n_part, (i+1) * n_part p_yx = yhat[ix_start:ix_end]
پس از محاسبه امتیاز ادراکی برای هر بخش از احتمالهای شرطی، میتوان امتیاز ادراکی میانگین و انحراف معیار را محاسبه کرد.
... # average across images is_avg, is_std = mean(scores), std(scores)
با کنار هم قرار دادن همه این موارد، تابع calculate_inception_score() که در ادامه آمده است، یک آرایه از تصاویر را با سایز و مقدار پیکسل مورد انتظار در [0,255] میگیرد و امتیاز ادراکی انحراف معیار و میانگین را با استفاده از مدل inception v3 در کرس محاسبه میکند.
# assumes images have the shape 299x299x3, pixels in [0,255] def calculate_inception_score(images, n_split=10, eps=1E-16): # load inception v3 model model = InceptionV3() # convert from uint8 to float32 processed = images.astype('float32') # pre-process raw images for inception v3 model processed = preprocess_input(processed) # predict class probabilities for images yhat = model.predict(processed) # enumerate splits of images/predictions scores = list() n_part = floor(images.shape[0] / n_split) for i in range(n_split): # retrieve p(y|x) ix_start, ix_end = i * n_part, i * n_part + n_part p_yx = yhat[ix_start:ix_end] # calculate p(y) p_y = expand_dims(p_yx.mean(axis=0), 0) # calculate KL divergence using log probabilities kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps)) # sum over classes sum_kl_d = kl_d.sum(axis=1) # average over images avg_kl_d = mean(sum_kl_d) # undo the log is_score = exp(avg_kl_d) # store scores.append(is_score) # average across images is_avg, is_std = mean(scores), std(scores) return is_avg, is_std
این تابع را میتوان با ۵۰ تصویر مصنوعی با مقدار 1.0 برای همه پیکسلها، آزمود.
... # pretend to load images images = ones((50, 299, 299, 3)) print('loaded', images.shape)
این مورد میتواند امتیاز را برای هر گروه پنجتایی از تصاویر محاسبه کند. کیفیت پایین حاکی از آن است که امتیاز ادراکی 1.0 در خروجی حاصل خواهد شد. مثال کامل، در ادامه آورده شده است.
# calculate inception score with Keras from math import floor from numpy import ones from numpy import expand_dims from numpy import log from numpy import mean from numpy import std from numpy import exp from keras.applications.inception_v3 import InceptionV3 from keras.applications.inception_v3 import preprocess_input # assumes images have the shape 299x299x3, pixels in [0,255] def calculate_inception_score(images, n_split=10, eps=1E-16): # load inception v3 model model = InceptionV3() # convert from uint8 to float32 processed = images.astype('float32') # pre-process raw images for inception v3 model processed = preprocess_input(processed) # predict class probabilities for images yhat = model.predict(processed) # enumerate splits of images/predictions scores = list() n_part = floor(images.shape[0] / n_split) for i in range(n_split): # retrieve p(y|x) ix_start, ix_end = i * n_part, i * n_part + n_part p_yx = yhat[ix_start:ix_end] # calculate p(y) p_y = expand_dims(p_yx.mean(axis=0), 0) # calculate KL divergence using log probabilities kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps)) # sum over classes sum_kl_d = kl_d.sum(axis=1) # average over images avg_kl_d = mean(sum_kl_d) # undo the log is_score = exp(avg_kl_d) # store scores.append(is_score) # average across images is_avg, is_std = mean(scores), std(scores) return is_avg, is_std # pretend to load images images = ones((50, 299, 299, 3)) print('loaded', images.shape) # calculate inception score is_avg, is_std = calculate_inception_score(images) print('score', is_avg, is_std)
پس از اجرای مثال بالا، ابتدا ۵۰ تصویر جعلی تعریف میشوند؛ سپس، امتیاز ادراکی برای هر دسته محاسبه میشود و امتیاز ادراکی مورد انتظار 1.0 و انحراف معیار 0.0 ارائه میشود.
نکته: اولین باری که مدل InceptionV3 استفاده شده است، کرس، وزنهای مدل را دانلود و آنها را در پوشهkeras/models/ ./~ در ایستگاه کاری کاربر ذخیره میکند. وزنها در حدود ۱۰۰ مگابایت هستند و ممکن است دانلود آنها بسته به سرعت اینترنت کاربر، دقایقی طول بکشد.
loaded (50, 299, 299, 3) score 1.0 0.0
میتوان محاسبه امتیاز ادراکی را روی دادههای واقعی نیز آزمود. «رابط برنامهنویسی کاربردی کرس» (Keras API) امکان دسترسی به مجموعه داده CIFAR-10 را فراهم میکند. این موارد، تصاویر رنگی با سایز کوچک و 32×32 پیکسل هستند. ابتدا، میتوان تصاویر را به گروههایی تقسیم کرد. سپس، تصاویر به ابعاد مورد انتظار 299×299 «بزرگنمایی» (Upsample) میشود؛ مقادیر پیکسلها پیشپردازش میشوند، احتمال کلاس پیشبینی میشود و سپس، امتیاز ادراکی محاسبه میشود. این یک مثال مفید برای محاسبه امتیاز ادراکی روی تصاویر تولید شده خود کاربر است؛ زیرا کاربر باید تصاویر را به اندازه مورد انتظار برای مدل inception v3 مقیاسدهی کند یا مدل را به صورتی تغییر دهد که کار بزرگنمایی را انجام دهد. ابتدا، تصاویر را میتوان بارگذاری و مخلوط کرد تا اطمینان حاصل شود که هر بخش یک مجموعه از کلاسها را پوشش میدهد.
... # load cifar10 images (images, _), (_, _) = cifar10.load_data() # shuffle images shuffle(images)
سپس، نیاز به راهی برای مقیاسدهی به تصاویر است. از کتابخانه «سایکیت-ایمیج» (Scikit-Image) برای تغییر اندازه آرایه نامپای برای مقادیر پیکسلها به اندازه مورد انتظار، استفاده میشود. تابع scale_images() که در زیر آمده است، این کار را پیادهسازی میکند.
# scale an array of images to a new size def scale_images(images, new_shape): images_list = list() for image in images: # resize with nearest neighbor interpolation new_image = resize(image, new_shape, 0) # store images_list.append(new_image) return asarray(images_list)
شایان توجه است که کاربر ممکن است کتابخانه «سایکیتلرن» (Scikit-Learn) را در صورتی که پیش از این نصب نشده باشد، نصب کند. این کار با استفاده از دستور زیر قابل انجام است. سپس، میتوان تعداد دستهها را شمرد، یک زیرمجموعه از تصاویر را انتخاب کرد، آنها را مقیاس و پیشپردازش کرد و از آنها برای پیشبینی احتمالهای کلاس شرطی استفاده کرد.
... # retrieve images ix_start, ix_end = i * n_part, (i+1) * n_part subset = images[ix_start:ix_end] # convert from uint8 to float32 subset = subset.astype('float32') # scale images to the required size subset = scale_images(subset, (299,299,3)) # pre-process images, scale to [-1,1] subset = preprocess_input(subset) # predict p(y|x) p_yx = model.predict(subset)
سایر محاسبات لازم برای امتیاز ادراکی، مشابه موارد پیشین است. با آزمودن همه این موارد در کنار هم، مثال کامل برای محاسبه امتیاز ادراکی روی مجموعه داده CIFAR واقعی، در زیر آمده است. بر اساس محاسبات مشابهی که در مقاله امتیاز ادراکی پایه گزارش شده است، انتظار میرود که امتیاز گزارش شده روی این مجموعه داده، تقریبا ۱۱ باشد. به طور جالبی، بهترین امتیاز ادراکی برای CIFAR-10 با تصاویر تولید شده، نزدیک به 8.8 برای تصاویر تولید شده با یک GAN در حال رشد مترقی است.
# calculate inception score for cifar-10 in Keras from math import floor from numpy import ones from numpy import expand_dims from numpy import log from numpy import mean from numpy import std from numpy import exp from numpy.random import shuffle from keras.applications.inception_v3 import InceptionV3 from keras.applications.inception_v3 import preprocess_input from keras.datasets import cifar10 from skimage.transform import resize from numpy import asarray # scale an array of images to a new size def scale_images(images, new_shape): images_list = list() for image in images: # resize with nearest neighbor interpolation new_image = resize(image, new_shape, 0) # store images_list.append(new_image) return asarray(images_list) # assumes images have any shape and pixels in [0,255] def calculate_inception_score(images, n_split=10, eps=1E-16): # load inception v3 model model = InceptionV3() # enumerate splits of images/predictions scores = list() n_part = floor(images.shape[0] / n_split) for i in range(n_split): # retrieve images ix_start, ix_end = i * n_part, (i+1) * n_part subset = images[ix_start:ix_end] # convert from uint8 to float32 subset = subset.astype('float32') # scale images to the required size subset = scale_images(subset, (299,299,3)) # pre-process images, scale to [-1,1] subset = preprocess_input(subset) # predict p(y|x) p_yx = model.predict(subset) # calculate p(y) p_y = expand_dims(p_yx.mean(axis=0), 0) # calculate KL divergence using log probabilities kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps)) # sum over classes sum_kl_d = kl_d.sum(axis=1) # average over images avg_kl_d = mean(sum_kl_d) # undo the log is_score = exp(avg_kl_d) # store scores.append(is_score) # average across images is_avg, is_std = mean(scores), std(scores) return is_avg, is_std # load cifar10 images (images, _), (_, _) = cifar10.load_data() # shuffle images shuffle(images) print('loaded', images.shape) # calculate inception score is_avg, is_std = calculate_inception_score(images) print('score', is_avg, is_std)
با اجرای مثال بالا، مجموعه داده بارگذاری و مدل آماده میشود. همچنین، امتیاز ادراکی روی مجموعه داده تست CIFAR-10 محاسبه میشود. میتوان مشاهده کرد که امتیاز 11.3 است که بسیار نزدیک به انتظار مورد انتظار 11.24 است.
تذکر: اولین باری که مجموعه داده CIFAR-10 مورد استفاده قرار بگیرد، کرس تصاویر را در قالب فشرده شده محاسبه و آنها را در پوشه /keras/datasets./~ ذخیره میکند. دانلود در حدود ۱۶۱ مگابایت است و ممکن است بر مبنای سرعت اینترنت، دقایقی طول بکشد.
loaded (50000, 32, 32, 3) score 11.317895 0.14821531
مشکلات موجود پیرامون امتیاز ادراکی
امتیاز ادراکی مفید است، اما عالی نیست. به طور کلی، امتیاز ادراکی برای تصاویر تولید شده از یک شی شناخته شده برای مدل مفید است تا احتمال کلاس شرطی محاسبه شود. در این شرایط، به دلیل آنکه مدل ادراکی V3 استفاده شده است، این یعنی برای ۱,۰۰۰ نوع شی استفاده شده در مجموعه داده ILSVRC 2012 [+] مفید است. این تعداد کلاس بسیار زیاد است، اما همه شیهایی که ممکن است برای کاربر interest داشته باشند نیست. میتوان لیست کامل کلاسها را از اینجا [+] مشاهده کرد.
همچنین، نیازمند آن است که تصاویر مربعی و دارای سایز نسبتا کوچکی در حدود 300×300 پیکسل باشند و شامل هر مقایسی است که برای بردن تصاویر مورد نظر به آن سایز نیاز میشود. یک امتیاز خوب، نیاز به داشتن توزیع خوبی از تصاویر تولید شده در سراسر اشیای پشتیبانی شده توسط مدل است و به یک عدد از نمونهها برای هر کلاس نیاز دارد. این امر میتواند کنترل این موضوع برای بسیاری از مدلهای GAN که کنترل برای انواع اشیای تولید شده ارائه نمیکنند، ممکن است دشوار باشد.
اگر نوشته بالا برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای دادهکاوی و یادگیری ماشین
- آموزش دادهکاوی در متلب
- مجموعه آموزشهای هوش مصنوعی
- تشخیص لبخند در چهره — راهنمای کاربردی
- آموزش یادگیری ماشین با مثالهای کاربردی ــ بخش چهارم
- بازشناسی تصویر با Keras و شبکههای عصبی پیچشی — راهنمای کاربردی
- بازشناسی گفتار (Speech Recognition) با پایتون — از صفر تا صد