یادگیری عمیق (Deep Learning) با پایتون — به زبان ساده

۲۴۰۳ بازدید
آخرین به‌روزرسانی: ۲۴ اردیبهشت ۱۴۰۲
زمان مطالعه: ۷ دقیقه
یادگیری عمیق (Deep Learning) با پایتون — به زبان ساده

در این مطلب، مفهوم یادگیری عمیق و روش پیاده‌سازی آن با زبان برنامه‌نویسی پایتون آموزش داده شده است. دلیل اصلی نهفته در پس «یادگیری عمیق» (Deep Learning) این ایده است که «هوش مصنوعی» (Artificial Intelligence) باید از مغز انسان الهام بگیرد. این چشم‌انداز موجب سربرآوردن مفاهیم «شبکه عصبی» (Neural Network) شده است. مغز انسان دارای میلیاردها «نورون» (neuron) با ده‌ها هزار اتصال میان آن‌ها است. الگوریتم یادگیری عمیق، مغز انسان را در بسیاری از شرایط شبیه‌سازی می‌کند، از همین رو هم مغز و هم مدل‌های یادگیری عمیق دارای گستره وسیعی از واحدهای محاسباتی (نورون‌ها) هستند که به صورت منزوی (ایزوله) فوق‌العاده «هوشمند» (Intelligent) نیستند، اما هنگامی که با یکدیگر تعامل دارند هوشمند می‌شوند.

«جفری اورست هینتون» (Geoffrey Everest Hinton)، دانشمند علوم کامپیوتر متولد بریتانیا است که بیشتر به دلیل پژوهش‌هایی که در زمینه «شبکه‌های عصبی مصنوعی» (Artificial Neural Networks) انجام داده شهرت دارد، او در این رابطه می‌گوید: «من فکر می‌کنم مردم نیاز دارند بدانند که یادگیری عمیق انجام کارها را - در پشت صحنه - بسیار بهتر می‌سازد. یادگیری عمیق در حال حاضر در جست‌و‌جوهای گوگل و جست‌و‌جوی تصاویر مورد استفاده قرار می‌گیرد و به شما این امکان را می‌دهد که عبارتی مانند «آغوش» را جست‌و‌جو کنید.»

نورون‌ها

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

شبکه‌های عصبی مصنوعی چگونه کار می‌کنند؟

یادگیری عمیق دربرگیرنده شبکه‌های عصبی مصنوعی است که روی شبکه‌هایی مشابه با آنچه در مغز انسان وجود دارد مدل شده‌اند.

با جا‌به‌جایی داده در این «مِش مصنوعی» (Artificial Mesh)، هر لایه یک جنبه از داده‌ها را پردازش، دورافتادگی‌ها را فیلتر، موجودیت‌های مشابه را علامت‌گذاری و خروجی نهایی را تولید می‌کند.

یادگیری عمیق

لایه ورودی

«لایه ورودی» (Input layer) شامل نورون‌هایی است که کاری به جز دریافت ورودی‌ها و پاس دادن آن‌ها به دیگر لایه‌ها انجام نمی‌دهند. تعداد لایه‌ها در لایه ورودی باید مساوی «خصیصه‌ها» (attributes) یا «ویژگی‌های» (features) موجود در «مجموعه داده» (dataset) باشد.

لایه خروجی

«لایه خروجی» (Output Layer)، ویژگی پیش‌بینی شده است، این لایه اساسا به نوع مدلی که ساخته می‌شود بستگی دارد.

لایه پنهان

در میان لایه ورودی و خروجی «لایه‌های پنهان» (Hidden Layers) بسته به نوع مدل قرار دارند. لایه‌های پنهان شامل گستره وسیعی از نورون‌ها می‌شوند. نورون‌ها در لایه پنهان، «تبدیل‌ها» (transformations) را پیش از پاس دادن ورودی‌ها روی آن‌ها اعمال می‌کنند. با آموزش دیدن شبکه، وزن‌ها به روز رسانی می‌شوند تا پیش‌بین‌تر باشند.

وزن نورون‌ها

