برنامه نویسی

در Torch.Sum و Torch.Tensor.Sum – Community Dev

من علاقه مند هستم که بدانم ، چگونه ، و تا چه اندازه LLMS دارای هوش واقعی هستند ، اما برای فهمیدن این موضوع ، باید بدانم که چگونه آنها کار می کنند. برای این منظور ، من “مقدمه املایی را به مدل سازی زبان: ساختمان Makemore” در لیست پخش YouTube آندره کارپتی “شبکه های عصبی: صفر به قهرمان” تماشا کرده ام. بین زمان های 44:23 و 47:20 ، آندره بینندگان خود را ترغیب می کند تا پاسخ سؤال زیر را از بین ببرند (توجه: من در حال بیان و ساده سازی هستم ، برخی از جزئیات کد آندره را از بین می برد). اجازه دادن tensor متغیری باشد که دارای یک تانسور Pytorch است – نمونه ای از کلاس torch.Tensor، نمایندگی


در حرفماتریس بعدیبشر\ textrm {an} n \ textrm {-dimensional}.

فرض کردن tensor ابعاد 27×27 دارد. چرا نمی توانیم ارزش بازگشت را فرض کنیم tensor.sum(1) یکسان با آن است tensor.sum(1, keepdim=True)، و بنابراین آن tensor / tensor.sum(1) وت tensor / tensor.sum(1, keepdim=True) هر دو مورد یک چیز را ارزیابی می کنند؟

از این گذشته ، طبق معناشناسی پخش پیتورچ ، tensor وت tensor.sum(1, keepdim=True) قابل پخش هستند ، و tensor وت tensor.sum(1) هم همینطور هستند اینقدر tensor می تواند توسط هر دو تقسیم شود tensor.sum(1, keepdim=True) یا tensor.sum(1)بشر و تا زمانی که این دو عملیات تقسیم قانونی باشند ، بلافاصله آشکار نیست که چگونه می توانند نتایج متفاوتی داشته باشند. تانسور تقسیم شده در هر دو حالت یکسان است. و هر یک از تقسیم کننده های متناوب یک تانسور است که حاوی مجموع هر “ردیف” است tensor در ابعاد 1بشر متغیر tensor همچنین در هر دو عملیات بخش دارای همان ارزش است. با توجه به همه این مشترکات ، ارزش چه تفاوتی می تواند باشد keepdim درست کردن؟

من می دانم که من فقط دانش نسبتاً خوبی را پیش بینی کرده ام. اگر ابتدا ویدیوی آندره را تماشا می کنید ، ممکن است پاراگراف قبلی را بهتر دنبال کنید. ما همچنین آنچه را که من فقط در یک پست آینده گفتم ، باز خواهیم کرد. اما قبل از اینکه حتی سعی کنم به سؤال آندره پاسخ دهم ، من می توانم انجام دهم ، یاد می گیرم که چگونه کد پایتون و مستندات کتابخانه های پایتون مانند Pytorch را بخوانم.


بیایید نگاهی به مستندات برای torch.sum:

https%3A%2F%2Fdev to

من به پایتون عادت ندارم ، فقط C ++ ، JavaScript و Java. بنابراین وقتی سعی کردم از امضای عملکرد در بالای تصویر استفاده کنم ، روند فکر من تقریباً به شرح زیر پیش رفت.

با tensor در اختیار ما ، می توانیم از یک عملکرد استفاده کنیم sum از هر دو روش: torch.sum(tensor, dim) یا tensor.sum(dim)بشر هر دو دعوت دقیقاً همان کار را انجام می دهند ، تا آنجا که می توانم بگویم. هر دو sum در هر دو مورد همان عملکرد است ، یا دو عملکرد با همین نام دارای پیاده سازی های بسیار مشابهی هستند. من با فرضیه قبلی می روم ، زیرا این ساده تر است. بنابراین ، torch وت tensor تابعی به نام را به اشتراک بگذارید sum از طریق اپراتور نقطه قابل دسترسی است ، .بشر به احتمال زیاد ، پس ، torch.Tensor و موارد آن ، از جمله tensor، به ارث بردن sum از torchبشر اکنون ، روش ها فقط از انواع و نه از اشیاء جداگانه می توانند به ارث برده شوند. اینقدر torch باید یک نوع باشد. فراتر از من است که چه نوع نوع است. من شنیده ام torch به عنوان یک ماژول توصیف شده است. این دلایلی را برای شک و تردید یک کلاس یا رابط کاربری تشکیل می دهد. اما برای همه من می دانم که ماژول ها کلاس ها یا رابط هستند. من با پایتون لنگو مانند “ماژول” چقدر ناآشنا هستم. در همه وقایع به نظر می رسد که sum یک روش استاتیک از torch، از آنجا که می توانید آن را صدا کنید torch خود ، نه فقط نمونه ای از نوع torchبشر و از آنجا که این روش بدن دارد torch، من مشکوک هستم torch رابط کاربری نیست.

