Amazon Mechanical Turk で課題を作成・発行する方法（画像分類課題）

# はじめに
先日、研究で画像分類タスクの人間データを集める際に、Amazon Mechanical Turk （以下AMT）を使用したのですが、一つにまとまった情報がなかったので、この記事でまとめて共有します。（AMT自体の説明や詳細については、少し古いですが[こちらのスライド](https://www.slideshare.net/Ayako_Hasegawa/amazon-mechanical-turk-92372451)が参考になるかと思います。）<br>
今回は、AMT側で用意されているテンプレートとCrowdHTMLというAMT用のタグを使用してシンプルな画像分類課題を作成しました。他の課題もテンプレが用意されているので、適宜自分の目的に合わせて作成してください。 <br>
また、より複雑な課題をオンラインで実施したい場合は、他のサービスなどを組み合わせる必要があると思います。詳しくは [#より複雑な課題を提出したい場合は？](#より複雑な課題を提出したい場合は)で考察しています。

<!-- いずれにせよ、AMTは被験者を大量に素早く集めるには良いサービスだと思います。（報酬額の妥当性や被験者の偏り、精度などについて議論はあると思いますが。）
-->

# 目次
1. [事前準備](#事前準備)
1. [AWSのS3に課題用の画像をアップする](#awsのs3に課題用の画像をアップする)
1. [AMTで課題を作成](#amtで課題を作成)
1. [課題をバッチごとに提出](#課題をバッチごとに提出)
1. [結果の確認](#結果の確認)
1. [より複雑な課題を提出したい場合は？](#より複雑な課題を提出したい場合は)

# 事前準備
- AMTのRequesterアカウントを作成 <br>
AMTでは課題に取り組むWorkerと、課題を出すRequesterが存在します。今回は課題を提出することが目的なので[ここ](https://www.mturk.com/get-started)からRequesterアカウントを作成してください。<br> 
また、Workerへの報酬を払うために、プリペイドへの入金、もしくはクレジットカードの登録が必要になります。この辺の設定は課題の提出前でも大丈夫です。
- AWSのアカウントを作成 <br>
S3の利用のために必要になります。ここでもクレジットカード等の料金支払い登録が必要です。

# AWSのS3に課題用の画像をアップする
AWSのファイルストレージシステムであるS3に、課題に必要な画像をアップロードします。 <br>
まず、AMT用のバケットを作成します。
![s3_console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/e2856873-f064-8a0b-5360-ffa3a5eba546.png)

その際、Workerが画像にアクセスできるように、"**Block _all_ public access**"をオフにします。
![s3_public_access.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/300e6533-d5af-f27b-84fb-6967496e3907.png)

また、"Amazon S3" → "[作成したバケット]" → "Permissions"のCORS設定を以下のように編集します。[（参照: CORS configuration requirement）](https://docs.aws.amazon.com/AWSMechTurk/latest/AWSMechanicalTurkRequester/MturkCorsConfig.html)
![s3_permissions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/5dbdf620-fc73-bd2e-8af5-1d6e0410fedf.png)

```text:CORS
[
    {
        "AllowedHeaders": [],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
```
以上でバケットの設定は完了です。

次に、S3に画像をアップロードしていきます。まず、本課題用のフォルダを作成します。
![s3_create_folder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/642fc260-f3b4-be91-bc13-c10469a99bfb.png)

作成したフォルダに画像をアップロードします。画像のフォルダを一括でアップロードすることもできます。
![s3_upload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/17c19e77-3670-0320-8a03-dad8ff135999.png)

この際、public-readアクセスの設定を忘れないようにしましょう。
![s3_upload_public_access.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/e44d6f7a-f132-0435-45a1-935e7ab1e553.png)

これで画像をアップロードできました。画像のページにいくと、URLが確認できます。別アカウントか、ログインしていない状態でもそのURLにアクセスできるか確認しておきましょう。
![s3_object_url.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/093ae53c-6d7b-537e-9ba9-7fa16a4a28af.png)

課題を提出する際には、画像のURLのリストを作成する必要があります。その手順は [#課題をバッチごとに提出](#課題をバッチごとに提出) で説明しています。

# AMTで課題を作成
AMTで"New Project"を作成します。今回は"Image Classification"のテンプレートを選択しました。
![amt_new_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/881cad39-37b8-0509-a3cb-e4d92ed7d436.png)

課題の設定を行います。特に重要なのは報酬などについての設定だと思います。以下でいくつかの項目についてまとめています。
![amt_project_settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/975231a4-30ce-7014-85f7-8a7284bf641f.png)


- **Reward per assignment** <br>
assignment毎の報酬額。"assignment"とは、提出されたタスク１つのことを指し、ここでは「1つの画像を分類する作業」を意味します。
- **Number of assignments per task** <br>
あるタスクを何人のワーカーに行ってもらうか。今回の例では、「１画像あたり何人のワーカーに分類してもらうか」という意味です。
- **Time allotted per assignment** <br>
１タスクにかかる最大時間。
- **Task expires in** <br>
タスクの有効期限。  
- **Auto-approve and pay Workers in** <br>
RequesterはWorkerが提出したタスクを承認（または拒否）することで報酬が発生（または拒否）するのですが、ここで指定した時間を経過すると自動で承認されます。

HTML/CSSを使ってタスクをデザインしていきます。テンプレの場合は、Crowd HTMLという要素を使ってタスクをデザインすることができます。詳しくは[ドキュメント](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-ui-template-reference.html)を参照してください。
ここで大事なのは画像の指定方法です。`<crowd-image-classifier>`タグの要素`src`にURLを指定することで画像を表示します。ここでは`src="${image_url}"`と変数を置いています。これは、課題を提出する際に、URLをCSVファイルでまとめて提出するのですが、そのときにURLが格納される変数です。
![amt_task_design.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/2155da4b-2422-4c61-2695-05ee56d70673.png)
タスクのデザインをして、プレビューを見て問題なさそうであれば"Finish"を押して完成です。画像は課題の提出の際に確認できます。また、タスクの設定やデザイン等は後で編集できます。
![amt_task_design_preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/b952da95-724e-2cca-fad4-a7812c946014.png)


# 課題をバッチごとに提出
課題を提出する際は、対象となる画像のURLをCSVファイルにまとめて提出します。このURLをいくつかに分割して提出することも可能です。
CSVファイルの中身について説明します。タスクをデザインした時、`src="${image_url}"`というように変数を置きました。この変数名をCSVファイルの先頭に置き、その後urlの一覧を１列に並べます。

```csv:file_list.csv
image_url
https://amt-backet.s3.ap-northeast-1.amazonaws.com/mturk-images/airplane_test_000.jpg
https://amt-backet.s3.ap-northeast-1.amazonaws.com/mturk-images/airplane_test_001.jpg
https://amt-backet.s3.ap-northeast-1.amazonaws.com/mturk-images/airplane_test_002.jpg
```
<details><summary>**URL変数とCSVファイルについてのtips**</summary><div>
CSVファイルにURLを並べるのは煩雑なので、URLの共通部分がある場合は、HTMLの要素に先に記述しておけば、CSVファイルの中身が綺麗になります。

== 記述例 ==

```HTML:task-design.html
<crowd-image-classifier 
    src="https://amt-backet.s3-ap-northeast-1.amazonaws.com/mturk-images/${image_url}"
    ...
>
```
```csv:file_list.csv
image_url
airplane_test_000.jpg
airplane_test_001.jpg
airplane_test_002.jpg
```
</div></details>

<details><summary>**CSVファイル作成コマンド例**</summary>
<div>

```shell:例１　URL一覧をCSVファイルに書き出す
images$ ls -1 > file_list.csv
```

```shell:例２　ソートして書き出す
images$ find . -name "*.jpg" | sort > file_list.csv
```
</div>
</details>

課題を提出します。AMTのRequesterページから"New Batch with an Existing Project"を選択すると、作成したタスク一覧が表示されるので、該当タスクの"Publish Batch"をクリックします。
![amt_projects.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/ecf83970-4a18-a5ae-156a-408c8bd78f28.png)

そして、先ほど作成した画像URL一覧のCSVファイルをアップロードします。
![amt_publich_batch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/40bfd41c-2727-dd92-b886-c64f88c8a9e4.png)

プレビューで画像が表示されるかなどを確認し、報酬額等の設定を再度確認した後、"Publish"を押せば課題が提出されます。
![amt_publish_batch_preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/29d7d16e-ed37-efe6-e113-c7df0cf1b512.png)
![amt_publish_batch_confirm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/96294afa-8ce1-e6b4-119d-c5d017eeb856.png)

# 結果の確認
AMTのRequesterページから"Manage"を選択すると提出したバッチの一覧を確認できます。タスクがどのくらい進んでいるかも確認できますね。タスクにもよりますが、かなり素早くデータを集めることができると思います。（筆者は数時間程度で4800枚もの画像分類データを集めることができました！）
![amt_batch_list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/0dd3f76e-d7cf-57f3-a350-bfde4e84450f.png)

バッチをクリックするとそのバッチに関する情報が表示され、"Results"を押すと結果が確認できます。
![amt_batch_details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/1f1acb20-8d75-d49d-8a23-9737789718c8.png)

結果のページでは、提出されたタスク(assignment)の承認や結果のフィルターを行うことができます。CSVファイルとして結果をダウンロードすることも可能です。
![amt_batch_results.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744885/55844bdc-70d6-2b68-690e-79733f154156.png)


# より複雑な課題を提出したい場合は？
今回は、AMT側で用意されているテンプレートを使用してシンプルな画像分類課題を作成しました。 
ただ、このテンプレートやCrowdHTMLは制約も多く、単純な課題しか作成できません。より複雑な課題の人間データを集めたい場合は、サーバーをホストして自分で課題を作るか、他のサービスを使って課題を作成する必要があります。
例えば、PsycoPyで作った課題をオンライン実験用に変換するとか。この手順はラボの後輩@Tiger-0512が記事にしてくれています。[（PsycoPyを使用してオンライン実験を始めるまで）](https://qiita.com/Tiger-0512/items/32459e4450da3db49217)

別のサイト等で課題を作成した場合は、その課題のURLをAMTの画面に貼り、Workerに課題のリンクに飛んでもらい、リンク先で課題を解いてもらった後、AMTのページに戻ってsubmitを押してもらうという流れが考えられます。
つまり、**AMTで被験者の募集と報酬の支払いを行い、別のページで課題を解いてもらうという方法**です。その際、課題のページでWorkerIDを入力してもらえば、AMT側での報酬等のやり取りもスムーズになるかと思います。 <br>
尚、筆者はここまでは実践していないので、もしこのような方法を試した方がいれば、共有していただけると幸いです！

# 参考文献
- [Tutorial: How to label thousands of images using the crowd](https://blog.mturk.com/tutorial-how-to-label-thousands-of-images-using-the-crowd-bea164ccbefc)
- [Tutorial: Using Crowd HTML Elements](https://blog.mturk.com/tutorial-using-crowd-html-elements-b8990ec71057)
- [Using CSV Files to Create Multiple HITs in the Requester UI](https://blog.mturk.com/using-csv-files-to-create-multiple-hits-in-the-requester-ui-22a25ec563dc)