در درس سی و ششم از آموزش یادگیری ماشین با پایتون می خواهیم به موضوع رگرسیون Softmax با استفاده از Keras بپردازیم.
شروع کار با کراس (Keras)
یادگیری عمیق (Deep Learning)، یکی از شاخههای مهم در حوزه یادگیری ماشین است که توسط کتابخانههای گوناگونی چون ثینو (Theano)، تنسورفلو (TensorFlow)، کافه (Caffe) و اماکسنت (Mxnet) پشتیبانی میشود. کراس (Keras)، که به عنوان یکی از قدرتمندترین و کاربردیترین کتابخانههای پایتون شناخته میشود، بر پایه کتابخانههای معروفی مثل تنسورفلو و Theano بنا شده و برای ساخت مدلهای یادگیری عمیق به کار میرود.
کراس مجموعهای از دادههای آموزشی را فراهم میکند که میتوان برای آموزش و ارزیابی مدلها از آنها استفاده کرد. یکی از این مجموعه دادهها، Fashion MNIST است که در API دادههای tf.keras قرار دارد. این مجموعه شامل ۷۰ هزار تصویر از اقلام مد در ۱۰ دسته مختلف مانند کفش، کیف، تیشرت و غیره است که هر کدام به صورت تصاویر خاکستری ۲۸ در ۲۸ پیکسلی هستند.
رویکرد
ابتدا باید دیتاست اشیاء MNIST را بارگذاری کنیم و سپس از کتابخانه Matplotlib برای مشاهده نمونههایی از دیتاست استفاده میکنیم تا درک بهتری از دیتاست به دست آوریم. پس از آن، با استفاده از API کراس و ساخت یک شبکه عصبی، به طبقهبندی آنها میپردازیم. در نهایت، مدل آموزش دیده خود را روی مجموعه داده تست آزمایش میکنیم تا دقت مدل خود را بررسی کنیم.
پیادهسازی
کد: بارگذاری دادهها
mnist = tf.keras.datasets.fashion_mnist (training_images, training_labels), (test_images, test_labels) = mnist.load_data()
فراخوانی تابع load_data روی این شیء به ما دو مجموعه شامل دو لیست میدهد، که شامل مقادیر آموزشی و آزمایشی برای گرافیکهایی است که شامل اقلام دیتاست و برچسبهای آنها هستند.
کد: درک دادهها
import numpy as np np.set_printoptions(linewidth = 200) import matplotlib.pyplot as plt plt.imshow(training_images[42]) # printing training labels and training images print(training_labels[42]) print(training_images[42])
خروجی:
9 [[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 82 187 26 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 179 240 237 255 240 139 83 64 43 60 54 0 1] [ 0 0 0 0 0 0 0 0 0 1 0 0 1 0 58 239 222 234 238 246 252 254 255 248 255 187 0 0] [ 0 0 0 0 0 0 0 0 0 0 2 3 0 0 194 239 226 237 235 232 230 234 234 233 249 171 0 0] [ 0 0 0 0 0 0 0 0 0 1 1 0 0 10 255 226 242 239 238 239 240 239 242 238 248 192 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 172 245 229 240 241 240 241 243 243 241 227 250 209 0 0] [ 0 0 0 0 0 0 0 0 0 6 5 0 62 255 230 236 239 241 242 241 242 242 238 238 242 253 0 0] [ 0 0 0 0 0 0 0 0 0 3 0 0 255 235 228 244 241 241 244 243 243 244 243 239 235 255 22 0] [ 0 0 0 0 0 0 0 0 0 0 0 246 228 220 245 243 237 241 242 242 242 243 239 237 235 253 106 0] [ 0 0 3 4 4 2 1 0 0 18 243 228 231 241 243 237 238 242 241 240 240 240 235 237 236 246 234 0] [ 1 0 0 0 0 0 0 0 22 255 238 227 238 239 237 241 241 237 236 238 239 239 239 239 239 237 255 0] [ 0 0 0 0 0 25 83 168 255 225 225 235 228 230 227 225 227 231 232 237 240 236 238 239 239 235 251 62] [ 0 165 225 220 224 255 255 233 229 223 227 228 231 232 235 237 233 230 228 230 233 232 235 233 234 235 255 58] [ 52 251 221 226 227 225 225 225 226 226 225 227 231 229 232 239 245 250 251 252 254 254 252 254 252 235 255 0] [ 31 208 230 233 233 237 236 236 241 235 241 247 251 254 242 236 233 227 219 202 193 189 186 181 171 165 190 42] [ 77 199 172 188 199 202 218 219 220 229 234 222 213 209 207 210 203 184 152 171 165 162 162 167 168 157 192 78] [ 0 45 101 140 159 174 182 186 185 188 195 197 188 175 133 70 19 0 0 209 231 218 222 224 227 217 229 93] [ 0 0 0 0 0 0 2 24 37 45 32 18 11 0 0 0 0 0 0 72 51 53 37 34 29 31 5 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
نرمالسازی
توجه داشته باشید که همه مقادیر در این اعداد بین 0 تا 255 هستند. هنگام آموزش یک شبکه عصبی، به دلایل متعدد، سادهتر است اگر همه مقادیر را در بازه 0 تا 1 در نظر بگیریم، فرآیندی که به آن ‘نرمالسازی’ گفته میشود. خوشبختانه در پایتون، نرمالسازی یک لیست به این شکل بدون نیاز به استفاده از حلقه بسیار ساده است و میتوانیم به این صورت انجام دهیم:
training_images = training_images / 255.0 test_images = test_images / 255.0
کد: پیادهسازی مدل کراس
model = tf.keras.models.Sequential([tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation = tf.nn.relu), tf.keras.layers.Dense(10, activation = tf.nn.softmax)])
- Sequential: این قسمت ترتیب لایهها در شبکه عصبی را مشخص میکند.
- Flatten: این قسمت تصویر را گرفته و به یک مجموعه یکبعدی تبدیل میکند.
- Dense: یک لایه از نورونها را اضافه میکند. هر لایه از نورونها نیازمند یک تابع فعالسازی است که مشخص کند آنها چه کاری انجام دهند. گزینههای متعددی وجود دارد، اما فعلا از این موارد استفاده میکنیم.
- Relu: در واقع به این معناست که “اگر X بیشتر از 0 باشد، X را برگردان، در غیر این صورت 0 را برگردان” – بنابراین، این تابع فقط مقادیر بزرگتر یا مساوی 0 را به لایه بعدی در شبکه منتقل میکند.
- Softmax: این تابع مجموعهای از مقادیر را گرفته و عملا بزرگترین مقدار را انتخاب میکند. به عنوان مثال، اگر خروجی آخرین لایه به شکل [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05] باشد، این تابع بزرگترین مقدار را انتخاب کرده و به [0, 0, 0, 0, 1, 0, 0, 0, 0] تبدیل میکند تا نیاز به بررسی دستی برای یافتن بزرگترین مقدار نباشد. هدف این است که کار کدنویسی را تا حد زیادی کاهش دهد.
گام بعدی: کامپایل کردن مدل
بعد از تعریف مدل، وقت آن رسیده که آن را بسازیم. این کار با کامپایل کردن مدل با استفاده از یک بهینهساز و تابع زیان، مانند دفعات قبل انجام میشود. سپس، با استفاده از دستور model.fit، مدل را آموزش میدهیم تا بتواند دادههای آموزشی را با برچسبهای مربوطه هماهنگ کند. به این ترتیب، مدل یاد میگیرد که چگونه ارتباط بین دادههای آموزشی و برچسبهای واقعی آنها را تشخیص دهد. در نتیجه، در آینده اگر با دادههایی مواجه شویم که شبیه به دادههای آموزشی هستند، مدل قادر خواهد بود پیشبینی کند که آن دادهها چه شکلی خواهند داشت.
model.compile(optimizer = tf.optimizers.Adam(), loss = 'sparse_categorical_crossentropy', metrics =['accuracy']) model.fit(training_images, training_labels, epochs = 5)
خروجی:
Instructions for updating: Colocations handled automatically by placer. Epoch 1/5 60000/60000 [==============================] - 8s 130us/sample - loss: 0.4714 - acc: 0.8322 Epoch 2/5 60000/60000 [==============================] - 8s 137us/sample - loss: 0.3598 - acc: 0.8683 Epoch 3/5 60000/60000 [==============================] - 9s 142us/sample - loss: 0.3201 - acc: 0.8824 Epoch 4/5 60000/60000 [==============================] - 8s 131us/sample - loss: 0.2949 - acc: 0.8917 Epoch 5/5 60000/60000 [==============================] - 8s 140us/sample - loss: 0.2767 - acc: 0.9098
پس از پایان آموزش، در انتهای دورهی آخر، میزان دقتی را خواهیم دید که ممکن است حدود ۰.۹۰۹۸ باشد. این نشان میدهد که شبکه عصبی شما تقریباً ۹۱٪ دقت در دستهبندی دادههای آموزشی دارد. به این معنا که توانسته الگویی را بین تصویر و برچسبها با موفقیت ۹۱٪ کشف کند. این نتیجه خیلی خوب نیست، اما با در نظر گرفتن اینکه تنها برای ۵ دوره آموزش دیده، نتیجه بدی هم نیست.
گام بعدی: ارزیابی مدل
حالا سوال این است که این مدل با دادههای جدید چطور عمل میکند؟ برای پاسخ به این سوال، ما از تصاویر آزمایشی استفاده میکنیم. میتوانیم با استفاده از دستور model.evaluate و ارسال هر دو مجموعه داده، از مدل بخواهیم که خطا را برای هر کدام گزارش دهد.
model.evaluate(test_images, test_labels)
خروجی:
10000/10000 [==============================] - 1s 60us/sample - loss: 0.2908 - acc: 0.8956
در نهایت، مدل خود را آموزش دادیم و توانستیم دقت ۹۰٪ را روی دادههای جدید به دست آوریم. این نتیجه واقعاً خوب است.
مزایای استفاده از KERAS
متوجه شدیم که کارهای محاسباتی ما از صدها خط کد به فقط ۷ یا ۸ خط کاهش یافته است. این بسیار عالی است. به طور کلی، این کمک میکند تا وقت و انرژی خود را صرفهجویی کنیم و احتمال بروز خطا در کدنویسی را نیز کاهش دهیم.