باز هم ، این پاراگراف آخر فقط همان چیزی است که من در ابتدا فکر می کردم ، وقتی که من کمی با سواد پایتون بودم. متأسفانه ، استدلال من در آنجا باعث گمراه شدن من شد. torch.sum(input,dim,keepdim=False,*,dtype=None) امضای یک روش استاتیک نیست. در واقع ، از آن زمان به هیچ وجه امضای روش نیست sum روشی نیست torchبشر چرا این روش نیست torch کمی توضیح می دهد

با تعریف ، یک تابع

جج

است روش از

xx

اگر و فقط اگر (من)

جج

ویژگی متعلق به نوعی است

حرفباt ،

و (ii)

xx

است یا فوراً است

حرفبشرt.

همانطور که اتفاق می افتد ، عملکرد sum یک ویژگی از یک نوع است ، یعنی torch.Tensorبشر بنابراین ، با تعریف ما ، sum روشی است torch.Tensor و از هر نمونه آن اما این روشی نیست torchبشر برای sum برای اینکه روشی باشد torchبا torch باید نوعی از آن باشد یا فوری کند sum یک ویژگی است یک ماژول بودن – که دقیقاً شبیه به بسته جاوا ، یک فضای نام است –torch یک نوع نیست (یک کلاس/ساختار یا رابط). بنابراین تنها راه sum می تواند روشی باشد torch اگر باشد torch نوعی از آن را فوری می کند sum یک ویژگی است حالا ، torch آیا انواع فوری ، یعنی کلاسهای فوق العاده module کلاس: object وت module خود اما sum ویژگی ای از آن نیست module یا objectبشر

بنابراین ، در حالی که sum یک ویژگی از torch و روشی از torch.Tensor و نمونه های آن ، این یک روش نیست torch، چه رسد به یک روش استاتیک torchبشر

ماژول هایی مانند torch، به نظر می رسد ، اشیاء موجود در پایتون هستند ، زیرا آنها نمونه هایی از آن هستند module کلاس. تقریباً همه چیز در پایتون یک شیء است ، از جمله کلاس ها و نمونه هایی مانند int وت bool که ممکن است انتظار داشته باشید که ابتدایی باشد ، مانند انواع مربوطه در زبان های دیگر. این توضیح می دهد که چگونه torch با وجود اینکه یک ماژول به جای یک کلاس یا رابط است ، می تواند ویژگی هایی داشته باشد. . torch یک رابط است ، نه اینکه به طور آزمایشی حاکم بر این باشد که بر اساس torchداشتن یک عملکرد قابل تماس.)

پس چگونه انجام می شود torch وت torch.Tensor ویژگی را داشته باشید sum مشترک؟ این نمی تواند باشد Tensor عملکرد را به ارث می برد sum از torchبشر نه می تواند torch وت Tensor ارث sum از نوعی غیر از Tensorبشر این امر به این دلیل است که فقط انواع ، نه ماژول ها ، می توانند در رابطه وراثت قرار بگیرند.

آنچه اتفاق می افتد این است که Tensor مشتق کردن sum از torch، اما از طریق مکانیسم متفاوتی نسبت به وراثت. تابع sum در ابتدا در ماژول تعریف شده است torch، و متعاقباً sum با کلاس همراه است Tensorبشر حداقل دو روش وجود دارد که می توان این کار را انجام داد: در داخل و خارج از تعریف Tensorبشر در اینجا چگونه می توان به تعریف کلاس نگاه کرد:

def sum(input, dim, keepdim=False, *, dtype=None):
    # Insert body

class Tensor:
    def sum(self, dim, keepdim=False, *, dtype=None):
        return sum(self, dim, keepdim, dtype)
    # Insert rest of class definition
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

و خارج از تعریف کلاس:

def sum(input, dim, keepdim=False, *, dtype=None):
    # Insert body

class Tensor:
    # Insert class definition

Tensor.sum = sum
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

