sequence to sequence Model

مدل seq2seq یکی از مدل های مورد استفاده در سیستم‌های تولید پاسخ است که می تواند احتمال تولید پاسخ مناسب را بیشینه کند.

مدل رمزنگار-رمزگشا LSTM (encoder-decoder) یک شبکه عصبی بازگشتی برای مسائلی است که یک دنباله را به دنباله دیگر نگاشت می‌کند. (یک دنباله به عنوان ورودی دریافت می کند و خروجی، دنباله دیگری است.) به همین دلیل به آن مدل seq2seq نیز گفته می‌شود. در مسائل seq2seq دنباله ورودی و خروجی می‌توانند دارای طول های متفاوتی باشند به همین دلیل این مسائل از اهمیت زیادی برخوردار بوده و چالش برانگیزند.

مدل seq2seq، در مسائلی چون ترجمه ماشینی، خلاصه‌کردن متن و تشخیص گفتار کاربرد دارد. به طور مثال در ترجمه ماشینی سنتی، جمله‌ها به چند قسمت تقسیم می‌شوند و هر قسمت به صورت جداگانه ترجمه می‌شود که منجر به اختلال در خروجی ترجمه‌ می‌گردد. این در حالی است که انسان ها برای ترجمه یک جمله ابتدا معنای آن را متوجه می‌شوند سپس جمله را ترجمه می‌کنند. مدل seq2seq در ترجمه ماشینی از روش انسان گونه‌ی ترجمه پیروی می‌کند.

این معماری از ترکیب دو مدل تشکیل شده است:

۱) رمزنگار (Encoder)

۲) رمزگشا (Decoder) 

شبکه رمزگشا(decoder)، خروجی (state) شبکه رمزنگار (encoder) را به عنوان ورودی دریافت می کند.

مثلا جمله ای یا سوالی به عنوان ورودی به شبکه بدهیم و پاسخی به عنوان خروجی دریافت کنیم.

مثال : جمله فرانسوی زیر را در نظر بگیرید قصد داریم این جمله به عنوان  ورودی به Encoder بدهیم و معادل یا ترجمه آن را به انگلیسی از Decoder دریافت کنیم.

 

Image-captioning به روش Encoder-Decoder

با وارد کردن یک عکس به عنوان ورودی به یک شبکه  pretrained مثل (VGG16,AlexNet,…) و پس از استخراج ویژگی ها، لایه آخر که softmax می باشد را حذف می کنیم و لایه ماقبل آن (۴۰۹۶تایی) را به عنوان ورودی به شبکه بعدی (Decoder) می دهیم.

ماشین ترجمه ( Mashine translation )، به عنوان ساختمان یک مدل زبان شرطی (conditional language model) عمل می کند.خروجی هر مرحله، ورودی مرحله بعدی است که می خواهیم p  در آن به حداکثر مقدار برسد.

یک Mashine translation و یک language model  از نظر ساختار و کاربرد با یکدیگر فرقی ندارند و دو شبکه باهم برابر هستند. هر دو زبان مبدا را به عنوان ورودی دریافت می کنند و زبان مقصد را به عنوان خروجی تولید (generate) می کنند.تنها تفاوت آن ها در این است که language model یک وکتور ۰ را به عنوان ورودی اولیه می گیرد ولی Mashine translation ، خروجی (state) مرحله قبلی را به عنوان ورودی می گیرد.

مدل زبان شرطی، احتمال تولید جمله خروجی را به شرط دریافت جمله ورودی برمی گرداند.

الگوریتم حریصانه (greedy)

الگوریتم حریصانه  شبیه روش‌های پویا اغلب برای حل مسائل بهینه سازی استفاده می‌شوند.این الگوریتم بهترین انتخاب را با توجه به شرایط مسئله انجام می‌دهد به امید آنکه با ادامهٔ همین روش بهینه‌سازی انجام شود.,ولی در مدل زبان شرطی (Conditional Languge model) اغلب به پاسخ درستی نمی رسیم.

به عنوان مثال جمله ی فرانسوی زیر را در نظر بگیرید :

از بین ترجمه های زیر ، ترجمه ی اول به عنوان ترجمه درست می باشد ولی با استفاده از الگوریتم حریصانه ترجمه دوم به عنوان ترجمه درست انتخاب می شود که نشان دهنده ی  آن است که الگوریتم حریصانه روش مناسبی نیست.

الگوریتم Beam Search