«شبکه‌های عصبی نظارت شده پیش‌خور» (Feedforward supervised neural networks) از جمله اولین و موفق‌ترین الگوریتم‌های یادگیری به شمار می‌آید. به این الگوریتم «شبکه‌های عمیق» (Deep Networks)، «پرسپترون چند لایه» (Multi-layer Perceptron | MLP) یا به صورت ساده‌تر «شبکه‌های عصبی» (Neural Networks) نیز گفته می‌شود و معماری متداول آن با یک لایه پنهان نمایش داده می‌شود. هر نورون با وزنی به نورون دیگر مرتبط می‌شود. شبکه، به منظور تولید یک مقدار خروجی، ورودی را با فعال‌سازی نورون‌ها پردازش می‌کند. به این کار «مسیر رو به جلو» (Forward Pass) در شبکه گفته می‌شود.

شبکه عصبی

تابع فعال‌سازی در یادگیری عمیق

«تابع فعال‌سازی» (Activation Function)، «مجموع ورودی وزن‌دار» را به خروجی نورون نگاشت می‌کند. به این تابع، بدین دلیل تابع فعال‌سازی/انتقال (transfer function) گفته می‌شود که آغازی که در آن نورون فعال می‌شود را کنترل کرده و سیگنال خروجی را قدرت می‌بخشد.

به بیان ریاضی داریم:

$$Y = ∑(weight * input) + bias$$

تابع‌های فعال‌سازی زیادی وجود دارد که در میان آن‌ها «واحد خطی یکسوسازی شده» (Rectified Linear Unit | ReLU)، «تانژانت هذلولوی» (tanh) و «SoftPlus» از پر استفاده‌ترین‌ها هستند. «تقلب‌نامه‌ای» (Cheat Sheet) برای توابع فعال‌سازی در زیر آمده است.

تقلب‌نامه توابع فعال‌سازی
تقلب‌نامه توابع فعال‌سازی

بازگشت به عقب

مقدار پیش‌بینی شده شبکه عصبی با خروجی مورد انتظار مقایسه می‌شود و مقدار خطا با استفاده از تابع محاسبه می‌شود. این خطا بعدا در کل شبکه، یک لایه در واحد زمان، به عقب بازگشت داده می‌شود و وزن‌ها مطابق با مقداری که در خطا مشارکت داشته‌اند به روز رسانی خواهند شد. این ریاضیات هوشمندانه «الگوریتم بازگشت به عقب» (Back-Propagation algorithm) نامیده می‌شود.

این فرآیند برای همه نمونه‌ها در داده‌های آموزش (training data) تکرار خواهد شد. یک دور به روز رسانی شبکه برای مجموعه داده آموزش، «epoch» نامیده می‌شود. یک شبکه ممکن است برای ده‌ها، صدها یا هزاران epoch آموزش ببیند.

epoch در شبکه عصبی

تابع هزینه و گرادیان کاهشی

«تابع هزینه» (Cost Function) سنجه‌ای برای آن است که مشخص شود یک شکبه عصبی برای مجموعه آموزش داده شده و خروجی مورد انتظار «چقدر خوب» عمل کرده است. این تابع همچنین بستگی به خصیصه‌هایی مانند «وزن‌ها» و «سوگیری‌ها» (biases) دارد.

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

تابع هزینه سازگار

به بیان ریاضیاتی، «مجموع مربعات خطاها» (Sum of Squared Errors | SSE)، به صورت زیر محاسبه می‌شود:

$$J(W) =\frac{1}{2}$$

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

$$Δw_j = \frac{1}{2}∑\limits_{i}((target)^i - (output)^1)^2$$

که در آن Δw یک بردار شامل وزن‌های به روز رسانی شده برای هر ضریب وزن w است که به صورت زیر محاسبه می‌شود:

$$Δw_j = \frac{1}{2}∑\limits_{i}((target)^i - (output)^i)x_j^{(i)}$$

گرادیان کاهشی تا هنگامی که مشتق به کمینه خطا برسد محاسبه می‌شود و هر گام با سراشیبیِ شیب تعیین میشود (گرادیان).

گرادیان کاهشی
بیان گرافیکی مطالب بالا، با توجه به تابع هزینه با ضریب تک

