نقوم بإنشاء مجموعة بيانات للتعرف على العدادات على Yandex.Tolok



قبل عامين ، من خلال تشغيل التلفزيون عن طريق الخطأ ، رأيت قصة مثيرة للاهتمام في برنامج Vesti. قيل إن إدارة تكنولوجيا المعلومات في موسكو تقوم بإنشاء شبكة عصبية ستقرأ قراءات عدادات المياه من الصور الفوتوغرافية. في القصة ، طلب مقدم العرض التلفزيوني من سكان المدينة مساعدة المشروع وإرسال صور لعداداتهم إلى بوابة mos.ru من أجل تدريب شبكة عصبية عليها.


إذا كنت أحد أقسام موسكو ، فإن إصدار مقطع فيديو على القناة الفيدرالية واطلب من الناس إرسال صور العدادات ليس مشكلة كبيرة. ولكن ماذا لو كنت شركة صغيرة ولا يمكنك عمل إعلان على قناة تلفزيونية؟ كيفية الحصول على 50000 صورة من العدادات في هذه الحالة؟ Yandex.Toloka يأتي لانقاذ!


Yandex.Toloka هي عبارة عن منصة التعهيد الجماعي التي يقوم بها أشخاص من جميع أنحاء العالم بمهام بسيطة ، حيث يتلقون أموالًا مقابل ذلك. على سبيل المثال ، يمكن لمستخدمي tolokers العثور على المشاة في الصورة وتدريب المساعدين الصوتيين والمزيد . في الوقت نفسه ، لا يمكن لموظفي Yandex فقط ، ولكن أي شخص يرغب في نشر المهام على Toloka.


بيان المشكلة


لذلك ، نريد إنشاء شبكة عصبية ، والتي من الصورة ستحدد قراءات العدادات. من أين نبدأ ، ما هي البيانات التي نحتاجها؟


بعد التشاور مع الزملاء ، نستنتج أنه من أجل إنشاء MVP ، نحتاج إلى 1000 صورة مضادة. علاوة على ذلك ، لكل عداد نريد أن نعرف القراءات الحالية ، وكذلك إحداثيات النافذة بالأرقام.


إذا لم تكن قد عملت مطلقًا مع Toloka ، أنصحك بقراءة المقال الذي كتبته قبل عام. نظرًا لأن المقالة الحالية ستكون أكثر تعقيدًا من الناحية الفنية ، سأحذف بعض النقاط الموضحة بالتفصيل في المقالة السابقة.


شكر

أصبحت المادة السابقة أعلى -2 في تصنيف المقالات من مجتمع المواد المستنفدة للأوزون . شكرا لتعليقك ووضع الايجابيات!)



الجزء 1. الحصول على الصور


ما يمكن أن يكون أسهل؟ ما عليك سوى مطالبة الشخص بفتح تطبيق Yandex.Tolok على هواتفه والتقاط صورة لعداده. إذا لم أعمل مع Toloka منذ عدة سنوات ، فكانت تعليمي هو: "أنت بحاجة إلى تصوير عداد المياه (ساخن أو بارد) وترسل لنا صورة . "


لسوء الحظ ، مع مثل هذا البيان للمشكلة ، لا يمكن جمع مجموعة بيانات جيدة. الشيء هو أن الناس يمكنهم تفسير هذه المعارف التقليدية بطرق مختلفة ، حيث لا تحتوي التعليمات على معايير واضحة لمهمة مكتملة بشكل صحيح. يمكن إرسال Tolockers:


  • الصور ضبابية.
  • الصور التي لا تظهر الأدلة
  • الصور مع عدادات متعددة.

تحتوي مدونة Toloka على برنامج تعليمي رائع حول كيفية كتابة التعليمات. تبعته ، حصلت على هذه التعليمات:

كمعلمات إدخال ، نقوم بتمرير معرف المهمة ، وفي الإخراج نحصل على ملف img ، والذي سيحتوي على صورة العداد.




واجهة الوظيفة مكتوبة في سطرين فقط!




عند إنشاء تجمع ، فإننا نشير إلى الوقت لإكمال المهمة ، وقبول التأخير وسعر المهمة 0.01 دولار.




وحتى لا يكمل الأشخاص المهمة عدة مرات ولا يرسلون الصور نفسها ، فإننا نحظر التنفيذ المتكرر للمهمة في كتلة مراقبة الجودة.




نشير إلى أننا نحتاج إلى مستخدمين ناطقين بالروسية يكملون المهمة من خلال تطبيق Yandex.Tolok للهاتف المحمول.




تنزيل المهام إلى التجمع.




نبدأ المجموعة ونفرح وننتظر ردود المستخدمين! هكذا تبدو مهمتنا من جانب toloker:



