Farbod Shahinfar
Farbod Shahinfar
خواندن ۹ دقیقه·۵ سال پیش

شبکه عصبی Kohonen

خلاصه مطلب

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

مقدمات

مدل شبکه عصبی Kohonen یک شبکه عصبی مصنوعی است برای ایجاد SOFM یاSelf Organizing Feature Map. یادگیری این شبکه به صورت بدون ناظر (unsupervised) صورت می‌گیرد. این شبکه برای دسته‌بند ورودی‌ها به صورت خودکار استفاده می‌شود. حاصل این شبکه معمولا یک نمایش گسسته از اطلاعات (map) است که معمولا ابعادی کوچک‌تر از ابعاد ورودی دارد.

از کاربرد‌های این شبکه می‌توان به clustering، space approximation و data visualization نام برد.

ساختار مدل  kohonen. منبع عکس
ساختار مدل kohonen. منبع عکس

ساختار شبکه‌های kohonen، علاوه بر تعداد نورون استفاده شده در شبکه، دارای پارامتر ابعاد نقشه هم می‌باشد (برای مثال شکل بالا یک نگاشت از یک فضای n بعدی به یک فضای دو بعدی است). در این مدل ورودی مدل به تمام نورون‌ها متصل است. هر کدام از این اتصالات دارای وزن می‌باشد. پس هر نوران در این شبکه دارای یک بردار وزن است که اندازه آن برابر با اندازه بردار ورودی است. در نتیجه‌ی فرآیند یادگیری مقدار این وزن‌ها تغییر پیدا می‌کند به طوری که خروجی به مقدار ورودی نزدیک‌تر گردد. پس از یادگیری، شبکه بدست آمده اطلاعات پراکندگی داده‌های استفاده شده در آموزش شبکه را مدل می‌کند (مانند شکل زیر).

عکس از ویکیپیدیا
عکس از ویکیپیدیا

در این مدل نورون‌های همسایه با یک دیگر در ارتباط هستند. همان طور که گفته شده این مدل برای تشکیل یک feature map بدون ناظر از ورودی استفاده می‌شود. در این شبکه تلاش می‌شود ورودی‌هایی که به یک دیگر نزدیکتر هستند در map بدست آمده در همسایگی هم قرار گیرند.

فرآیند یادگیری

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

۱. مقدار دهی اولیه

۲. رقابت

۳. همکاری

۴. تطبیق

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

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

رقابت

در هر iteration با معرفی یکی از اطلاعات موجود در دادگان آموزش به مدل، نورونی که کوتاه‌ترین فاصله را از آن ورودی دارد انتخاب می‌شود. به این نورون اصطلاحا BMU (Best Matching Unit) گفته می‌شود. این فاصله همان فاصله اقلیدسی میان بردار وزن نورون و اطلاعات ورودی است. در رابطه زیر x مقدار بردار ورودی است و w_i مقدار بردار وزن برای نورون iام است.

همکاری

در این فرآیند یک تابع همسایگی تعریف می‌شود که قصد آن تعیین میزان تاثیر گذاری مرحله تطابق برروی همسایگان BMU است. به همین دلیل حاصل این تابع مقداری در بازه [0,1] است. هدف این تابع این است که باعث شود همسایگان یک نورون ویژگی‌های نزدیک به یک دیگر را مدل کنند.

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

یکی از پارامتر‌های مهم این تابع شعاع همسایگی است. این شعاع باید مشخص کند که تا چه فاصله‌ای از BMU این تغییرات باید اعمال گردد (پارامتر ورودی تابع همسایگی فاصله از BMU است). یکی از توابعی که مناسب این هدف است تابع گوسی است. در تابع گوسی شعاع همسایگی را می‌توان معادل واریانس در نظر گرفت.

یکی از نکاتی که در آموزش شبکه‌های kohonen مطرح می‌شود این است که شعاع همسایگی در ابتدای فرآیند بزرگ در نظر گرفته شود به صورتی که تمام نورون‌های دیگر را تحت تاثیر قرار دهد چرا که وزن‌های شبکه به مقدار نهایی خود نزدیک نیستند. سپس با گذشت هر epoch این شعاع کاهش یابد تا نورون‌های کمتری را تحت پوشش قرار دهد.

تطبیق

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

استفاده از مدل آموزش دیده

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

یک نمونه از این شبکه

در ادامه این مطلب یک شبکه عصبی kohonen را پیاده سازی می‌کنیم که رنگ‌های موجود در یک عکس را دسته بندی می‌کند.

‌هدف این شبکه این است که مقدار RGB تک تک پیکسل‌های یک عکس را به عنوان داده آموزشی به این شبکه بدهیم و در نهایت یک نقشه از رنگ‌های استفاده شده در این عکس بدست بیاوریم. (به عکس‌های زیر توجه کنید.)