(توجه: ما تصور می کنیم یکی از قطعه های کد فوق در برخی از پرونده ها موجود است torch دایرکتوری ماژول/بسته.) به هر صورت ، این میراث واقعی نیست. این در حال استفاده مجدد است torch اجرای ماژول از sum اجرای Tensor.sum، یا از طریق دعوت از torch.sum در تعریف Tensor.sum، یا از طریق وصله میمون (اختصاص دادن torch.sum به Tensor.sum، بعد از Tensor تعریف شده است) ما در موعد مقرر خواهیم دید که کدام یک از این دو رویکرد توسعه دهندگان پیوکتورچ باید انجام داده اند ، با فرض اینکه هیچ رویکردی سوم که من از آن غافل شده ام وجود ندارد.


بیایید یک بار دیگر به امضای عملکرد از اسناد نگاه کنیم: torch.sum(input,dim,keepdim=False,*,dtype=None)بشر چهار پارامتر وجود دارد که وجود دارد inputبا dimبا keepdimوت dtype، به این ترتیب ویژگی sum از tensor باید داشته باشد حداقل این چهار پارامتر نیز از آنجا Tensor.sum وت torch.sum در اصل همان عملکرد هستند. اعطا می شود ، یک فرصت خوب وجود دارد tensor.sum با اولین پارامتر خود به روشی متفاوت از torch.sum انجام می دهد. برای torch.sum در سطح ماژول تعریف می شود ، در حالی که tensor.sum به طور محتمل در سطح کلاس تعریف می شود (همانطور که در بلوک کد اول بالا نشان داده شده است). فرض کنید اینگونه است tensor.sum تعریف شده است بیشتر فرض کنید که این یک روش غیر استاتیک است. سپس اولین پارامتر آن نمونه کلاس است که در آن عملکرد نامیده می شود. این دقیقاً نحوه کار روشهای غیر استاتیک در پایتون است. بنابراین اولین پارامتر از سمت چپ اپراتور DOT آمده است ، نه آغاز لیست استدلال های محصور در پرانتز. با این وجود ، اولین پارامتر برای دریافت تانسور در نظر گرفته شده است ، همانطور که اولین پارامتر از torch.sumبشر علاوه بر این ، من فکر می کنم با اطمینان می توانیم فرض کنیم پارامترهای باقیمانده از سه پارامتر آخر قابل تشخیص نیستند torch.sumبشر

اکنون ، کدام پارامترها کدام آرگومان را در عملکرد تماس می گیرند tensor.sum(1) وت tensor.sum(1, keepdim=True)؟ به یاد بیاورید که ما دو سناریو متقابل منحصر به فرد را در حال شمارش هستیم: (الف) که در نتیجه وصله میمون ، tensor.sum وت torch.sum پارامترهای یکسانی دارند ، و (ب) که به دلیل tensor.sumدر یک کلاس تعریف شده است ، tensor.sum وت torch.sum با توجه به منبع پارامتر اول متفاوت است. ما می توانیم با توجه به اینکه اولین استدلال محصور در پرانتز است ، رد کنیم (الف) 1 در هر دو tensor.sum(1) وت tensor.sum(1, keepdim=True)بشر بنابراین (الف) و این واقعیت که 1 به عنوان یک استدلال موقعیتی منتقل می شود ، 1 اولین استدلال ، دوره است. به جای اینکه برای dim، برای آن گذشت inputبشر اما مانند input و برخلاف keepdim وت dtypeبا dim فاقد یک مقدار پیش فرض است. اینقدر dim به هیچ وجه مقداری اختصاص نمی یابد. مطمئناً اگر اینگونه بود ، tensor.sum(1) وت tensor.sum(1, keepdim=True) حداقل یک TypeErrorبشر اولین خطایی که پایتون به احتمال زیاد مطرح می کند چیزی شبیه به:

TypeError: sum(): argument 'input' (position 1) must be Tensor, not int
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اما در صورت عدم موفقیت ، پایتون بدون شک این خطا را مطرح می کند:

TypeError: sum() missing 1 required positional argument: "input"
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

از آنجا که هیچ یک از این دو خطا در واقع مطرح نشده است ، ما نشان داده ایم که (الف) اینگونه نیست. مگر اینکه من از سناریوی سوم ، (ج) غافل شده باشم ، این تنها یک امکان در رابطه با پارامترهای پارامترها را به وجود می آورد tensor.sum و مواردی از torch.sum: (ب). یعنی اولین استدلال tensor.sum، کدام عملکرد در یک کلاس تعریف شده است ، باید هر آنچه در سمت چپ اپراتور DOT باشد باشد (برخلاف اولین استدلال torch.sum، که اولین مورد در لیست محصور در پرانتز در تماس عملکرد است). در دعوت نامه ها tensor.sum(1) وت tensor.sum(1, keepdim=True)، یعنی tensorبشر

