برای اینکه بفهمید چی به چیه برید قسمتهای اول و دوم و سوم رو بخونین. توی این قسمت میخوایم از مدلمون یه instance بسازیم و حلقه train رو بنویسیم.
برای ساخت یک نمونه از کلاس که کدش رو در قسمت قبل نوشتیم اول از همه برای تولید اعداد تصادفی یه seed برای torch ست میکنیم. و بعد یه ابجکت از کلاس TabularModel میسازیم.
torch.manual_seed(33) model = TabularModel(emb_szs, conts.shape[1], 1, [200,100], p=0.4)
ورودی های کلاس همونطور که در قسمت قبل دیدیم. emb_szd تاپلهایی بود که اندازه متغیرهای categorical و سایز امبدینگهامون رو داشت. conts.shape[1] تعداد متغیرهای عددیمون بود. آرگومان بعدی سایز خروجی هست که گفتیم 1 میذاریم چون فقط میخوایم یه عدد رو پیش بینی کنیم. [100,200] تعداد نورونهای لایه های شبکه هست. ینی شبکه ما دو لایه داره. در لایه اول 200 نورون و در لایه دوم 100 تا نورون داره. و اون p هم نرخ دراپ اوت هست که برای لایه های شبکه عدد 0.4 رو ست میکنیم.
مدلمون رو مرور کوچولو بکنیم :
همونطور که میبینین یه مدل داریم که لایه هاش عبارتند از یه لایه 200 تایی بعد یه لایه 100 تایی و در نهایت هم یه لایه 1 نورونی
مرحله بعدی تعریف criterion و optimiser هست:
criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
برای criterion از MSELoss (میانگین مربع خطا) استفاده میکنیم. برای optimizer هم از Adam . آرگومان اولش که پارامترهای مدل هست و ارگومان دوم کهlearning rate مقدارش رو 0.001 میدیم.
مرحله بعدی جداسازی دیتای train و test هست. که چون ما از اول داده های categorical و continius یا عددی رو جدا کردیم، اینجا هم همینکار رو میکنیم:
batch_size = 120000 test_size = int(batch_size * .2) cat_train = cats[:batch_size-test_size] cat_test = cats[batch_size-test_size:batch_size] con_train = conts[:batch_size-test_size] con_test = conts[batch_size-test_size:batch_size] y_train = y[:batch_size-test_size] y_test = y[batch_size-test_size:batch_size]
البته یادمون باشه که قبل از اسپیلیت باید یه دور دیتا رو شافل کنیم. مثلا انگار که بر بزنیم دیتا رو تا هیچ الگو یا سوگیری نداشته باشه.
حالا رسیدیم به قسمت اصلی کار یعنی حلقه train :
import time start_time = time.time() epochs = 300 losses = [] for i in range(epochs): i+=1 y_pred = model(cat_train, con_train) loss = torch.sqrt(criterion(y_pred, y_train)) # RMSE losses.append(loss) if i%25== 1: print(f'epoch: {i:3} loss: {loss.item():10.8f}') optimizer.zero_grad() loss.backward() optimizer.step() print(f'epoch: {i:3} loss: {loss.item():10.8f}') print(f'\nDuration: {time.time() - start_time:.0f} seconds')
اون time رو صرفا برای این گذاشتم که مدت زمان رو چک کنم. تعداد epoch ها رو 300 قرار میدیم و داخل حلقه loss ها رو محاسبه میکنیم و اخر از همه هم چاپش میکنیم. اون if رو برای این گذاشتیم که lossهای epochها رو هر 25 تا یه بار چاپ کنه
خروجی کار رو میبینین:
نمودار loss بر حسب epoch رو که رسم کنیم روند نزولی اش رو میتونین ببینین:
حالا چون که مرحله train مون تموم شد و دیگه نمیخوایم وزنها و پارامترهامون رو بهتر کنیم میایم torch.no_grad رو صدا میکنیم و مدل رو روی دیتای test اجرا میکنیم و loss اش رو درمیاریم:
with torch.no_grad(): y_val = model(cat_test, con_test) loss = torch.sqrt(criterion(y_val, y_test)) print(f'RMSE: {loss:.8f}')
چون پایتورچ متد mseاش جذر رو نگرفته خودمون دستی مجذور رو هم محاسبه میکنیم. این عدد 3.34 یعنی اینکه کرایه های پیش بینی شده ما به طور میانگین 3.34 تا از واقعی ها کمتر یا بیشتر هستند. حالا بیاید کرایه های پیش بینی شده امون رو خودمون ببینیم.
حالا بیاید مقدار واقعی کرایه و مقداری که ما پیش بینی کردیم رو با هم مقایسه کنیم:
print(f'{"PREDICTED":>12} {"ACTUAL":>8} {"DIFF":>8}') for i in range(50): diff = np.abs(y_val[i].item()-y_test[i].item()) print(f'{i+1:2}. {y_val[i].item():8.4f} {y_test[i].item():8.4f} {diff:8.4f}')
کاری که اینجا میکنیم اینه که اول به چیزی که میخوایم چاپ کنیم یه فرمتی میدیم و 8 تا space فاصله بینشون میندازیم. بعد قدر مطلق تفاضلشون رو چاپ میکنیم. بعد هم فرمت چاپ اعداد رو 4تا عدد بعد از ممیز میذاریم
میبینین که بعضی جاها خوب پیش بینی کردیم و بعضی جاها هم اصلا خوب نیست و خیلی تفاوتشون هست.
میتونیم اخر کار این مدل با این وضعیت پارامترها و ... رو ذخیره کنیم و برای یه دیتای دیگه ازش استفاده کنیم
torch.save(model.state_dict(), 'TaxiFareRegrModel.pt')
حالا شما میتونین یه نقطه جدید برای سوار شدن مسافر و پیاده شدنش بهش به این مدل بدین و ازش بخواین که کرایه رو پیش بینی کنه.
خلاصه که همین.
در قسمت بعد میریم سراغ classification و میبینیم که با همین دیتا چه طوری یه مسئله دسته بندی رو حل میکنیم.