Kami membuat dataset untuk pengakuan penghitung di Yandex.Tolok



Dua tahun lalu, dengan menyalakan TV secara tidak sengaja, saya melihat cerita yang menarik dalam program Vesti. Diberitahu bahwa Departemen Teknologi Informasi Moskow sedang menciptakan jaringan saraf yang akan membaca pembacaan meter air dari foto. Dalam ceritanya, presenter TV meminta warga kota untuk membantu proyek dan mengirim gambar meter mereka ke portal mos.ru untuk melatih jaringan saraf pada mereka.


Jika Anda adalah departemen di Moskow, maka merilis video di saluran federal dan meminta orang untuk mengirim gambar meter bukanlah masalah yang sangat besar. Tetapi bagaimana jika Anda adalah startup kecil dan Anda tidak dapat membuat iklan di saluran TV? Bagaimana cara mendapatkan 50.000 gambar penghitung dalam kasus ini? Yandex.Toloka datang untuk menyelamatkan!


Yandex.Toloka adalah platform crowdsourcing tempat orang dari seluruh dunia melakukan tugas sederhana, menerima uang untuk ini. Misalnya, toloker dapat menemukan pejalan kaki dalam gambar, melatih asisten suara, dan banyak lagi . Pada saat yang sama, tidak hanya karyawan Yandex, tetapi siapa pun yang ingin dapat memposting tugas di Toloka.


Pernyataan masalah


Jadi, kami ingin membuat jaringan saraf, yang dari foto akan menentukan pembacaan penghitung. Di mana untuk memulai, data apa yang kita butuhkan?


Setelah berkonsultasi dengan kolega, kami menyimpulkan bahwa untuk membuat MVP kami membutuhkan 1000 gambar penghitung. Selain itu, untuk setiap penghitung kami ingin mengetahui bacaan saat ini, serta koordinat jendela dengan angka.


Jika Anda belum pernah bekerja dengan Toloka, saya sarankan Anda membaca artikel yang saya tulis setahun yang lalu. Karena artikel saat ini akan lebih rumit secara teknis, saya akan menghilangkan beberapa poin yang dijelaskan secara rinci dalam artikel sebelumnya.


Ucapan Terima Kasih

Artikel sebelumnya menjadi TOP-2 di peringkat artikel dari komunitas ODS . Terima kasih telah berkomentar dan mengajukan pro!)



Bagian 1. Akuisisi Gambar


Apa yang bisa lebih mudah? Hanya perlu meminta orang tersebut untuk membuka aplikasi Yandex.Tolok di ponsel mereka dan mengambil gambar penghitung mereka. Jika saya tidak bekerja dengan Toloka selama beberapa tahun, instruksi saya adalah: "Anda perlu memotret meteran air Anda (panas atau dingin) dan mengirimkan gambar kepada kami . "


Sayangnya, dengan pernyataan masalah seperti itu, dataset yang baik tidak dapat dikumpulkan. Masalahnya adalah orang dapat menafsirkan TK ini dengan cara yang berbeda, karena instruksi tidak memiliki kriteria yang jelas untuk tugas yang diselesaikan dengan benar. Tolockers dapat mengirim:


  • gambar buram;
  • Gambar yang tidak menunjukkan bukti
  • Gambar dengan banyak penghitung.

Blog Toloka memiliki tutorial yang bagus tentang cara menulis instruksi. Mengikutinya, saya mendapat instruksi ini:

Sebagai parameter input, kami melewatkan id tugas, dan pada output kami mendapatkan file img, yang akan berisi gambar penghitung.




Antarmuka pekerjaan ditulis hanya dalam 2 baris!




Saat membuat kumpulan, kami menunjukkan waktu untuk menyelesaikan tugas, penerimaan tertunda dan harga untuk tugas $ 0,01.




Dan agar orang tidak menyelesaikan tugas beberapa kali dan tidak mengirim foto yang sama, kami melarang eksekusi tugas yang berulang di blok kontrol kualitas.




Kami mengindikasikan bahwa kami membutuhkan pengguna berbahasa Rusia yang menyelesaikan tugas melalui aplikasi seluler Yandex.Tolok.




Mengunduh tugas ke kolam.




Kami memulai kumpulan, bersukacita dan menunggu tanggapan pengguna! Beginilah tugas kami terlihat dari sisi toloker:



Bagian 2. Penerimaan tugas


