تابع زیان به خروجی مدل و پاسخ مرجع، هزینه عددی نسبت میدهد. در آموزش، الگوریتم از این عدد برای تغییر پارامترها استفاده میکند. خطای صفر و یک فقط درست یا غلطشدن دسته نهایی را میبیند؛ زیانی مانند Log Loss به احتمال نسبتدادهشده به پاسخ درست نیز حساس است. برای همین، دقت برابر به معنی زیان برابر نیست.
یک مسئله دودویی، چهار مجموعه امتیاز
دو پاسخ مرجع ساختگی داریم: [1,0]. امتیاز خام یا logit را با سیگموید به احتمال کلاس ۱ تبدیل میکنیم و برای تصمیم نهایی، احتمال ۰٫۵ را آستانه میگذاریم. وزنها را در این راهنما آموزش نمیدهیم؛ چهار مجموعه امتیاز را خودمان تعیین کردهایم تا رفتار معیار را جدا ببینیم.
| امتیازهای خام | دقت روی دو نمونه | میانگین Log Loss تقریبی |
|---|---|---|
| [0.4,-0.4] | ۱۰۰٪ | ۰٫۵۱۳۰۱۵ |
| [4,-4] | ۱۰۰٪ | ۰٫۰۱۸۱۵۰ |
| [0.01,0.01] | ۵۰٪ | ۰٫۶۹۳۱۶۰ |
| [4,4] | ۵۰٪ | ۲٫۰۱۸۱۵۰ |
دو ردیف اول هر دو برچسب را درست انتخاب میکنند، اما ردیف دوم احتمال بیشتری به پاسخ مرجع میدهد. در دو ردیف آخر، هر دو نمونه کلاس ۱ میگیرند؛ یک پاسخ درست و یک پاسخ غلط است. ردیف آخر درباره همان خطای غلط، اطمینان بیشتری نشان میدهد و هزینه لگاریتمی بالاتری میگیرد.
فرمول چه چیزی را جریمه میکند؟
برای پاسخ y که صفر یا یک است و احتمال p برای کلاس ۱، زیان برابر منفیِ کل جمعِ (y×ln(p)+(1−y)×ln(1−p)) است. در حالت y=1 فقط منفی ln(p) میماند؛ در حالت y=0 منفی ln(1−p). در اینجا لگاریتم طبیعی به کار میبریم و روی دو نمونه میانگین میگیریم، نه جمع.
این تعریف، قرارداد همه تابعهای زیان نیست. برای یک خروجی عددی، خطای مطلق یا مربع خطا ممکن است هدف دیگری بسازد؛ برای وزندهی کلاس یا نمونه نیز مقدار و تفسیر جمع تغییر میکند. پیش از مقایسه دو گزارش، کاهش میانگین، جمع، وزنها و مجموعه داده را یکسان کنید.
کد پایدار، مستقیم از امتیاز خام
import math
def binary_logit_loss(z, y):
if not math.isfinite(z) or y not in (0,1):
raise ValueError('finite logit and binary label required')
return max(z,0.0)-z*y+math.log1p(math.exp(-abs(z)))
truth = [1,0]
for logits in ([.4,-.4],[4.0,-4.0],[.01,.01],[4.0,4.0]):
losses = [binary_logit_loss(z,y) for z,y in zip(logits,truth)]
accuracy = sum((z >= 0) == bool(y) for z,y in zip(logits,truth))/len(truth)
print(logits, 'accuracy', accuracy, 'mean loss', round(sum(losses)/len(losses),6))
assert abs(binary_logit_loss(0,1)-math.log(2)) < 1e-12
assert binary_logit_loss(1000,0) == 1000.0
assert binary_logit_loss(-1000,1) == 1000.0
assert math.isfinite(binary_logit_loss(1000,1))
assert abs(binary_logit_loss(.4,1)-0.5130152523999526) < 1e-12
اگر ابتدا احتمال بسیار نزدیک به صفر یا یک را به عدد رایانهای تبدیل کنیم و بعد log بگیریم، ممکن است به گردشدن یا log(0) برسیم. این تابع از شکل معادلِ پایدارترِ زیان از logit استفاده میکند؛ برای z=1000 و پاسخ غلط صفر، مقدار ۱۰۰۰ میدهد. این ویژگی عددی، کیفیت پیشبینی یا صحت برچسب را تضمین نمیکند.
زیان آموزش با عملکرد تازه فرق دارد
در مثال رگرسیون لجستیک یک گام تغییر وزن را میبینید؛ اینجا حتی یک پارامتر را هم تغییر ندادیم. کاهش زیان روی نمونههای آموزش، بهتنهایی شاهد بهترشدن عملکرد روی داده تازه نیست. داده اعتبارسنجی و آزمون باید وظیفه مشخص داشته باشند؛ بیشبرازش همین فاصله را مهم میکند.
همچنین احتمال خروجی مدل با فراوانی واقعی رخدادها یکی فرض نمیشود. کالیبراسیون احتمال درباره این سازگاری سؤال دیگری میپرسد. این مثال کوچک نه نمونه کافی برای سنجش کالیبراسیون است و نه نتیجه واقعی یک محصول.
برای انتخاب راهکار چه سؤالی بپرسیم؟
از ارائهدهنده بخواهید روشن کند تابع زیان آموزش چه بوده، معیار گزارششده روی چه دادهای حساب شده و خطای مهم برای فرایند شما چیست. در پاسخگویی مشتری، درستبودن عدد زیان جای بررسی پاسخ مجاز، ارجاع انسانی و انجام اقدام بعدی را نمیگیرد. چند نمونه واقعیِ بدون اطلاعات حساس را برای بررسی نیاز با اپرا آماده کنید؛ این آموزش ادعایی درباره الگوریتم آموزش محصولات ندارد.
فایل تمرین و منابع
دریافت کد مستقل تمرین؛ بدون نصب بسته اضافه یا اتصال شبکه. ورودیها آموزشیاند و داده مشتری نیستند.
تاریخ خواندن منابع: ۳ نوامبر ۲۰۲۶. مثالها، کد و اعداد این راهنما برای آموزش طراحی شدهاند.