الجزء 2. قبول المهام


بعد الانتظار بضع ساعات ، نرى أن tolkers أكمل المهمة. نظرًا للتأخير في القبول ، لا يتم دفع الجائزة إلى المقاول فورًا ، ولكن يتم تجميدها في الميزانية العمومية للعميل ، والآن يتعين علينا التحقق من جميع الصور المرسلة. لكي يقبل فناني الأداء حسن النية المهام ، وبالنسبة لفناني الأداء الذين يرسلون صورًا غير مناسبة للمعايير ، يرفضون ويكتبون سبب الرفض.


إذا لم يكن هناك الكثير من الصور ، فيمكننا مشاهدة جميع الصور المرسلة بأنفسنا والتحقق منها. لكننا نريد الحصول على آلاف وعشرات الآلاف من الصور! سيتطلب التحقق من حجم المهام هذا مقدارًا كبيرًا من الوقت. بالإضافة إلى ذلك ، تتطلب هذه العملية مشاركتنا مباشرة.


تولوكا يأتي لإنقاذ مرة أخرى! يمكننا إنشاء مهمة جديدة "التحقق من الصور المضادة" ونسأل tolkers آخرين للإجابة عما إذا كانت الصورة تتوافق مع معاييرنا أم لا. من خلال إعداد العملية مرة واحدة ، نحصل على جمع البيانات التلقائي بالكامل والتحقق من صحة! في نفس الوقت ، يمكن جمع البيانات بسهولة ، وإذا كنا بحاجة إلى زيادة حجم مجموعة البيانات عدة مرات ، فقط انقر فوق اثنين من الأزرار.


تبدو مذهلة وكبيرة ، أليس كذلك؟
ثم حان الوقت لوضع الفكرة موضع التنفيذ!


بادئ ذي بدء ، سنحدد المعايير التي سنعتبر بها الصورة جيدة.
الصورة جيدة إذا:


  • يوجد في الصورة عداد واحد للمياه الباردة أو الساخنة.
  • قراءات على العداد واضحة للعيان.

في حالات أخرى ، تعتبر الصورة سيئة.


قمنا بفرز المعايير ، والآن نكتب تعليمات!

كمعلمات الإدخال نقوم بتمرير الرابط إلى الصورة. سوف يكون الإخراج علامتين:


  • check_count - الإجابة على السؤال الأول
  • check_quality - الإجابة على السؤال الثاني

سيتم كتابة العداد إلى متغير القيمة.




تأخذ واجهة هذه المهمة بالفعل 14 سطرًا.




لزيادة الدقة ، سيتم فحص صورة واحدة بشكل مستقل بواسطة 5 tokers ، لذلك سنضع تداخلًا بين 5. وبعد ذلك ، سننظر في كيفية استجابة 5 أشخاص ونفترض أن الإجابة الصحيحة هي التي صوتت بها الأغلبية. هذه المهمة لن تؤخر القبول.




دعنا نعترف 50 ٪ من أفضل أداء لهذه المهمة.




في المهام دون تأخر القبول ، يتلقى الجميع الدفع ، بغض النظر عما إذا كانوا يؤدون المهمة بشكل صحيح أم لا. ولكننا نريد أن يقرع tolokers الإرشادات بعناية ، وأن يحاولوا إكمال المهمة بشكل صحيح. كيف يمكن تحقيق ذلك؟


هناك نوعان من الأدوات الرئيسية في Tolok تتيح لك الحفاظ على نوعية جيدة:


  1. التعليم. قبل إكمال المهمة الرئيسية ، يمكننا أن نطلب من المدربين التدريب. في مجموعة التدريب ، يتم إعطاء الأشخاص المهام التي نعرف الإجابات الصحيحة عنها مسبقًا. إذا أجاب شخص بطريقة غير صحيحة ، فسيظهر خطأ له وشرح كيفية الإجابة. بعد الانتهاء من التدريب ، نرى النسبة المئوية للمهام التي أنجزها المؤدي ويمكننا فقط السماح لأولئك الذين قاموا بعمل جيد بمجموعة المهام الرئيسية.
  2. كتل مراقبة الجودة. قد يكون تجمع التدريب ممتازًا بالنسبة لفناني الأداء ، فقد سُمح لنا بالقيام بذلك ، لكن بعد خمس دقائق غادر للعب كرة القدم ، وترك شقيقه البالغ من العمر ثلاث سنوات على الكمبيوتر. لحسن الحظ ، هناك العديد من الأساليب في Tolok التي تسمح لك بتتبع كيفية إكمال الأشخاص للمهام.

مع مجموعة التدريب ، يكون كل شيء بسيطًا: ما عليك سوى إضافة المهام ووضع علامات عليها في واجهة Yandex.Tolki وتحديد الحد الأدنى للمرور ، حيث نسمح للأشخاص بالقيام بالمهمة الرئيسية.