Setelah menunggu beberapa jam, kami melihat bahwa tolker menyelesaikan tugas. Karena dengan penerimaan yang tertunda, penghargaan tersebut tidak dibayarkan kepada kontraktor dengan segera, tetapi dibekukan di neraca pelanggan, sekarang kami harus memeriksa semua gambar yang dikirim. Untuk pemain yang bonafid untuk menerima tugas, dan untuk pemain yang mengirim gambar yang tidak sesuai untuk kriteria, menolak dan menulis alasan penolakan.


Jika tidak ada banyak gambar, maka kami dapat melihat dan memeriksa semua gambar yang dikirim sendiri. Tapi kami ingin mendapatkan ribuan dan puluhan ribu gambar! Memeriksa volume tugas ini akan membutuhkan banyak waktu. Plus, proses ini membutuhkan partisipasi kita secara langsung.


Toloka datang untuk menyelamatkan lagi! Kami dapat membuat tugas baru "Memeriksa gambar penghitung" dan meminta tolkers lain untuk menjawab apakah gambar tersebut sesuai dengan kriteria kami atau tidak. Dengan mengatur proses sekali, kami mendapatkan pengumpulan dan validasi data sepenuhnya otomatis! Pada saat yang sama, pengumpulan data mudah diukur, dan jika kita perlu menambah ukuran dataset beberapa kali, cukup klik beberapa tombol.


Kedengarannya luar biasa dan hebat, bukan?
Maka sudah saatnya mempraktikkan ide itu!


Pertama-tama, kita akan menentukan kriteria yang kita anggap foto itu baik.
Sebuah foto bagus jika:


  • Di foto itu ada persis satu counter air dingin atau panas;
  • Bacaan di konter terlihat jelas.

Dalam kasus lain, foto tersebut dianggap buruk.


Kami menyortir kriteria, sekarang kami sedang menulis instruksi!

Sebagai parameter input, kami meneruskan tautan ke gambar. Output akan menjadi dua flag:


  • check_count - menjawab pertanyaan pertama
  • check_quality - jawaban untuk pertanyaan kedua

Penghitung akan ditulis ke variabel nilai.




Antarmuka tugas ini sudah mengambil 14 baris.




Untuk meningkatkan akurasi, satu gambar akan diperiksa secara independen oleh 5 tokers, untuk ini kita akan tumpang tindih dengan 5. Setelah itu, kita akan melihat bagaimana 5 orang menjawab dan menganggap bahwa jawaban yang benar adalah yang dipilih oleh mayoritas. Tugas ini tidak lagi menunda penerimaan.




Mari kita akui 50% dari pemain terbaik untuk tugas itu.




Dalam tugas tanpa penerimaan tertunda, semua orang menerima pembayaran, terlepas dari apakah mereka melakukan tugas dengan benar atau tidak. Tapi kami ingin tolokers membaca instruksi dengan seksama, mencoba dan menyelesaikan tugas dengan benar. Bagaimana ini bisa dicapai?


Ada dua alat utama di Tolok yang memungkinkan Anda mempertahankan kualitas yang baik:


  1. Pelatihan Sebelum menyelesaikan tugas utama, kita bisa meminta pelatih untuk dilatih. Di kolam pelatihan, orang diberikan tugas yang sebelumnya kita tahu jawaban yang benar. Jika seseorang menjawab salah, kesalahan ditunjukkan kepadanya dan dijelaskan bagaimana menjawabnya. Setelah menyelesaikan pelatihan, kami melihat persentase tugas yang diselesaikan oleh pemain dan kami hanya dapat mengizinkan mereka yang melakukannya dengan baik ke kumpulan tugas utama.
  2. Blok kontrol kualitas. Mungkin ada situasi di mana kolam latihan pemain sangat bagus, kami diizinkan melakukannya, tetapi lima menit kemudian ia pergi bermain sepak bola, meninggalkan saudara lelakinya yang berusia tiga tahun di depan komputer. Untungnya, ada banyak metode di Tolok yang memungkinkan Anda melacak bagaimana orang menyelesaikan tugas.

Dengan kumpulan pelatihan, semuanya sederhana: cukup tambahkan tugas, tandai di antarmuka Yandex.Tolki dan tentukan ambang untuk lewat, mulai dari yang kami izinkan orang ke tugas utama.




Dengan unit kontrol kualitas, semuanya lebih menarik: ada cukup banyak, tetapi saya akan fokus pada dua yang paling penting.