پرسپترون چند لایه (انتشار رو به جلو)

این کلاس از شبکه‌ها شامل لایه‌های چندگانه از نورون‌ها، معمولا به صورت «پیش‌خور» (feed-forward) است (به صورت رو به جلو حرکت می‌کند). هر نورون در یک لایه دارای اتصالاتی به نورون‌های موجود در لایه‌های متعاقب است. در بسیاری از کاربردها، واحدهای این شبکه‌ها یک تابع سیگموئید یا ReLU (تابع واحد خطی یکسوسازی شده | Rectified Linear Activation) را به عنوان یک تابع فعال‌سازی اعمال می‌کنند.

اکنون، مساله پیدا کردن تعداد تراکنش‌ها برای حساب‌های داده شده و اعضای خانواده به عنوان ورودی مفروض است. برای حل این مساله، ابتدا نیاز به آغاز کار با ساخت یک «شبکه عصبی انتشار رو به جلو» (forward propagation neural network) است. لایه ورودی تعداد اعضای خانواده و حساب‌ها است. یک لایه پنهان وجود دارد و لایه خروجی تعداد تراکنش‌ها محسوب می‌شود. وزن‌های داده شده چنانکه در تصویر زیر نشان داده شده، لایه ورودی تا لایه پنهان با تعداد اعضای خانواده ۲ و ۳ حساب به عنوان ورودی است. اکنون، مقادیر لایه پنهان (i,j) و لایه خروجی (k) با استفاده از انتشار رو به جلو با انجام گام‌هایی که در ادامه آمده محاسبه می‌شوند.

فرآیند

  1. ضرب (فرآیند افزودن)
  2. ضرب داخلی (ورودی‌ها × وزن‌ها)
  3. انتشار پیش‌رو برای یک نقطه داده در هر زمان
  4. خروجی، پیش‌بینی برای آن نقطه داده در هر زمان است.

انتشار رو به جلو

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

i = (2 * 1) + (3 * 1)

→ i = 5

به طور مشابه داریم:

j = (2 * -1) + (3 * 1)

→ j = 1

K = (5 * 2) + (1 * -1)

→ k = 9

انتشار رو به جلو

حل مساله پرسپترون چند لایه در پایتون

1import numpy as np
2
3print("Enter the two values for input layers")
4
5print('a = ')
6a = int(input())
7# 2
8print('b = ')
9b = int(input())
10# 3
11
12input_data = np.array([a, b])
13
14weights = {
15    'node_0': np.array([1, 1]),
16    'node_1': np.array([-1, 1]),
17    'output_node': np.array([2, -1])
18}
19
20node_0_value = (input_data * weights['node_0']).sum()
21# 2 * 1 +3 * 1 = 5
22print('node 0_hidden: {}'.format(node_0_value))
23
24node_1_value = (input_data * weights['node_1']).sum()
25# 2 * -1 + 3 * 1 = 1
26print('node_1_hidden: {}'.format(node_1_value))
27
28hidden_layer_values = np.array([node_0_value, node_1_value])
29
30output_layer = (hidden_layer_values * weights['output_node']).sum()
31
32print("output layer : {}".format(output_layer))
$python dl_multilayer_perceptron.py
Enter the two values for input layers
a =
3
b =
4
node 0_hidden: 7
node_1_hidden: 1
output layer : 13

استفاده از تابع فعال‌سازی

برای شبکه عصبی به منظور کسب بیشینه قدرت پیش‌بینی نیاز به اعمال یک تابع فعال‌سازی برای لایه‌های پنهان است. این تابع غیرخطی بودن‌ها را ثبت می‌کند.

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

تابع واحد یکسوسازی شده (ReLU)

