BluemixでWatson API のVisual Recognition を使う by curl

# はじめに
タイトルの通りです．
※python版は[BluemixでWatson API のVisual Recognition を使う by python
](http://qiita.com/MoriKen/items/112c652e4001fa54ab5e)を参照．

構成は下記の通りです．

- サーバ：Bluemix上でVisual Recognitionのサービスをインスタンス化する
- クライアント：コマンドラインから`curl`コマンドで学習と判別を行う

基本的には下記チュートリアルを参照しました．

- [Visual Recognition Tutorials](https://www.ibm.com/watson/developercloud/doc/visual-recognition/tutorials.shtml)

Bluemix アカウントはトライアル版です．Bluemixにログインをした状態からスタートします．

# 手順
## Visual Recognition のサービスを準備する
1. HOME画面からダッシュボードを選択する．
![01_ダッシュボード.png](https://qiita-image-store.s3.amazonaws.com/0/110138/f41b3e4e-7d1e-f48c-4da9-e7aa49ac12b1.png)

2. サービスまたはAPIの使用を選択する．
![02_サービス＆API.png](https://qiita-image-store.s3.amazonaws.com/0/110138/b2ba1c3e-67fb-359b-83b1-ac09d3e869ed.png)

3. サービスの一覧から「Watson」→「Visual Recognition」を選択する．
![03_Visual Recognition.png](https://qiita-image-store.s3.amazonaws.com/0/110138/0a4a22eb-2787-da9a-e102-5bc9c753d1e8.png)

4. Visual Recognitionサービスをインスタンス化する．アプリとのバインドをしないこと．ここでバインドすると資格情報をここで取得できない．
![04_Visual Recognition_インスタンス化.png](https://qiita-image-store.s3.amazonaws.com/0/110138/8ace57de-97e7-54f1-8e08-314cc6f55f21.png)

5. 資格情報を確認するために，サービスの画面に遷移する．迷子になっても必ずアクセスできるように，ダッシュボードからインスタンス化したVisual Recognitionサービスを選択するフローを示しておく．
![05_Visual Recognition_サービス選択.png](https://qiita-image-store.s3.amazonaws.com/0/110138/6f41741b-98d3-7e46-cbc1-ae4f6a6bed01.png)

6. 資格情報を確認する．***api_key***はこの後何度も使うので，控えること．
![06_資格情報取得.png](https://qiita-image-store.s3.amazonaws.com/0/110138/0770ce1a-4143-7754-681f-beeb579093dc.png)

## ユーザが用意した画像で学習させる
1. ポジティブ画像群を***{positive_images}.zip***で保存する．
 - 名称は任意でよい．
 - 保存場所はローカルで良い．
 - 今回はチュートリアル参考に[beagle.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/beagle.zip)，[husky.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/blob/master/visual-recognition/husky.zip)，[golden-retriever.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/golden-retriever.zip) を保存した．
2. ネガティブ画像群を***{negative_images}.zip***で保存する．
 - 名称は任意でよい．
 - 保存場所はローカルで良い．
 - 今回はチュートリアル参考に[cats.zip](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/cats.zip) を保存した．
2. 下記書式に従って学習コマンドを実行する
 - 書式
     - `curl -X POST -F "classname_positive_examples=@{positive_images}.zip" -F "negative_examples=@{negative_images}.zip" -F "name={classifier_name}" "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classifiers?api_key={api-key}&version=2016-05-20"`
         - ***{positive_images}.zip***: ポジティブクラスの画像群を格納したzipファイル．ローカルであれば相対パスでも絶対パスでも良い．クラウド上に保存されたファイルならURLを指定する．クラスは複数指定できる．
         - ***classname*** にクラス名が入る．
            - 各クラスの接尾詞である"_positive_examples"と"_negative_examples"は固定．
         - ***{negative_images}.zip***：ネガティブクラスの画像群を格納したzipファイル．
         - ***{classifier_id}***：分類器id
         - ***{api-key}***：先に取得したapi-key名
         - versionを入れないと動かない．
 - 例（チュートリアルを参考）
      - `curl -X POST -F "beagle_positive_examples=@beagle.zip" -F "husky_positive_examples=@husky.zip" -F "goldenretriever_positive_examples=@golden-retriever.zip" -F "negative_examples=@cats.zip" -F "name=dogs" "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classifiers?api_key={api-key}&version=2016-05-20"`
      - 画像ファイル群はカレントディレクトリに保存されているものとする．
4. 結果を確認する．
 - 分類器のidや，クラスの種類等学習機に関わるパラメータが出力されたら，学習完了．

```js
{
    "classifier_id": "dogs_xxxxxxxxxx",
    "name": "dogs",
    "owner": "xxxx-xxxxx-xxx-xxxx",
    "status": "training",
    "created": "2016-xx-xxTxx:xx:xx.xxxZ",
    "classes": [
        {"class": "husky"},
        {"class": "goldenretriever"},
        {"class": "beagle"}
    ]
}
```
 
## ユーザ学習によるカスタム分類器を利用する
1. 下記内容を`myparams.json`として保存する．
- `{
    "classifier_ids": ["dogs_xxxxxxxxxx", "default"] 
}`
     - `"dogs_xxxxxxxxxx"`は，先の処理で取得した`"classifier_id"`と対応させる．
     - `"default"`は元々Visual Recognitionが持っている分類器のid．
     - こうして指定することで，複数の分類器の結果を得られる．
2. 認識させたい画像を用意する．
 - 名称は任意でよい．
 - 保存場所はローカルで良い．Web上の画像でも良い．
 - 今回はチュートリアル参考に[bdogs.jpg](https://github.com/watson-developer-cloud/doc-tutorial-downloads/raw/master/visual-recognition/dogs.jpg)を保存した．
2. 認識させたい画像をカスタム分類器に送信し，学習結果と照合させる．
  - 書式
      - `curl -X POST -F "images_file=@{image}.jpg" -F "parameters=@myparams.json" "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classify?api_key={api-key}&version=2016-05-20"`
      - `myparams.json`はカレントディレクトリに保存されているものとする．
  - 例（チュートリアルを参考）
      - `curl -X POST -F "images_file=@dogs.jpg" -F "parameters=@myparams.json" "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classify?api_key={api-key}&version=2016-05-20"`
4. 結果を確認する．
 -  前半は元々Visual Recognitionが持っている分類器("classifier_id": "default")による結果．
     -  "animal", "mammal", "dog"
 -  後半はカスタム分類器("classifier_id": "dogs_xxxxxxxxxx")による結果．
     - "goldenretriever"  

```js
{
    "images": [
        {
            "classifiers": [
                {
                    "classes": [
                        {
                            "class": "animal",
                            "score": 1.0,
                            "type_hierarchy": "/animals"
                        },
                        {
                            "class": "mammal",
                            "score": 1.0,
                            "type_hierarchy": "/animals/mammal"
                        },
                        {
                            "class": "dog",
                            "score": 0.880797,
                            "type_hierarchy": "/animals/pets/dog"
                        }
                    ],
                    "classifier_id": "default",
                    "name": "default"
                },
                {
                    "classes": [
                        {
                            "class": "goldenretriever",
                            "score": 0.610501
                        }
                    ],
                    "classifier_id": "dogs_xxxxxxxxxx",
                    "name": "dogs"
                }
            ],
            "image": "dogs.jpg"
        }
    ],
    "images_processed": 1
}
```

# おわりに，その他
- Bluemix上でVisual Recognitionサービス単体を使うだけなら，`curl` コマンド経由でサクッと学習できることが分かりました．
- curl以外のAPI経由で学習もしてみたい．
  - [Visual Recognition API Reference](http://www.ibm.com/watson/developercloud/visual-recognition/api/v3/?curl#introduction)
  - クライアントは，Curl, Node.js, Java, Python が対応しているらしい．
- 既存のランタイムと連携できていない．
   - [visual-recognition-nodej](https://github.com/watson-developer-cloud/visual-recognition-nodejs) をバインドさせて実行させようとしても，実行できない．状態は不明となる．良く分からない．
   - Eclipseとの連携もうまくいかない．チュートリアルを読んでやっているが，書かれた通りの挙動にならない．Bluemix DevOpsでしかうまく行っていない．
- Bluemixのチュートリアルや勉強会資料が沢山あるのはありがたいです．ただ，情報が発散して何をどの順番に読めばよいのか分からなかったり，資料の途中で分からない概念の言葉が出てきてそれを調べるのにまた時間がかかったり，チュートリアルの通りにやってもその通りの挙動にならなかったり，結構躓いています…．
- 私がWebプログラミング初心者で力不足だからなのは100で認めるのですが，ラピッドコーディングができることがメリットではあるはずのBluemixのチュートリアルを完了させるまでの環境整備にかなり時間を費やしていて悲しくなるときもありました…．