Pendapat mayoritas
Kami memberikan tugas kepada 5 orang independen. Dan jika empat orang menjawab "Ya" untuk pertanyaan, dan yang kelima menjawab "Tidak," yang kelima mungkin membuat kesalahan. Dengan demikian, kita dapat menyaksikan bagaimana jawaban orang tersebut konsisten dengan jawaban orang lain, dan memblokir pengguna yang merespons berbeda dari yang lain.




Kontrol tugas
Kita dapat menggabungkan tugas ke dalam kumpulan, yang sebelumnya kita tahu jawaban yang benar. Pada saat yang sama, tugas kontrol kualitas terlihat sama dengan tugas biasa. Atas dasar apakah seseorang menjawab tugas kontrol dengan benar, kita dapat memperkirakan dan berasumsi, dengan benar atau tidak, bahwa dia menyelesaikan semua tugas lain yang kita tidak tahu jawabannya. Jika seseorang merespons dengan buruk untuk mengontrol tugas, kami dapat memblokirnya, dan jika itu baik, maka berikan bonus.




Hore, tugas dibuat! Seperti inilah tampilan antarmuka dari eksekutor:




Bagian 3. Bergabung dengan Pekerjaan


Hebat, tugas sudah siap! Tetapi muncul pertanyaan, bagaimana cara menghubungkan tugas satu sama lain? Bagaimana cara menjalankan kedua setelah tugas pertama?


Tentu saja, Anda dapat bermain dengan rebana dan melakukannya secara manual melalui antarmuka Toloka, tetapi ada cara yang lebih sederhana dan lebih cepat! Yandex.Tolok memiliki API , gunakan dan tulis skrip python!


Saya tahu banyak dari Anda tidak suka membaca kode, jadi saya menyembunyikannya di bawah spoiler
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") 

Kami menjalankan kode dan inilah hasil yang sudah lama ditunggu-tunggu: set data dari 871 gambar penghitung siap.




Harga


Mari kita evaluasi komponen ekonomi proyek.
Untuk gambar yang dikirim pada tugas pertama, kami menawarkan $ 0,01.
Sayangnya, jika kami membayar pemain $ 0,01, kami harus membayar $ 0,018.
Bagaimana ini dilakukan?


  • Komisi Yandex minimal (0,005.20%). Untuk tugas dengan harga $ 0,01, komisi akan menjadi 50%;
  • PPN adalah 20%.

Untuk memeriksa 10 gambar penghitung, kami membayar $ 0,01. Dalam hal ini, satu gambar diperiksa 5 kali oleh orang-orang independen. Secara total, kami berikan untuk memeriksa satu gambar: (0,01 x 5/10) x 1,2 x 1,5 = $ 0,009.


Dari 1000 pengiriman yang dikirim, 871 gambar diterima, dan 129 ditolak. Jadi, untuk mendapatkan dataset 871 gambar, kami membayar:
0,018 $ x 871 + 0,009 $ x 1000 = $ 25 dan Anda membutuhkan 92.000 rubel untuk mendapatkan dataset 50.000 gambar. Ini jelas lebih murah daripada memesan iklan di saluran federal!


Namun angka ini sebenarnya bisa dikurangi beberapa kali. Anda bisa:


  • Sarankan dalam tugas pertama untuk tidak mengambil satu foto, tetapi beberapa. Pada saat yang sama menaikkan harga, maka komisi Yandex tidak akan menjadi 50%, tetapi 20%;
  • Gunakan tumpang tindih dinamis dalam tugas kedua. Jika 4 dari 5 orang memberikan jawaban yang sama, maka tidak masuk akal untuk memberikan tugas kepada orang kelima;
  • Bekerja dengan Toloka sebagai badan hukum asing. Dalam hal ini, Anda tidak membayar PPN.

Karena ada begitu banyak materi, saya memutuskan untuk membagi artikel menjadi dua bagian. Lain kali kami akan berbicara dengan Anda tentang cara memilih objek dalam gambar menggunakan Toloka dan membuat kumpulan data untuk tugas di Computer Vision. Dan agar tidak ketinggalan, berlangganan dan sukai!


PS
Setelah membaca artikel itu, mungkin bagi Anda tampak bahwa ini adalah iklan tersembunyi Yandex.Tolki, tetapi tidak, tidak. Yandex tidak membayar saya apa pun, dan kemungkinan besar tidak akan membayar. Saya hanya ingin menunjukkan contoh fiksi, tetapi relevan dan menarik, bagaimana menggunakan layanan ini Anda dapat dengan cepat dan murah merakit dataset untuk tugas apa pun, baik itu tugas mengenali kucing atau melatih kendaraan tanpa awak.

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


All Articles