مع وحدات مراقبة الجودة ، كل شيء أكثر إثارة للاهتمام: هناك الكثير منهم ، لكنني سأركز على أهم اثنين.


رأي الأغلبية
نعطي المهمة ل 5 أشخاص مستقلين. وإذا أجاب أربعة أشخاص "نعم" على السؤال ، وأجاب الخامس "لا" ، فمن المحتمل أن يكون الخامس قد أخطأ. وبالتالي ، يمكننا مشاهدة مدى انسجام إجابات الشخص مع إجابات الأشخاص الآخرين ، وحظر المستخدمين الذين يستجيبون بشكل مختلف عن الآخرين.




مهام التحكم
يمكننا مزج المهام في المجموعة ، التي نعرف الإجابة الصحيحة عليها مسبقًا. في الوقت نفسه ، تبدو مهام مراقبة الجودة مثل المهام العادية. على أساس ما إذا كان الشخص يجيب على مهام التحكم بشكل صحيح ، يمكننا أن نقدر ونفترض ، بشكل صحيح أم لا ، أنه يحل جميع المهام الأخرى التي لا نعرف الإجابات عنها. إذا كان رد فعل شخص ما ضعيفًا للسيطرة على المهام ، فيمكننا حظره ، وإذا كان جيدًا ، فعندئذٍ نقدم مكافأة.




الصيحة ، تم إنشاء المهمة! هذا ما تبدو عليه الواجهة من المنفذ:




الجزء 3. الانضمام إلى وظائف


عظيم ، المهام جاهزة! ولكن السؤال الذي يطرح نفسه ، وكيفية ربط المهام مع بعضها البعض؟ كيفية جعل الجولة الثانية بعد المهمة الأولى؟


بالطبع ، يمكنك اللعب مع الدف والقيام بذلك يدويًا من خلال واجهة Toloka ، ولكن هناك طريقة أبسط وأسرع! Yandex.Tolok لديه API ، واستخدامها وكتابة برنامج نصي بيثون!


أعلم أن الكثير منكم لا يحب قراءة الكود ، لذلك أخفته تحت المفسد
import pandas as pd import numpy as np import requests import boto3 #       ,  #  Yandex Object Storage      def load_image_on_yandex_storage(img_id): session = boto3.session.Session( region_name="us-east-1", aws_secret_access_key="", aws_access_key_id="" ) s3 = session.client( service_name="s3", endpoint_url="https://storage.yandexcloud.net" ) file = requests.get( url=URL_API + "attachments/%s/download" % img_id, headers=HEADERS ) s3.put_object(Bucket="schetchiki", Key=img_id, Body=file.content) return "https://storage.yandexcloud.net/schetchiki/%s" % img_id #    API,   ID      TOLOKA_OAUTH_TOKEN = "" POOL_ID_FIRST = 7156932 POOL_ID_SECOND = 7006945 URL_API = "https://toloka.yandex.ru/api/v1/" HEADERS = { "Authorization": "OAuth %s" % TOLOKA_OAUTH_TOKEN, "Content-Type": "application/JSON", } #       ,    url_assignments = ( URL_API + "assignments/?status=SUBMITTED&limit=10000&pool_id=%s" % POOL_ID_FIRST ) submitted_tasks = requests.get(url_assignments, headers=HEADERS).json()["items"] #  ,  ,   id     #  id     url_to_first_id_map = {} first_id_to_second_id_map = {} json_second_task = [] #      : # *   id # *    Yandex Object Storage # *    json    for task in submitted_tasks: first_task_id = task["id"] img_id = task["solutions"][0]["output_values"]["img"] url_img = load_image_on_yandex_storage(img_id) url_to_first_id_map[url_img] = first_task_id json_second_task.append( {"input_values": {"image": url_img}, "pool_id": POOL_ID_SECOND, "overlap": 5} ) #      # " ,  ":   API      , #      API second_tasks_request = requests.post( url=URL_API + "tasks?open_pool=true", headers=HEADERS, json=json_second_task ).json() #     id  . #         ,    for second_task in second_tasks_request["items"].values(): second_task_id = second_task["id"] img_url = second_task["input_values"]["image"] first_task_id = url_to_first_id_map[img_url] first_id_to_second_id_map[first_task_id] = second_task_id #     ,      ,    #        def unknown_fun(k): return list(map(lambda t: t['solutions'][np.where(np.array(list(map(lambda x: x['id'], t['tasks']))) == second_task_id)[0][0]]['output_values'][k], second_task)) #  keys  values  first_id_to_url_map = dict((v, k) for k, v in url_to_first_id_map.items()) db = [] #      ,   2   for first_task_id in first_id_to_second_id_map: #     1 second_task_id = first_id_to_second_id_map[first_task_id] #    2 url_assignments = ( URL_API + "assignments/?status=ACCEPTED&task_id=%s" % second_task_id ) second_task = requests.get(url_assignments, headers=HEADERS).json()["items"] #     value_list = unknown_fun("value") check_count_list = unknown_fun("check_count") check_quality_list = unknown_fun("check_quality") #         «», #      , #     .   if np.sum(check_count_list) < 3: json_check = { "status": "REJECTED", "public_comment": "          ", } #     ,    ,   elif np.sum(check_quality_list) < 3: json_check = { "status": "REJECTED", "public_comment": "     ", } #      else: json_check = { "status": "ACCEPTED", "public_comment": "  ", } url = URL_API + "assignments/%s" % first_task_id result_patch_request = requests.patch(url, headers=HEADERS, json=json_check) #        (values, counts) = np.unique(value_list, return_counts=True) ind = np.argmax(counts) if counts[ind] > 3 and json_check["status"] == "ACCEPTED": print( " : %s.   %d  5 " % (values[ind], counts[ind]) ) #       ,    db.append( { "first_task_id": first_task_id, "second_task_id": second_task_id, "url_img": first_id_to_url_map[first_task_id], "check_count_list": check_count_list, "check_quality_list": check_quality_list, "value_list": value_list, } ) #    pd.DataFrame(db).to_csv("result.csv") 