در این الگوریتم پارامتری به نام beam width داریم که به تعداد آن محتمل ترین ها را در مرحله اول برمیداریم به طول مثال همان طور که در شکل زیر می بینید فرض کنید یک دیکشنری ۱۰۰۰۰تایی داشته باشیم و B = ۳ باشد در این صورت ۳ کلمه را به عنوان محتمل ترین انتخاب می کنیم و احتمال آن را محاسبه می کنیم.

در مرحله بعد هر کدام از کلماتی که انتخاب کردیم از ۱۰۰۰۰تا کلمه دیگر باید کلمه محتمل بعدی را انتخاب کنند که در این حالت ۳۰۰۰۰تا حالت داریم  و این مراحل را تا جایی ادامه می دهیم که به <EOS> برسیم و احتمالات آن هارا محاسبه می کنیم.

این روش مشکلاتی نیز دارد. زمانی که تعدادی عدد بین ۰ و ۱ در هم ضرب شود عددی که به دست می آید آنقدر کوچک می شود که ممکن است کامپیوتر قادر به ذخیره سازی آن نباشد.(under flow رخ می دهد.)

برای حل این مشکل از تابع لگاریتم که روند افزایشی-صعودی دارد استفاده می کنیم.(تابع لگاریتم بین ۰ و ۱ مقادیر منفی دارد.)به صورت زیر  :در این مرحله هنوز وابسته به طول خروجی می باشد برای حل این مشکل تقسیم بر طول جمله می کنیم.(به صورت زیر)

اصلاحات روش Beam search

در production اعداد بیشتری را برای Beam width می گذاریم ولی در research اعداد کمتری می گذاریم.کوچک یا بزرگ گذاشتن Beam width هر کدام مزایا و معایبی دارد.

زمانی که Beam width را بزرگ انتخاب کنیم از فضای کلی مسئله فضای بیشتری را پوشش می دهد و احتمال اینکه به جواب درست برسیم بیشتر است و نتیجه بهتری می دهد ولی سرعت آن کمتر می باشد.

زمانی که Beam width را کوچک انتخاب کنیم احتمال اینکه به جواب درست برسیم کمتر است و فضای کمتری از مسئله را پوشش می دهد ولی سرعت آن بیشتر می باشد.برخلاف الگوریتم های BFS و DFS که بهترین ها را انتخاب می کنند این روش لزوما بهترین ها را انتخاب نمی کند.

آنالیز ارورهای روش Beam search

مثال:

جمله فرانسوی زیر را در نظر داشته باشید.ترجمه ی اول، ترجمه ی درست و ترجمه ی دوم، ترجمه ای است که شبکه تولید کرده است.

دو حالت برای اشتباه ترجمه کردن توسط شبکه وجود دارد :

۱)RNN(تعداد دیتای آموزش دیده کم باشد.)

 ۲)Beam width(مقدار آن کم تعیین شده باشد.)

اگر حالت زیر پیش بیاید مشکل از مقدار Beam width می باشد و باید مقدار بیشتری را انتخاب کنیم. واگر حالت زیر پیش بیاید مشکل از RNN هاست و باید آن ها را اصلاح کنیم.

در نهایت این مقایسه برای تمامی جملات ترجمه شده صورت می گیرد که مشکل مشخص شود و اصلاحات صورت بگیرد.

تصاویر دودویی و حد آستانه

به طور کلی ، عکس ها به سه دسته تقسیم می شوند :

  • باینری یا دودویی(Binary)
  • مقیاس خاکستری (Gray scale)
  • رنگی (Color)

تحلیل تصاویر باینری

زمانی که یک تصویر را آنالیز می کنیم یک سری 0 و 1 به دست می آید.
0، پس زمینه را نشان می دهد.
1، پیش زمینه را نشان می دهد.

                                    

کاربرد های تحلیل تصاویر باینری :

  • بررسی قسمت ها
  • در صنعت و تولید
  • پردازش اسناد متنی

 

(عکس سمت راست خوب باینری نشده است( مناسب نبودن مقدار حد آستانه))

 

 کارهایی که می توانیم با باینری کردن تصاویر انجام دهیم :

  • جدا کردن یک شی از پس زمینه
  • متراکم کردن پیکسل های یک شی
  • محاسبه و استخراج ویژگی های یک شی

مثال – تصویر سلول گلبول قرمز

کاربرد: برای مثال برای تسریع در شمارش گلبول‌های قرمز در تصاویر پزشکی می‌توان از پردازش تصویر استفاده کرد.

مشکل: اما اگر بخواهند تعداد گلبول های قرمز را بشمارند با باینری کردن تصویر یکی از مشکلاتی که ممکن است پیش بیاید این است که چند  گلبول به یکدیگر چسبیده باشند و یا یک حفره وجود داشته باشد و نویزهایی درون تصویر وجود داشته باشد.