1import numpy as np
2
3print("Enter the two values for input layers")
4
5print('a = ')
6a = int(input())
7# 2
8print('b = ')
9b = int(input())
10
11weights = {
12    'node_0': np.array([2, 4]),
13    'node_1': np.array([[4, -5]]),
14    'output_node': np.array([2, 7])
15}
16
17input_data = np.array([a, b])
18
19
20def relu(input):
21    # Rectified Linear Activation
22    output = max(input, 0)
23    return(output)
24
25
26node_0_input = (input_data * weights['node_0']).sum()
27node_0_output = relu(node_0_input)
28
29node_1_input = (input_data * weights['node_1']).sum()
30node_1_output = relu(node_1_input)
31
32hidden_layer_outputs = np.array([node_0_output, node_1_output])
33
34model_output = (hidden_layer_outputs * weights['output_node']).sum()
35
36print(model_output)
$python dl_fp_activation.py
Enter the two values for input layers
a =
3
b =
4
44

توسعه اولین شبکه عصبی با Keras

«کِراس» (Keras) یک رابط برنامه‌نویسی نرم‌افزار کاربردی (Application Programming Interface | API) سطح بالای شبکه عصبی نوشته شده در پایتون و قادر به اجرا بر فراز کتابخانه‌های «تِنسورفلو» (TensorFlow) (+)، (جعبه ابزار شناختی مایکروسافت) (CNTK | Microsoft Cognitive Toolkit) (+) یا «ثینو» (Theano) (+) است.

برای نصب Keras روی دستگاه با استفاده از PIP، باید دستور زیر را اجرا کرد.

1sudo pip install keras

گام‌هایی برای پیاده‌سازی برنامه یادگیری عمیق در Keras

  1. بارگذاری داده‌ها
  2. تعریف کردن مدل
  3. کامپایل کردن مدل
  4. برازش (Fit) مدل
  5. ارزیابی مدل
  6. ترکیب کلیه گام‌ها

توسعه مدل Keras ایجاد شده

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

تا این لحظه مدل تعریف و مجموعه آن به منظور داشتن محاسبات موثر کامپایل شده است. اکنون زمان آن فرا رسیده تا مدل روی داده PIMA اجرا شود. می‌توان مدل را بر مبنای داده‌ها با فراخوانی تابع ()fit آموزش و یا برازش داد. در ادامه، کد برنامه مذکور در KERAS آمده است.

1# Importing Keras Sequential Model
2from keras.models import Sequential
3from keras.layers import Dense
4import numpy
5
6# Initializing the seed value to a integer.
7seed = 7
8
9numpy.random.seed(seed)
10
11# Loading the data set (PIMA Diabetes Dataset)
12dataset = numpy.loadtxt('datasets/pima-indians-diabetes.csv', delimiter=",")
13
14# Loading the input values to X and Label values Y using slicing.
15X = dataset[:, 0:8]
16Y = dataset[:, 8]
17
18# Initializing the Sequential model from KERAS.
19model = Sequential()
20
21# Creating a 16 neuron hidden layer with Linear Rectified activation function.
22model.add(Dense(16, input_dim=8, init='uniform', activation='relu'))
23
24# Creating a 8 neuron hidden layer.
25model.add(Dense(8, init='uniform', activation='relu'))
26
27# Adding a output layer.
28model.add(Dense(1, init='uniform', activation='sigmoid'))
29
30
31
32# Compiling the model
33model.compile(loss='binary_crossentropy',
34              optimizer='adam', metrics=['accuracy'])
35# Fitting the model
36model.fit(X, Y, nb_epoch=150, batch_size=10)
37
38scores = model.evaluate(X, Y)
39
40print("%s: %.2f%%" % (model.metrics_names[1], scores[1] * 100))
$python keras_pima.py
768/768 [==============================] - 0s - loss: 0.6776 - acc: 0.6510
Epoch 2/150
768/768 [==============================] - 0s - loss: 0.6535 - acc: 0.6510
Epoch 3/150
768/768 [==============================] - 0s - loss: 0.6378 - acc: 0.6510
.
.
.
.
.
Epoch 149/150
768/768 [==============================] - 0s - loss: 0.4666 - acc: 0.7786
Epoch 150/150
768/768 [==============================] - 0s - loss: 0.4634 - acc: 0.773432/768 
[>.............................] - ETA: 0sacc: 77.73%

شبکه عصبی تا ۱۵۰ epoch آموزش داده می‌شود و مقدار صحیح را باز می‌گرداند.

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

^^

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

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