از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
استفاده از یادگیری ماشینی برای پیش بینی آب و هوا: قسمت 3
سرفصلهای مطلب
این مقاله نهایی است روی استفاده از یادگیری ماشین در پایتون برای پیشبینی میانگین دما بر اساس دادههای آب و هوای هواشناسی بازیابی شده از آب و هوا زیرزمینی همانطور که در قسمت اول این مجموعه توضیح داده شد.
موضوع این مقاله نهایی ساخت یک رگرسیون شبکه عصبی با استفاده از Google’s Open خواهد بود Source TensorFlow کتابخانه برای آشنایی کلی با TensorFlow و همچنین بحث در مورد روشهای نصب، لطفاً به آموزش شبکه عصبی TensorFlow پست عالی Mihajlo Pavloski مراجعه کنید.
موضوعاتی که در این مقاله به آنها خواهم پرداخت عبارتند از:
- آشنایی با نظریه شبکه های عصبی مصنوعی
- API برآوردگر سطح بالا TensorFlow
- ساخت یک DNNRegressor برای پیش بینی آب و هوا
آشنایی با نظریه شبکه های عصبی مصنوعی
در آخرین مقاله (قسمت 2) من توضیح دادم process ساخت یک مدل رگرسیون خطی، یک تکنیک یادگیری ماشینی ارجمند که زیربنای بسیاری دیگر است، برای پیشبینی میانگین دمای روزانه در لینکلن، نبراسکا. مدل های رگرسیون خطی بسیار قدرتمند هستند و از زمان بسیار قبل از ابداع اصطلاح “یادگیری ماشینی” برای پیش بینی های عددی و همچنین مقوله ای استفاده شده اند. با این حال، این تکنیک انتقاداتی دارد، عمدتاً در مورد فرض خطی آن از رابطه خطی بین متغیر وابسته و متغیر(های) مستقل.
تعداد بی شماری از الگوریتم های دیگر در صنعت علم داده و یادگیری ماشین وجود دارد که بر این فرض خطی بودن غلبه می کند. یکی از محبوبترین حوزههای تمرکز در سالهای اخیر، اعمال است شبکه های عصبی به مجموعه وسیعی از مشکلات یادگیری ماشین. شبکههای عصبی روشی قدرتمند برای استفاده از تکنیکهای یادگیری مبتنی بر آن دارند روی عملیات خطی و غیر خطی
شبکه های عصبی از نورون های بیولوژیکی در مغز الهام گرفته شده اند که در شبکه پیچیده ای از تعاملات برای انتقال، جمع آوری و یادگیری اطلاعات بر اساس تاریخچه اطلاعاتی که قبلاً جمع آوری شده است، کار می کنند. شبکههای عصبی محاسباتی مورد علاقه ما شبیه به نورونهای مغز هستند زیرا مجموعهای از نورونها (گرهها) هستند که سیگنالهای ورودی (کمیتهای عددی) را دریافت میکنند. process ورودی، و سیگنال های پردازش شده را به دیگر عوامل پایین دستی در شبکه ارسال می کند. پردازش سیگنال ها به عنوان کمیت های عددی که از شبکه عصبی عبور می کنند یک ویژگی بسیار قدرتمند است که به روابط خطی محدود نمی شود.
در این سریال تمرکز من بوده است روی نوع خاصی از یادگیری ماشینی به نام یادگیری تحت نظارت، که به سادگی به این معنی است که مدلهای در حال آموزش با استفاده از دادههایی ساخته میشوند که دارای نتایج هدف شناخته شدهای هستند که مدل سعی میکند پیشبینی کند. علاوه بر این، نوع پیشبینیهایی که انجام میشوند مقادیر واقعی عددی هستند، به این معنی که ما با واپس گرای الگوریتم های پیش بینی
از نظر گرافیکی، یک شبکه عصبی مشابه آنچه در این مقاله توضیح داده شده است در تصویر زیر نشان داده شده است.
شبکه عصبی تصویر شده در بالا حاوی یک لایه ورودی است روی سمت چپ، دو ویژگی x1 و x2 را نشان میدهد که شبکه عصبی را تغذیه میکنند. این دو ویژگی به شبکه عصبی وارد می شوند که از طریق دو لایه نورون پردازش و منتقل می شوند که به آنها لایه های پنهان گفته می شود. این تصویر دو لایه پنهان را نشان می دهد که هر لایه شامل سه نورون (گره) است. سپس سیگنال از شبکه عصبی خارج می شود و در لایه خروجی به عنوان یک مقدار عددی پیش بینی شده تجمیع می شود.
اجازه دهید لحظه ای به توضیح معنای پشت فلش هایی که نشان دهنده داده های در حال پردازش هستند را توضیح دهم node به node در سراسر لایه ها هر فلش نشان دهنده یک تبدیل ریاضی از یک مقدار است که از پایه فلش شروع می شود و سپس در وزن مخصوص آن مسیر ضرب می شود. هر یک node در داخل یک لایه یک مقدار به این ترتیب تغذیه می شود. سپس تمام مقادیر همگرا در node خلاصه می شوند. این مجموع ضرب در وزن ها و جمع محصولات است که عملیات خطی یک شبکه عصبی را که قبلاً ذکر کردم تعریف می کند.
پس از جمع بندی در هر یک انجام می شود node یک تابع خاص و غیر خطی به مجموع اعمال می شود که در تصویر بالا به صورت نشان داده شده است Fn (…). این تابع ویژه که ویژگی های غیر خطی را وارد شبکه عصبی می کند، an نامیده می شود عملکرد فعال سازی. این ویژگی غیر خطی است که توسط توابع فعال سازی ایجاد می شود که به شبکه های عصبی چند لایه قدرت آنها را می دهد. اگر غیر خطی بودن به آن اضافه نمی شد process سپس تمام لایهها به طور موثر فقط از نظر جبری در یک عملیات ثابت ترکیب میشوند که شامل ضرب ورودیها در مقداری ضریب مسطح (یعنی یک مدل خطی) است.
بسیار خوب، پس همه چیز خوب و شیک است، اما امیدوارم در ته ذهن خود متعجب باشید… خوب، آدام، اما چگونه این به یک الگوریتم یادگیری تبدیل می شود؟ خوب مستقیم ترین پاسخ به آن، ارزیابی پیش بینی های انجام شده، خروجی مدل “y” به مقادیر واقعی مورد انتظار (هدف ها) و انجام یک سری تنظیمات برای وزن ها به گونه ای است که کلیت را بهبود بخشد. دقت پیش بینی
در دنیای الگوریتمهای یادگیری ماشین رگرسیور، دقت را با استفاده از یک تابع هزینه (با نام مستعار “از دست دادن” یا “هدف”) ارزیابی میکنیم. مجموع مربعات خطاها (SSE). توجه داشته باشید که من این عبارت را به کل پیوسته یادگیری ماشین تعمیم دادم، نه فقط شبکه های عصبی. در مقاله قبلی، الگوریتم حداقل مربعات معمولی دقیقاً این کار را انجام داد، ترکیبی از ضرایب را یافت که مجموع مربعات خطاها را به حداقل می رساند (یعنی حداقل مربعات).
رگرسیور شبکه عصبی ما دقیقاً همین کار را انجام می دهد. این دادههای آموزشی را در مقادیر ویژگی تکرار میکند، تابع هزینه را محاسبه میکند (با استفاده از SSE) و وزنها را به گونهای تنظیم میکند که تابع هزینه را به حداقل برساند. این process فشار دادن مکرر ویژگی ها از طریق الگوریتم و ارزیابی روش تنظیم وزن ها بر اساس تابع هزینه، در اصل چیزی است که به عنوان بهینه سازی مدل شناخته می شود.
الگوریتم های بهینه سازی مدل در ساخت شبکه های عصبی قوی بسیار مهم هستند. همانطور که نمونه ها از طریق معماری شبکه (یعنی عرض و عمق) تغذیه می شوند و سپس در برابر تابع هزینه ارزیابی می شوند، وزن ها تنظیم می شوند. زمانی گفته میشود که مدلها «یادگیری» میکنند که تابع بهینهساز تشخیص میدهد که تنظیم وزن به گونهای انجام شده است که تابع هزینه را بهبود نمیبخشد (کاهش نمیدهد) که در بهینهساز ثبت میشود تا وزنها را در آن تنظیم نکند. جهت دوباره
API برآوردگر سطح بالا TensorFlow
کتابخانه TensorFlow گوگل شامل چند API است که محبوبترین آنها Core API است که مجموعهای از ابزارهای سطح پایین را در اختیار کاربر قرار میدهد تا اساساً هر الگوریتم یادگیری ماشینی را با استفاده از عملیات نمادین تعریف و آموزش دهد. به این هسته TensorFlow گفته می شود. در حالی که TensorFlow Core یک API شگفتانگیز با قابلیت کاربردی گسترده است، من تمرکز خواهم کرد روی یک API جدیدتر و بالاتر که تیم TensorFlow توسعه داده است که در مجموع به عنوان API برآوردگر نامیده می شود.
تیم TensorFlow برای دسترسی بیشتر به کتابخانه برای توسعهدهندگان روزمره، API تخمینگر را توسعه داد. این API سطح بالا یک رابط مشترک را فراهم می کند train(...)
مدل ها، evaluate(...)
مدل ها و predict(...)
نتایج موارد ناشناخته مشابه (و تحت تأثیر) کتابخانه محبوب Sci-Kit Learn، که با پیاده سازی یک رابط مشترک برای الگوریتم های مختلف انجام می شود. همچنین، در API سطح بالا مجموعهای از بهترین شیوههای یادگیری ماشین، انتزاعها و توانایی مقیاسپذیری تعبیه شده است.
همه این خوبی های یادگیری ماشینی مجموعه ای از ابزارهای پیاده سازی شده در کلاس Estimator پایه و همچنین چندین نوع مدل از پیش کنسرو شده را به همراه دارد که مانع ورود برای استفاده از TensorFlow را کاهش می دهد تا بتوان آن را در host مشکلات (یا فرصت های) روزمره. با انتزاع کردن بسیاری از جنبه های دنیوی و دستی چیزهایی مانند نوشتن حلقه های آموزشی یا برخورد با جلسات، توسعه دهنده می تواند تمرکز کند. روی چیزهای مهمتری مانند آزمایش سریع چندین مدل و معماری مدل برای یافتن مدلی که به بهترین وجه با نیاز آنها مطابقت دارد.
در این مقاله من روش استفاده از یکی از برآوردگرهای بسیار قدرتمند شبکه عصبی عمیق، DNNRegressor
.
ساخت یک DNNRegressor برای پیش بینی آب و هوا
اجازه دهید با وارد کردن تعدادی کتابخانه مختلف که برای ساخت مدل از آنها استفاده خواهم کرد، شروع کنم:
import pandas as pd
import numpy as np
import tensorflow as tf
from sklearn.metrics import explained_variance_score, \
mean_absolute_error, \
median_absolute_error
from sklearn.model_selection import train_test_split
حالا بیایید دستمان را بگیریم روی داده ها را دوباره به اوج خود برسانیم تا با آن آشنا شویم. من تمام کدها و داده ها را در مخزن GitHub خود قرار داده ام اینجا تا خوانندگان بتوانند آن را دنبال کنند.
df = pd.read_csv('end-part2_df.csv').set_index('date')
df.describe().T
شمردن | منظور داشتن | std | دقیقه | 25% | 50% | 75% | حداکثر | |
---|---|---|---|---|---|---|---|---|
meantempm | 997.0 | 13.129388 | 10.971591 | -17.0 | 5.0 | 15.0 | ساعت 22.00 | 32.00 |
maxtempm | 997.0 | 19.509529 | 11.577275 | -12.0 | 11.0 | 22.0 | ساعت 29.00 | 38.00 |
mintempm | 997.0 | 6.438315 | 10.957267 | -27.0 | -2.0 | 7.0 | ساعت 16.00 | ساعت 26.00 |
meantempm_1 | 997.0 | 13.109328 | 10.984613 | -17.0 | 5.0 | 15.0 | ساعت 22.00 | 32.00 |
meantempm_2 | 997.0 | 13.088265 | 11.001106 | -17.0 | 5.0 | 14.0 | ساعت 22.00 | 32.00 |
meantempm_3 | 997.0 | 13.066199 | 11.017312 | -17.0 | 5.0 | 14.0 | ساعت 22.00 | 32.00 |
meandewptm_1 | 997.0 | 6.440321 | 10.596265 | -22.0 | -2.0 | 7.0 | ساعت 16.00 | ساعت 24.00 |
meandewptm_2 | 997.0 | 6.420261 | 10.606550 | -22.0 | -2.0 | 7.0 | ساعت 16.00 | ساعت 24.00 |
meandewptm_3 | 997.0 | 6.393180 | 10.619083 | -22.0 | -2.0 | 7.0 | ساعت 16.00 | ساعت 24.00 |
meanpressurem_1 | 997.0 | 1016.139418 | 7.582453 | 989.0 | 1011.0 | 1016.0 | 1021.00 | 1040.00 |
فشار متوسط_2 | 997.0 | 1016.142427 | 7.584185 | 989.0 | 1011.0 | 1016.0 | 1021.00 | 1040.00 |
meanpressurem_3 | 997.0 | 1016.151454 | 7.586988 | 989.0 | 1011.0 | 1016.0 | 1021.00 | 1040.00 |
حداکثر رطوبت_1 | 997.0 | 88.107322 | 9.280627 | 47.0 | 83.0 | 90.0 | 93.00 | 100.00 |
حداکثر رطوبت_2 | 997.0 | 88.106319 | 9.280152 | 47.0 | 83.0 | 90.0 | 93.00 | 100.00 |
حداکثر رطوبت_3 | 997.0 | 88.093280 | 9.276775 | 47.0 | 83.0 | 90.0 | 93.00 | 100.00 |
حداقل رطوبت_1 | 997.0 | 46.025075 | 16.108517 | 9.0 | 35.0 | 45.0 | 56.00 | 92.00 |
حداقل رطوبت_2 | 997.0 | 46.021063 | 16.105530 | 9.0 | 35.0 | 45.0 | 56.00 | 92.00 |
حداقل رطوبت_3 | 997.0 | 45.984955 | 16.047081 | 9.0 | 35.0 | 45.0 | 56.00 | 92.00 |
maxtempm_1 | 997.0 | 19.489468 | 11.588542 | -12.0 | 11.0 | 22.0 | ساعت 29.00 | 38.00 |
maxtempm_2 | 997.0 | 19.471414 | 11.603318 | -12.0 | 11.0 | 22.0 | ساعت 29.00 | 38.00 |
maxtempm_3 | 997.0 | 19.455366 | 11.616412 | -12.0 | 11.0 | 22.0 | ساعت 29.00 | 38.00 |
mintempm_1 | 997.0 | 6.417252 | 10.974433 | -27.0 | -2.0 | 7.0 | ساعت 16.00 | ساعت 26.00 |
mintempm_2 | 997.0 | 6.394183 | 10.988954 | -27.0 | -2.0 | 7.0 | ساعت 16.00 | ساعت 26.00 |
mintempm_3 | 997.0 | 6.367101 | 11.003451 | -27.0 | -2.0 | 7.0 | ساعت 16.00 | ساعت 26.00 |
maxdewptm_1 | 997.0 | 9.378134 | 10.160778 | -18.0 | 1.0 | 11.0 | ساعت 18.00 | ساعت 26.00 |
maxdewptm_2 | 997.0 | 9.359077 | 10.171790 | -18.0 | 1.0 | 11.0 | ساعت 18.00 | ساعت 26.00 |
maxdewptm_3 | 997.0 | 9.336008 | 10.180521 | -18.0 | 1.0 | 11.0 | ساعت 18.00 | ساعت 26.00 |
mindewptm_1 | 997.0 | 3.251755 | 11.225411 | -28.0 | -6.0 | 4.0 | ساعت 13.00 | ساعت 22.00 |
mindewptm_2 | 997.0 | 3.229689 | 11.235718 | -28.0 | -6.0 | 4.0 | ساعت 13.00 | ساعت 22.00 |
mindewptm_3 | 997.0 | 3.198596 | 11.251536 | -28.0 | -6.0 | 4.0 | ساعت 13.00 | ساعت 22.00 |
maxpressurem_1 | 997.0 | 1019.913741 | 7.755590 | 993.0 | 1015.0 | 1019.0 | 1024.00 | 1055.00 |
maxpressurem_2 | 997.0 | 1019.917753 | 7.757705 | 993.0 | 1015.0 | 1019.0 | 1024.00 | 1055.00 |
maxpressurem_3 | 997.0 | 1019.927783 | 7.757805 | 993.0 | 1015.0 | 1019.0 | 1024.00 | 1055.00 |
minpressurem_1 | 997.0 | 1012.317954 | 7.885743 | 956.0 | 1008.0 | 1012.0 | 1017.00 | 1035.00 |
minpressurem_2 | 997.0 | 1012.319960 | 7.886681 | 956.0 | 1008.0 | 1012.0 | 1017.00 | 1035.00 |
minpressurem_3 | 997.0 | 1012.326981 | 7.889511 | 956.0 | 1008.0 | 1012.0 | 1017.00 | 1035.00 |
precipm_1 | 997.0 | 2.593180 | 8.428058 | 0.0 | 0.0 | 0.0 | 0.25 | 95.76 |
precipm_2 | 997.0 | 2.593180 | 8.428058 | 0.0 | 0.0 | 0.0 | 0.25 | 95.76 |
precipm_3 | 997.0 | 2.573049 | 8.410223 | 0.0 | 0.0 | 0.0 | 0.25 | 95.76 |
df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 997 entries, 2015-01-04 to 2017-09-27
Data columns (total 39 columns):
meantempm 997 non-null int64
maxtempm 997 non-null int64
mintempm 997 non-null int64
meantempm_1 997 non-null float64
meantempm_2 997 non-null float64
meantempm_3 997 non-null float64
meandewptm_1 997 non-null float64
meandewptm_2 997 non-null float64
meandewptm_3 997 non-null float64
meanpressurem_1 997 non-null float64
meanpressurem_2 997 non-null float64
meanpressurem_3 997 non-null float64
maxhumidity_1 997 non-null float64
maxhumidity_2 997 non-null float64
maxhumidity_3 997 non-null float64
minhumidity_1 997 non-null float64
minhumidity_2 997 non-null float64
minhumidity_3 997 non-null float64
maxtempm_1 997 non-null float64
maxtempm_2 997 non-null float64
maxtempm_3 997 non-null float64
mintempm_1 997 non-null float64
mintempm_2 997 non-null float64
mintempm_3 997 non-null float64
maxdewptm_1 997 non-null float64
maxdewptm_2 997 non-null float64
maxdewptm_3 997 non-null float64
mindewptm_1 997 non-null float64
mindewptm_2 997 non-null float64
mindewptm_3 997 non-null float64
maxpressurem_1 997 non-null float64
maxpressurem_2 997 non-null float64
maxpressurem_3 997 non-null float64
minpressurem_1 997 non-null float64
minpressurem_2 997 non-null float64
minpressurem_3 997 non-null float64
precipm_1 997 non-null float64
precipm_2 997 non-null float64
precipm_3 997 non-null float64
dtypes: float64(36), int64(3)
memory usage: 311.6+ KB
توجه داشته باشید که ما کمتر از 1000 رکورد داده های هواشناسی داریم و همه ویژگی ها ماهیت عددی دارند. همچنین، به دلیل سخت کوشی ما در مقاله اول، همه رکوردها کامل هستند که هیچ مقداری را از دست نمی دهند (بدون تهی).
اکنون ستونهای «mintempm» و «maxtempm» را حذف میکنم زیرا هیچ معنایی در پیشبینی میانگین دمای متوسط ندارند. ما سعی می کنیم آینده را پیش بینی کنیم، بنابراین واضح است که نمی توانیم اطلاعاتی در مورد آینده داشته باشیم. من همچنین ویژگی ها را جدا می کنم (X
) از اهداف (y
).
df = df.drop(('mintempm', 'maxtempm'), axis=1)
X = df((col for col in df.columns if col != 'meantempm'))
y = df('meantempm')
مانند تمام برنامه های کاربردی یادگیری ماشینی تحت نظارت، من مجموعه داده های خود را به مجموعه های آموزشی و آزمایشی تقسیم خواهم کرد. با این حال، برای توضیح بهتر تکراری process برای آموزش این شبکه عصبی، من از یک مجموعه داده اضافی استفاده خواهم کرد که از آن به عنوان “مجموعه اعتبار سنجی” یاد می کنم. برای مجموعه آموزشی من از 80 درصد داده ها استفاده خواهم کرد و برای مجموعه تست و اعتبارسنجی هر کدام 10 درصد از داده های باقی مانده خواهند بود.
برای تقسیم این داده ها، من دوباره از Sci-Kit Learn استفاده خواهم کرد train_test_split(...)
.
X_train, X_tmp, y_train, y_tmp = train_test_split(X, y, test_size=0.2, random_state=23)
X_test, X_val, y_test, y_val = train_test_split(X_tmp, y_tmp, test_size=0.5, random_state=23)
X_train.shape, X_test.shape, X_val.shape
print("Training instances {}, Training features {}".format(X_train.shape(0), X_train.shape(1)))
print("Validation instances {}, Validation features {}".format(X_val.shape(0), X_val.shape(1)))
print("Testing instances {}, Testing features {}".format(X_test.shape(0), X_test.shape(1)))
Training instances 797, Training features 36
Validation instances 100, Validation features 36
Testing instances 100, Testing features 36
اولین قدمی که باید در ساخت یک مدل شبکه عصبی برداشته شود، نمونه سازی است tf.estimator.DNNRegressor(...)
کلاس سازنده کلاس چندین پارامتر دارد، اما من تمرکز خواهم کرد روی به شرح زیر:
feature_columns
: ساختاری لیست مانند که شامل تعریفی از نام و انواع داده برای ویژگی های وارد شده به مدل استhidden_units
: ساختاری لیست مانند که حاوی تعریفی از عرض و عمق اعداد شبکه عصبی استoptimizer
: نمونه ای ازtf.Optimizer
زیر کلاس، که وزن مدل را در طول تمرین بهینه می کند. پیش فرض آن بهینه ساز AdaGrad است.activation_fn
: یک تابع فعال سازی که برای معرفی غیر خطی بودن شبکه در هر لایه استفاده می شود. پیش فرض است ReLUmodel_dir
: فهرستی که باید ایجاد شود که حاوی ابرداده و سایر موارد ذخیره شده برای مدل باشد
من با تعریف لیستی از ستون های ویژگی های عددی شروع خواهم کرد. برای این کار از tf.feature_column.numeric_column()
تابعی که a را برمی گرداند FeatureColumn
نمونه ای برای ویژگی های عددی با ارزش پیوسته.
feature_cols = (tf.feature_column.numeric_column(col) for col in X.columns)
با ستون های ویژگی تعریف شده، اکنون می توانم نمونه سازی کنم DNNRegressor
کلاس و آن را در متغیر regressor ذخیره کنید. من مشخص می کنم که من یک شبکه عصبی می خواهم که دارای دو لایه عمیق باشد که هر دو لایه دارای عرض 50 گره باشند. همچنین نشان میدهم که میخواهم دادههای مدل من در فهرستی به نام ذخیره شود tf_wx_model.
regressor = tf.estimator.DNNRegressor(feature_columns=feature_cols,
hidden_units=(50, 50),
model_dir='tf_wx_model')
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_tf_random_seed': 1, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_model_dir': 'tf_wx_model', '_log_step_count_steps': 100, '_keep_checkpoint_every_n_hours': 10000, '_save_summary_steps': 100, '_keep_checkpoint_max': 5, '_session_config': None}
کار بعدی که می خواهم انجام دهم این است که یک تابع قابل استفاده مجدد را تعریف کنم که به طور کلی به عنوان “عملکرد ورودی” نامیده می شود، که من آن را فراخوانی می کنم. wx_input_fn(...)
. این تابع برای تغذیه داده ها به شبکه عصبی من در طول مراحل آموزش و آزمایش استفاده خواهد شد. راههای مختلفی برای ساخت توابع ورودی وجود دارد، اما من روش تعریف و استفاده از یک توابع را توضیح خواهم داد. tf.estimator.inputs.pandas_input_fn(...)
از آنجایی که داده های من در ساختارهای داده پاندا است.
def wx_input_fn(X, y=None, num_epochs=None, shuffle=True, batch_size=400):
return tf.estimator.inputs.pandas_input_fn(x=X,
y=y,
num_epochs=num_epochs,
shuffle=shuffle,
batch_size=batch_size)
توجه کنید که این wx_input_fn(...)
تابع دارای یک پارامتر اجباری و چهار پارامتر اختیاری است که سپس به یک تابع ورودی TensorFlow به طور خاص برای دادههای پاندا تحویل داده میشود که برگردانده میشود. این یک ویژگی بسیار قدرتمند TensorFlow API (و پایتون و سایر زبانهایی است که با توابع به عنوان شهروندان درجه یک رفتار میکنند).
پارامترهای تابع به صورت زیر تعریف می شوند:
X
: ویژگی های ورودی به یکی از سه مورد تغذیه می شودDNNRegressor
روش های رابط (train
،evaluate
، وpredict
)y
: مقادیر هدف ازX
، که اختیاری هستند و به آنها ارائه نمی شودpredict
زنگ زدنnum_epochs
: یک پارامتر اختیاری. یک دوره زمانی اتفاق می افتد که الگوریتم یک بار روی کل مجموعه داده اجرا شود.shuffle
: یک پارامتر اختیاری، مشخص می کند که هر بار که الگوریتم اجرا می شود، یک دسته (زیر مجموعه) از مجموعه داده به طور تصادفی انتخاب شود یا خیر.batch_size
: تعداد نمونه هایی که در هر بار اجرای الگوریتم باید گنجانده شود
با تعریف تابع ورودی ما اکنون می توانیم شبکه عصبی خود را آموزش دهیم روی مجموعه داده آموزشی ما برای خوانندگانی که با API سطح بالای TensorFlow آشنا هستند، احتمالا متوجه خواهید شد که من در مورد روش آموزش مدل خود کمی غیر متعارف هستم. یعنی حداقل از منظر آموزش های فعلی روی وب سایت تنسورفلو و سایر آموزش ها روی وب.
معمولاً هنگامی که یکی از این مدلهای از پیش آماده شده API سطح بالا را آموزش میدهید، چیزی شبیه به زیر خواهید دید.
regressor.train(input_fn=input_fn(training_data, num_epochs=None, shuffle=True), steps=some_large_number)
.....
lots of log info
....
سپس نویسنده مستقیماً به نشان دادن آن خواهد پرداخت evaluate(...)
عمل می کند و به سختی اشاره ای به توصیف آنچه انجام می دهد یا دلیل وجود این خط کد.
regressor.evaluate(input_fn=input_fn(eval_data, num_epochs=1, shuffle=False), steps=1)
.....
less log info
....
و پس از این، آنها مستقیماً به اجرای آن خواهند پرداخت predict(...)
عملکرد با فرض اینکه همه با مدل آموزش دیده کامل است.
predictions = regressor.predict(input_fn=input_fn(pred_data, num_epochs=1, shuffle=False), steps=1)
برای تازهوارد ML که این نوع آموزش را میخواند، من دلم گرفته است. فکر بسیار بیشتری در این سه خط کد وجود دارد که توجه بیشتری را ایجاب می کند. من احساس می کنم این تنها نقطه ضعف داشتن یک API سطح بالا است – جمع کردن یک مدل بدون درک نکات کلیدی بسیار آسان می شود. امیدوارم بتوانم توضیح معقولی در مورد روش آموزش و ارزیابی این شبکه عصبی به گونه ای ارائه کنم که خطر تطبیق یا بیش از حد برازش این مدل با داده های آموزشی را به حداقل برساند.
بنابراین، بدون تاخیر بیشتر اجازه دهید یک حلقه آموزشی ساده برای آموزش مدل تعریف کنم روی داده های آموزشی و ارزیابی دوره ای آن روی داده های ارزیابی
evaluations = ()
STEPS = 400
for i in range(100):
regressor.train(input_fn=wx_input_fn(X_train, y=y_train), steps=STEPS)
evaluations.append(regressor.evaluate(input_fn=wx_input_fn(X_val,
y_val,
num_epochs=1,
shuffle=False)))
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Saving checkpoints for 1 into tf_wx_model/model.ckpt.
INFO:tensorflow:step = 1, loss = 1.11335e+07
INFO:tensorflow:global_step/sec: 75.7886
INFO:tensorflow:step = 101, loss = 36981.3 (1.321 sec)
INFO:tensorflow:global_step/sec: 85.0322
... A WHOLE LOT OF LOG OUTPUT ...
INFO:tensorflow:step = 39901, loss = 5205.02 (1.233 sec)
INFO:tensorflow:Saving checkpoints for 40000 into tf_wx_model/model.ckpt.
INFO:tensorflow:Loss for final step: 4557.79.
INFO:tensorflow:Starting evaluation at 2017-12-05-13:48:43
INFO:tensorflow:Restoring parameters from tf_wx_model/model.ckpt-40000
INFO:tensorflow:Evaluation (1/1)
INFO:tensorflow:Finished evaluation at 2017-12-05-13:48:43
INFO:tensorflow:Saving dict for global step 40000: average_loss = 10.2416, global_step = 40000, loss = 1024.16
INFO:tensorflow:Starting evaluation at 2017-12-05-13:48:43
INFO:tensorflow:Restoring parameters from tf_wx_model/model.ckpt-40000
INFO:tensorflow:Finished evaluation at 2017-12-05-13:48:43
INFO:tensorflow:Saving dict for global step 40000: average_loss = 10.2416, global_step = 40000, loss = 1024.16
حلقه بالا 100 بار تکرار می شود. در بدنه حلقه من the را صدا می زنم train(...)
متد شی regressor، ارسال آن قابل استفاده مجدد wx_input_fn(...)
که به نوبه خود مجموعه و اهداف آموزشی من را گذرانده است. من عمداً پارامترهای پیش فرض را ترک کردم num_epochs
مساوی با None
، که اساساً می گوید: “برای من مهم نیست که چند بار از مجموعه آموزشی عبور می کنید، فقط به آموزش الگوریتم در برابر هر پیش فرض ادامه دهید. batch_size
400 اینچ (تقریباً نصف اندازه مجموعه آموزشی). shuffle
پارامتر برابر با مقدار پیش فرض آن است True
به طوری که در حین آموزش، داده ها به صورت تصادفی انتخاب می شوند تا از هرگونه رابطه متوالی در داده ها جلوگیری شود. پارامتر نهایی به train(...)
روش است steps
که من روی 400 تنظیم کردم، یعنی مجموعه آموزشی در هر حلقه 400 بار دسته بندی می شود.
این به من فرصت خوبی می دهد تا به روش عددی دقیق تر توضیح دهم که معنای یک دوره چیست. از گلوله های بالا به یاد بیاورید که یک دوره زمانی اتفاق می افتد که تمام رکوردهای یک مجموعه آموزشی از طریق شبکه عصبی منتقل می شود تا دقیقاً یک بار آموزش داده شود. بنابراین، اگر ما حدود 800 (به طور دقیق 797) رکورد در مجموعه آموزشی خود داشته باشیم و هر دسته 400 رکورد را انتخاب کند، در این صورت به ازای هر دو دسته، یک دوره را انجام داده ایم. بنابراین، اگر روی مجموعه آموزشی بیش از 100 تکرار 400 مرحله ای با اندازه دسته ای 400 (یک نیم دوره در هر دسته) تکرار کنیم، دریافت می کنیم:
(100 x 400 / 2) = 20,000 epochs
حالا ممکن است تعجب کنید که چرا من و evaluate(...)
روش برای هر تکرار حلقه و خروجی آن در یک لیست ثبت می شود. ابتدا اجازه دهید توضیح دهم که هر بار چه اتفاقی می افتد train(...)
روش شلیک می شود. دستهای تصادفی از رکوردهای آموزشی را انتخاب میکند و آنها را تا زمانی که یک پیشبینی انجام میشود در شبکه هل میدهد و برای هر رکورد تابع ضرر محاسبه میشود. سپس بر اساس تلفات محاسبهشده، وزنها بر اساس منطق بهینهساز تنظیم میشوند، که در انجام تنظیمات به سمت جهتی که تلفات کلی را برای تکرار بعدی کاهش میدهد، کار بسیار خوبی انجام میدهد. این مقادیر از دست دادن، به طور کلی تا زمانی که میزان یادگیری به اندازه کافی کوچک باشد، در طول زمان با هر تکرار یا مرحله کاهش می یابد.
با این حال، پس از مقدار معینی از این تکرارهای یادگیری، وزنها نه تنها تحت تأثیر روند کلی دادهها، بلکه تحت تأثیر نویز غیراطلاعاتی که تقریباً در تمام دادههای واقعی به ارث میرسد، میشوند. در این مرحله شبکه بیش از حد تحت تأثیر ویژگیهای خاص دادههای آموزشی قرار میگیرد و قادر به تعمیم پیشبینیها در مورد جمعیت کلی دادهها (یعنی دادههایی که هنوز دیده نشده است) میشود.
این مربوط به موضوعی است که قبلاً در مورد بسیاری از آموزش های دیگر ذکر کردم روی API سطح بالا TensorFlow کوتاهی کرده است. بسیار مهم است که به طور دوره ای در طول آموزش شکسته شود و روش تعمیم مدل به مجموعه داده های ارزیابی یا اعتبارسنجی ارزیابی شود. بیایید یک لحظه به آنچه که evaluate(...)
تابع با مشاهده خروجی ارزیابی تکرار حلقه اول برمی گردد.
evaluations(0)
{'average_loss': 31.116383, 'global_step': 400, 'loss': 3111.6382}
همانطور که می بینید، میانگین تلفات (میانگین مربعات خطا) و مجموع ضرر (مجموع مربعات خطا) را برای مرحله آموزش که برای این مرحله 400 مرحله است، خروجی می دهد. چیزی که معمولاً در یک شبکه بسیار آموزش دیده می بینید، روندی است که در آن ضررهای آموزش و ارزیابی کم و بیش به طور مداوم به طور موازی کاهش می یابد. با این حال، در یک مدل بیش از حد برازش در برخی از زمانها، در واقع در نقطهای که برازش بیش از حد شروع میشود، مجموعه آموزشی اعتبارسنجی کاهشهایی را در خروجی خود مشاهده نخواهد کرد. evaluate(...)
روش. اینجاست که میخواهید آموزش بیشتر مدل را ترجیحاً درست قبل از این تغییر متوقف کنید.
اکنون که مجموعهای از ارزیابیها برای هر یک از تکرارها داریم، اجازه دهید آنها را به عنوان تابعی از مراحل آموزشی ترسیم کنیم تا مطمئن شویم که مدل خود را بیش از حد آموزش ندادهایم. برای انجام این کار من از یک نمودار پراکندگی ساده از matplotlib استفاده خواهم کرد pyplot
مدول.
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams('figure.figsize') = (14, 10)
loss_values = (ev('loss') for ev in evaluations)
training_steps = (ev('global_step') for ev in evaluations)
plt.scatter(x=training_steps, y=loss_values)
plt.xlabel('Training steps (Epochs = steps / 2)')
plt.ylabel('Loss (SSE)')
plt.show()
سرد! از نمودار بالا به نظر می رسد که پس از تمام آن تکرارها، مدل را بیش از حد برازش نداده ام، زیرا ضررهای ارزیابی هرگز تغییر قابل توجهی در جهت به سمت یک مقدار افزایشی نشان نمی دهند. اکنون می توانم با خیال راحت حرکت کنم روی برای انجام پیشبینیها بر اساس مجموعه دادههای آزمایشی باقیمانده و ارزیابی عملکرد مدل به عنوان پیشبینی میانگین دمای هوا.
مشابه دو روش رگرسیور دیگر که نشان دادم، predict(...)
روش نیاز به یک input_fn
که من با استفاده از قابل استفاده مجدد از آن عبور خواهم کرد wx_input_fn(...)
، مجموعه داده آزمایشی را به آن تحویل می دهیم و مقدار را مشخص می کنیم num_epochs
یکی بودن و shuffle
نادرست بودن به طوری که به طور متوالی تمام داده ها را برای آزمایش تغذیه می کند.
در مرحله بعد، من مقداری قالببندی دیکتههای تکرارشوندهای که از the برگردانده میشوند را انجام میدهم predict(...)
روش به طوری که من یک آرایه ناچیز از پیش بینی ها داشته باشم. سپس از آرایه پیشبینیها با روشهای sklearn استفاده میکنم explained_variance_score(...)
، mean_absolute_error(...)
، و median_absolute_error(...)
برای اندازه گیری میزان موفقیت پیش بینی ها در رابطه با اهداف شناخته شده y_test
. این به توسعه دهنده می گوید که قابلیت های پیش بینی مدل چیست.
pred = regressor.predict(input_fn=wx_input_fn(X_test,
num_epochs=1,
shuffle=False))
predictions = np.array((p('predictions')(0) for p in pred))
print("The Explained Variance: %.2f" % explained_variance_score(
y_test, predictions))
print("The Mean Absolute Error: %.2f degrees Celcius" % mean_absolute_error(
y_test, predictions))
print("The Median Absolute Error: %.2f degrees Celcius" % median_absolute_error(
y_test, predictions))
INFO:tensorflow:Restoring parameters from tf_wx_model/model.ckpt-40000
The Explained Variance: 0.88
The Mean Absolute Error: 3.11 degrees Celcius
The Median Absolute Error: 2.51 degrees Celcius
من از معیارهای مشابه مقاله قبلی در مورد تکنیک رگرسیون خطی استفاده کرده ام تا نه تنها بتوانیم این مدل را ارزیابی کنیم، بلکه بتوانیم آنها را با هم مقایسه کنیم. همانطور که می بینید این دو مدل کاملاً مشابه عمل کردند و مدل رگرسیون خطی ساده تر کمی بهتر است. با این حال، یک پزشک زیرک مطمئناً چندین آزمایش را انجام میدهد که پارامترهای فراپارامتر (نرخ یادگیری، عرض و عمق) این شبکه عصبی را تغییر میدهد تا کمی آن را تنظیم کند، اما به طور کلی این احتمالاً تقریباً به مدل بهینه نزدیک است.
این نکته ای را مطرح می کند که قابل ذکر است، به ندرت چنین است و قطعاً توصیه نمی شود که به سادگی به آن اعتماد کنیم. روی یک مدل یا جدیدترین موضوع داغ در جامعه یادگیری ماشین. هیچ دو مجموعه داده یکسان نیستند و هیچ مدلی پادشاه نیست. تنها راه برای تعیین بهترین مدل این است که آنها را واقعاً امتحان کنید. سپس هنگامی که بهترین مدل را شناسایی کردید، معاوضه های دیگری مانند تفسیرپذیری وجود دارد.
منابع
آیا می خواهید ابزارها، تکنیک های یادگیری ماشینی و تجزیه و تحلیل داده های مورد استفاده در این آموزش را یاد بگیرید؟ در اینجا چند منبع عالی برای شروع شما وجود دارد:
نتیجه
این مقاله روش استفاده از API سطح بالای TensorFlow را برای زیرکلاس از پیش آماده شده تخمینگر نشان داده است. DNNRegressor
. در طول راه، به طور کلی، نظریه شبکه های عصبی، روش آموزش آنها و اهمیت آگاهی از خطرات بیش از حد برازش یک مدل را توضیح دادم. process.
برای نشان دادن این process از ساخت شبکه های عصبی من مدلی ساخته ام که قادر است میانگین دمای روز بعد را بر اساس ویژگی های عددی جمع آوری شده در مقاله اول این مجموعه پیش بینی کند. با توجه به آنچه گفته شد، من می خواهم لحظه ای وقت بگذارم تا قصد خود را برای این سریال روشن کنم. هدف اصلی من ساختن مدلهای پیشبینی پیشرفته در مقاله رگرسیون خطی یا مقاله فعلی نبوده است. روی شبکه های عصبی، اما اهداف من انجام موارد زیر بوده است:
- ژنرال را نشان دهید process برای انجام یک پروژه تحلیلی (یادگیری ماشین، علم داده، هر چیز دیگری…) از جمع آوری داده ها، پردازش داده ها، تجزیه و تحلیل داده های اکتشافی، انتخاب مدل، ساخت مدل، و ارزیابی مدل.
- با استفاده از دو کتابخانه محبوب پایتون، StatsModels و Scikit Learn، روش انتخاب ویژگیهای معنیدار را که مفروضات کلیدی تکنیک رگرسیون خطی را نقض نمیکنند، نشان دهید.
- روش استفاده از TensorFlow API سطح بالا را نشان دهید و به آنچه در زیر تمام آن لایههای انتزاعی در حال رخ دادن است، شهودی بدهید.
- در مورد مسائل مربوط به بیش از حد برازش یک مدل بحث کنید.
- اهمیت آزمایش با بیش از یک نوع مدل را برای حل بهترین مشکل توضیح دهید.
ممنون که خواندید. امیدوارم شما هم مثل من از این سریال لذت برده باشید و مثل همیشه از نظرات و انتقادات استقبال می کنم.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-28 20:02:03