عکس ورود
عکس ورود
عکس خروجی
عکس خروجی

برای پیاده سازی این شبکه از زبان برنامه نویسی python استفاده کرده‌ایم. و فقط از ماژول‌های زیر استفاده کرده‌ایم. شما می‌توانید این شبکه را با هر زبان دلخواهی پیاده کنید. دلیل استفاده از پایتون فقط به دلیل در دسترس بودن این زبان برای من بوده است.

ماژول PIL برای ذخیره سازی عکس‌های ایجاد شده استفاده شده است و نقش مهمی در برنامه ندارد.

اطلاعات شبکه را در آرایه‌های کتابخانه  numpy ذخیره کرده‌ایم.

import numpy as np from random import randrange from PIL import Image

ساختار شبکه:

ورودی شبکه یک بردار با اندازه سه است که سه مقدار RGB در آن قرار دارد. شبکه را یک نقشه ۲ بعدی با ابعاد ۴۰x۴۰ در نظر می‌گیریم (یعنی ۱۶۰۰ نورون).

قدم اول ایجاد یک عکس تصادفی:

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

def generate_random_color_image(image_shape=(40,40,3)): rnd_colors = np.zeros(image_shape, dtype='uint8') for i in range(image_shape[0]): for j in range(image_shape[1]): for k in range(3): v = randrange(0, 256) rnd_colors[i][j][k] = v return rnd_colors

خروجی تابع بالا یک آرایه چند بعدی است که می‌توانیم با دستورات زیر در یک فایل ذخیره کنیم.

dataset = generate_random_color_image() img = Image.fromarray(dataset, 'RGB') img.save('random.png')

پیاده سازی شبکه:

همان طور که گفتیم اطلاعات شبکه را در یک آرایه چند بعدی ذخیره می‌کنیم. این اطلاعات همان بردار‌های وزن مربوط به هر یک از نورون‌ها است. ابعاد شبکه در متغیر map_shape تعریف شده است. این متغیر یک نقشه ۴۰ در ۴۰ که یک بردار با اندازه ۳ برای هر نورون در نظر گرفته شده است را نشان می‌دهد.

در این پیاده سازی مقدار دهی‌اولیه به صورت تصادفی صورت گرفته است.

map_shape = (40, 40, 3) nodes = np.random.randint(256, size=map_shape).astype(float)

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

for e in range(epochs): print('epoch:', e+1) for i in range(dateshpae[0]): for j in range(dateshpae[1]): # find nearest row = 0 col = 0 min_value = np.linalg.norm(dataset[i][j] - nodes[row][col]) for r in range(map_shape[0]): for c in range(map_shape[1]): dist = np.linalg.norm(dataset[i][j] - nodes[r][c]) if dist < min_value: min_value = dist row = r col = c winner = (row, col)

در ادامه پس از مشخص شدن BMU باید وزن نورون‌ها را بروز رسانی کنیم.

در کد زیر فاصله هر نورون روی نقشه ۲ بعدی از BMU محاسبه شده است و به عنوان ورودی به تابع neighborhood_func داده شده است (تابع همسایگی مورد نظر). علاوه بر فاصله دو نورون شماره epoch هم به تابع همسایگی داده شده است تا به مرور زمان شعاع همسایگی کاهش پیدا کند. (همان طور که در بالا اشاره کرده‌ایم.)

# update weights for node in n: dist = ((winner[0] - node[0]) ** 2 + (winner[1] - node[1]) ** 2) ** 0.5 delta = learning_rate \ * neighborhood_func(dist, e) \ * (dataset[i][j] - nodes[node[0]][node[1]]) new_value = nodes[node[0]][node[1]] + delta nodes[node[0]][node[1]] = new_value

تابع همسایگی به صورت زیر تعریف گشته است. یک تابع گوسی که شعاع آن با افزایش epoch کاهش می‌یابد.

def neighborhood_func(dist, epoch): sigma = 255 * 4 / ((epoch + 1) ** 2) value = np.exp(-(dist * dist) / (2 * sigma)) return value

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

sofm = kohonen(dataset) sofm_img = Image.fromarray(sofm, 'RGB') sofm_img.save('SOFM.png')

شما می‌توانید کد پیاده شده را در اینجا مشاهده کنید.

نتیجه‌گیری

در این نوشتار به معرفی شبکه عصبی Kohonen به صورت خلاصه پرداخته شد. این شبکه، یک شبکه‌ی Self Organizing Feature Map است. ساختار این شبکه مطرح گشت و مراحل مختلف فرآیند یادگیری آن بررسی شد. در ادامه یک مثال از پیاده سازی این شبکه عصبی مصنوعی مطرح گشت. درنهایت امیدوارم که مطالب مفید و مورد استفاده قرار گرفته باشد.

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