برای دودویی  کردن تصویر و حل مشکلی که در مثال شمارش گلبول‌های قرمز بیان شد و سایر کاربردهای مفید در ایجاد و تحلیل تصاویر دودوبی برخی از عملکردها روی تصاویر معرفی شده است که در ادامه به صورت مختصر تشریح میگردد.

عملکرد های مفید

  • آستانه گذاری یک تصویر در مقیاس خاکستری ( gray scale )
  • تعیین کردن حد آستانه مناسب
  • تحلیل اجزای متصل به هم
  • مورفولوژی دودویی ریاضی
  • انواع استخراج ویژگی، ثابت ( محیطی، مرکزی، مداری، …)

آستانه گذاری

تعریف مختصر:

برای تبدیل یک تصویر gray scale یا مقیاس خاکستری به تصویر دودویی باید یک حد آستانه (Threshold) تعیین کنیم و تمام پیکسل‌های دارای مقدار کمتر از حد آستانه را 0 و تمام پیکسل‌های دارای مقدار بیشتر از حد آستانه را 1 (یا 255) کرد.

آستانه گذاری در OpenCV:

همان طور که بیان شد برای تبدیل تصویر gray scale به تصویر دودویی از آستانه گذاری استفاده میکنیم.

در OpenCV نیز این عملیات پیاده سازی شده و اگر مقدار پیکسلی بیشتر از مقدار threshold ( حد آستانه ) باشد، یک مقدار به آن تعلق می گیرد ( ممکن است آن مقدار سفید باشد. )
درغیر آن صورت مقدار دیگری به آن تعلق می گیرد ( ممکن است آن مقدار سیاه باشد. )

تابعی که در OpenCV برای آستانه گذاری  استفاده می شود، cv2.threshold می باشد

  • پارامتر اول آن تصویر منبع (  image ) می باشد که باید یک تصویر در مقیاس خاکستری ( gray-scale ) باشد.
  • پارامتر دوم، مقدار حد آستانه ( threshold ) می باشد، که برای دسته بندی مقادیر پیکسل ها استفاده می شود.
  • پارامتر سوم، بیشترین مقدار ( Max value ) می باشد، که مقداری را نشان می دهد که اگر پیکسلی از مقدار حد آستانه ( threshold value ) بیشتر ( در مواردی ممکن است کمتر ) باشد، Max value به آن مقدار تعلق میگیرد.
  • پارامتر چهارم مربوط به نوع است. OpenCV حالت های مختلفی برای آستانه گذاری تعیین کرده است :
  • cv2.THRESH_BINARY
  • cv2.THRESH_BINARY_INV
  • cv2.THRESH_TRUNC
  • cv2.THRESH_TOZERO
  • cv2.THRESH_TOZERO_INV

 

 مثال آستانه گذاری

آستانه گذاری به روش Ostu 

در آستانه گذاری سراسری ( global thresholding )، یک مقدار دلخواه برای مقدار حد آستانه ( threshold ) استفاده می شود.
سوالی که پیش می آید این است که مقدار انتخاب شده مناسب است یا خیر؟!
پاسخ : متد آزمایش و خطا
اما با فرض یک تصویر biomodel، ( به بیان ساده تر، تصویر biomodel  تصویری است که histogram دو قله ( یا حداکثر ) دارد. )
برای این تصویر ما می توانیم تقریبا حد وسط قله ها را برای مقدار حد آستانه در نظر بگیریم. یعنی کاری که در روش ostu انجام می شود. به صورت خودکار مقدار حد آستانه از تصویر histogram  برای  تصویر biomodel  محاسبه می شود.

مثال: پس زمینه مشکی است و گیلاس سالم روشن است و قسمت های ضرب دیده تیره متوسط است.

نمودار هیستوگرام (Histogram) دو قسمت از گیلاس را نشان می دهد. ( پس زمینه ی مشکی حذف شده است. )

 

 