من ممکن است از خودم جلو بروم. یک عارضه وجود دارد که من هنوز در مورد آن بحث نکرده ام ، که ممکن است استنباط ما را مسدود کند (ب). این عارضه است ، torch.sum بیش از حد بارگذاری شده است ، بنابراین دارای یک لیست پارامتر جایگزین است:

https%3A%2F%2Fdev to uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjab9hkrrjrj3h4v533t7

فقط یکی از پارامترهای این اضافه بار ، یعنی input، فاقد یک مقدار پیش فرض است.

بیایید تصریح کنیم که ، به ازای هر پیشنهاد (الف) Tensor میمون مورد استفاده قرار گرفته است تا یک ویژگی یکسان با آن داشته باشد torch.sumبشر به این نتیجه می رسد که tensor.sum بیش از حد اضافه شده است torch.sum دارد بنابراین حتی اگر فقط یک استدلال بین پارنز تصویب شود ، تا زمانی که این استدلال از نوع صحیح باشد ، هیچ خطایی نخواهد بود. اما در آنجا مالش نهفته است. اولین استدلال اضافه بار torch.sum(input, *, dtype=None) انتظار می رود یک تانسور است. اینقدر tensor.sum(1) هنوز یکی از خطاهای ذکر شده در گذشته را افزایش می دهد:

TypeError: sum(): argument 'input' (position 1) must be Tensor, not int
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اما ، برخلاف پیش بینی عجول قبلی من ، خطای استدلال از دست رفته مطرح نمی شود. علاوه بر این ، پایتون تفسیر می کند tensor.sum(1, keepdim=True) به عنوان یک دعوت از اضافه بار با لیست پارامتر بزرگتر ، زیرا فقط این اضافه بار پارامتر نام دارد keepdimبشر بنابراین ، چه زمانی tensor.sum(1, keepdim=True) اعدام شده است ، ما باید انتظار داشته باشیم که پایتون هر دو خطایی را که قبلاً پیش بینی کرده ام مطرح کند.

باز هم ، این همه بر این فرض است که (الف) درست است. از آنجا که این پیام های خطا در واقع مطرح نشده اند ، ممکن است استنباط کنیم که (الف) نادرست است. بنابراین ، نتیجه گیری اصلی ما است: (ب) درست است. به این نتیجه می رسد که tensor برای input در tensor.sum(1) وت tensor.sum(1, keepdim=True)بشر فقط یک تجدید نظر اضافی وجود دارد که می تواند به تصور ما از اجرای آن بپردازد Tensor.sumبشر پس از tensor.sum() وت torch.sum(tensor) همان مقدار را برگردانید ، tensor.sum باید بیش از حد بارگیری شود torch.sum معنی دارد torch.sum وت Tensor.sum هر کدام دو تعریف داشته باشید:

def sum(input, dim, keepdim=False, *, dtype=None):
    # Insert body

def sum(input, *, dtype=None):
    # Insert body

class Tensor:
    def sum(self, dim, keepdim=False, *, dtype=None):
        return sum(self, dim, keepdim, dtype)

    def sum(self, *, dtype=None):
        return sum(self, dtype)

    # Insert rest of class definition
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در این مرحله ما می توانیم به طور مستقیم مقادیر را مشخص کنیم dimبا keepdimوت dtype دریافت اگر آرگومان های موقعیتی/غیر کلید واژه را در دعوت بگذریم tensor.sum(1) به torch.sum به عنوان استدلال کلمات کلیدی ، ما دریافت می کنیم torch.sum(input=tensor, dim=1, keepdim=False, dtype=None)بشر این دو دعوت معادل هستند. همچنین معادل (به یکدیگر) دعوت نامه ها هستند tensor.sum(1, keepdim=True) وت torch.sum(input=tensor, dim=1, keepdim=True, dtype=None)بشر بنابراین ، با توجه به چگونه Tensor.sum از نظر تعریف شده است torch.sumبا tensor.sum(1) وت tensor.sum(dim=1, keepdim=False, dtype=None) معادل هستند ، و همینطور هستند tensor.sum(1, keepdim=True) وت tensor.sum(dim=1, keepdim=True, dtype=None)بشر


در پست بعدی من در این سری ، قول می دهم آنچه را که در وهله اول انجام داده ام انجام دهم: به سوال آندره کارپتی پاسخ دهید.

نوشته های مشابه

دیدگاهتان را بنویسید

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

دکمه بازگشت به بالا