نعمل على تشغيل الكود ، والنتيجة التي طال انتظارها: مجموعة بيانات الصور المضبوطة المكونة من 871 جاهزة.




السعر


لنقم بتقييم المكون الاقتصادي للمشروع.
للصورة المرسلة في المهمة الأولى ، نحن نقدم 0.01 دولار.
لسوء الحظ ، إذا دفعنا فنان الأداء 0.01 دولار ، فسنضطر إلى دفع 0.018 دولار.
كيف يتم ذلك؟


  • عمولة ياندكس دقيقة (0.005.20٪). لمهمة بسعر 0.01 دولار ، ستكون العمولة 50٪ ؛
  • ضريبة القيمة المضافة هي 20 ٪.

للتحقق من 10 صور للعدادات ، ندفع 0.01 دولار. في هذه الحالة ، يتم فحص صورة واحدة 5 مرات من قبل أشخاص مستقلين. في المجموع ، نعطي للتحقق من صورة واحدة: (0.01 × 5/10) × 1.2 × 1.5 = 0.009 دولار.


من بين 1000 إرسال تم إرسالها ، تم استلام 871 صورة ، ورُفض 129 صورة. للحصول على مجموعة من 871 صورة ، دفعنا:
0.018 دولار × 871 + 0.009 دولار × 1000 = 25 دولارًا ، وستحتاج إلى 92000 روبل للحصول على مجموعة من 50000 صورة. هذا بالتأكيد أرخص من طلب الإعلانات على القناة الفيدرالية!


ولكن في الواقع يمكن تخفيض هذا الرقم عدة مرات. يمكنك:


  • اقترح في المهمة الأولى عدم التقاط صورة واحدة ، بل عدة صور. في نفس الوقت رفع السعر ، فلن تكون عمولة ياندكس 50 ٪ ، ولكن 20 ٪.
  • استخدم التداخل الديناميكي في المهمة الثانية. إذا أعطى 4 من كل 5 أشخاص نفس الإجابة ، فليس من المنطقي إعطاء المهمة للشخص الخامس ؛
  • العمل مع Toloka ككيان قانوني أجنبي. في هذه الحالة ، لا تدفع ضريبة القيمة المضافة.

نظرًا لوجود الكثير من المواد ، قررت تقسيم المقالة إلى قسمين. في المرة القادمة سنتحدث معك حول كيفية تحديد كائنات على الصور باستخدام Toloka وإنشاء مجموعات بيانات للمهام في Computer Vision. وحتى لا تفوت ، اشترك وما شابه!


PS
بعد قراءة المقال ، قد يبدو لك أن هذا إعلان خفي عن Yandex.Tolki ، لكن لا ، إنه ليس كذلك. لم تدفع ياندكس لي أي شيء ، وعلى الأرجح لن تدفع. أردت فقط أن أعرض على سبيل المثال الخيالي ، ولكن ذو صلة ومثيرة للاهتمام ، كيفية استخدام هذه الخدمة يمكنك بسرعة وبتكلفة زهيدة تجميع مجموعة بيانات لأي مهمة ، سواء كانت مهمة التعرف على القطط أو تدريب المركبات غير المأهولة.

Source: https://habr.com/ru/post/ar469633/


All Articles