در پردازش تصویر، (balanced histogram thresholding (BHT یک متد بسیار ساده است (مثل روش ostu ) و متد lterative selection thresholding یک histogram بر مبنای متد آستانه گذاری ( thresholding ) می باشد.
این رویکرد تصویر را به دو کلاس اصلی تقسیم می کند :

  • پس زمینه ( Background )
  • پیش زمینه ( Foreground )

BHT سعی دارد سطح آستانه ( threshold ) را بهینه کند و histogram را به دو کلاس تقسیم می کند.
این متد histogram را می سنجد که بررسی می کند کدام بخش سنگین تر است و وزن را از بخش سنگین تر حذف کند تا روشن تر شود.

آستانه گذاری تطبیقی

در موارد قبلی، ما از مقدار های سراسری ( global ) به عنوان مقدار حد آستانه ( threshold value ) استفاده کردیم. اما در همه ی شرایط ممکن نیست این مقدار مناسب باشد؛ مثلا در مکانی که عکس شرایط روشنایی متفاوتی دارد، در این موارد ما به آستانه گذاری تطبیقی ( Adaptive theesholding ) رجوع می کنیم که الگوریتم، مقدار حد آستانه را برای نواحی کوچک تصویر محاسبه می کند. بنابراین ما به حد آستانه های متفاوتی برای نواحی مختلف همان تصویر می رسیم.
نتیجه: آستانه گذاری تطبیقی ( adaptive thresholding )، نتایج بهتری برای تصاویر با روشنایی متفاوت به نمایش می گذارد.

متد تطبیقی

  • cv2.ADAPTIVE_THRESH_MEAN_C  مقدار حد آستانه ( threshold )، میانگین مقادیر نواحی همسایه می باشد.
  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C  مقدار حد آستانه ( threshold )، جمع وزنی مقادیر نواحی همسایه می باشد.

آستانه گذاری در پایتون و OpenCV

آستانه گذاری در پایتون و numpy

در ابتدا با numpy تصویر را باینری می‌کنیم.

در این کد با بارگذاری کردن تصویر gray scale، به رنگ های کمتر از حد آستانه ( 127 ) را صفر تعلق می گیرد ( سفید ) و به رنگ های بیشتر از حد آستانه ( 127 )  255 تعلق می گیرد.( سیاه )

نکته :
دلیل اینکه از np.copy استفاده می کنیم این است که اگر به این صورت باشد : ( Newimage = image )
در واقع به یک مکان از حافظه دو اشاره گر اشاره می کند که در این صورت عکس اصلی ( اولیه) خراب می شود.

آستانه گذاری در OpenCV

برای اینکار می‌توانیم از تابع threshold در opencv نیز استفاده کنیم

پس از بارگذاری عکس، این بار به کمک تابع threshold که در آن حد آستانه 127 تعیین شده است، به مقادیر کمتر از این مقدار 0 تعلق می گیرد و به مقادیر بیشتر از این مقدار 1 تعلق می گیرد و نوع آن به صورت باینری (سیاه و سفید) تعیین شده است. ( در اینجا ret نشان دهنده ی حد آستانه است. )

پارامترهای مختلف تابع threshold

در این کد پارامتر چهارم (threshold types) بررسی شده است.

  : cv2.THRESH_BINARY

به مقادیر کمتر از حد آستانه (  127 )،  0 تعلق می گیرد ( سفید ) و به مقادیر بیشتر از حد آستانه،  255 تعلق می گیرد ( سیاه ).

 : cv2.THRESH_BINARY_INV

به رنگ های کمتر از حد آستانه (  127 )، 255 تعلق می گیرد ( سیاه ) و به رنگ های  بیشتر از حد آستانه،  0 تعلق می گیرد ( سفید ).(برعکس مورد قبل)

 : cv2.THRESH_TRUNC

مقادیر بیشتر از حد آستانه بریده می شوند. ( 255 بدون استفاده می ماند. )

 : cv2.THRESH_TOZERO

مقادیر بیشتر از حد آستانه تغییر نمی کنند. و به مقادیر کمتر از حد آستانه، 0 تعلق می گیرد.

 : cv2.THRESH_TOZERO_INV

مقادیر کمتر از حد آستانه تغییر نمی کنند.و به مقادیر بیشتر از حد آستانه، 0 تعلق می گیرد.

یک مثال عملی از دودویی کردن تصویر در OpenCV

در ابتدا به کمک فیلتر ها نویزها را برطرف می کنیم زیرا thresholding ها local هستند باعث ایجاد نویز در تصویر می شوند.در آخر از ostu استفاده می کنیم چون ostu حد آستانه را مشخص می کند تصویر بهتری در خروجی نشان می دهد. ( ممکن است در روش های قبل threshold حد آستانه را درست تعیین نکرده باشیم. )

خروجی ها به صورت زیر است :

نتیجه گیری : ostu تصویر بهتری در خروجی نشان می دهد.

 

threshold Binary

: Adaptive thresholding

: Gaussian ostu thresholding 

 : ostu thresholding

 : Adaptive thresholding with Gaussian