Cognitive Services Custom Vision を REST API のみで使いこなす (2)既存プロジェクトの作成済みモデルに追加学習

Custom Vision を利用すると、最小で画像5枚から画像解析モデルを作成し、Web API や CoreML、TensorFlow、ONNX のフォーマットで Export して利用できるほか、そのままお手持ちの Docker 環境で Image Build して Web API サービスとして利用できる Dockerfile としても Export 可能です。

[前回](https://qiita.com/annie/items/1abf23017831442ab1ad)は Custom Vision Portal を使わず、REST API (Training API) を用いて、の新規プロジェクトの作成、学習データのアップロード、学習、モデル公開まで行う手順を紹介しました。
今回は同じくこの Training API を用いて、既存プロジェクトに、画像を追加アップロードしてタグ付け、モデルを再学習させて公開するまでのプロセスを行う手順を紹介します。

- **Cognitive Services Custom Vision を REST API のみで使いこなす** シリーズ
    - (1) [新規プロジェクトを作成してモデルを学習、公開](https://qiita.com/annie/items/1abf23017831442ab1ad)
    - (2) 既存プロジェクトの作成済みモデルに追加学習 (←この記事)

# 準備

## Custom Vision の作成済みプロジェクト

Custom Vision の 作成済みプロジェクトを使います。
[Custom Vision Portal](https://www.customvision.ai/) から GUI で作成、または、Training API で作成 (手順は[前回](https://qiita.com/annie/items/1abf23017831442ab1ad)をご覧ください)、どちらで作成したプロジェクトでも構いません。

## Training Key、Resource Id、Location の取得

[前回の手順](https://qiita.com/annie/items/1abf23017831442ab1ad#training-keyresource-id-%E3%81%AE%E5%8F%96%E5%BE%97)と同様に取得しておきます。

## Project Id の取得

[前回、Training API を用いてプロジェクトを作成した手順](https://qiita.com/annie/items/1abf23017831442ab1ad#1-%E6%96%B0%E8%A6%8F%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90) で取得できた Project Id をこちらでも使用します。または下記の手順でも取得できます。

### Custom Vision Portal から取得する場合

[Custom Vision Portal](https://customvision.ai) にサインインして、追加学習を行うプロジェクトを選択して開きます。その後、プロジェクトの画面右上の ⚙ (設定アイコン)をクリックします。

**Project Id** に表示されている値を **projectId** としてローカルに保存しておきます。

> Training Key, Location, Resource Id もこのページから値を確認、取得することができます。

![20200720_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117583/2cfc2cb1-96be-1aa3-bb5c-f1455ece2504.png)


### Training API から取得する場合

Training API の [GetProjects](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc6548b571998fddead) で Training Key に紐づいたプロジェクト一覧が取得できます。

- Url
    - https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects
        - *YOUR_LOCATION* → ローカルに保存しておいた **Location**
- ヘッダー
    - **Training-key**: Training Key

```
GET https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects HTTP/1.1
Training-key: ••••••••••••••••••••••••••••••••
```

Result で以下のようにプロジェクト一覧が取得できます。ここから該当するプロジェクトを確認し、表示される *id* の値を **projectId** としてローカルに保存しておきます。

```
[{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx",
  "name": "CLASSIFICATION_PJ",
  "description": "",
  "settings": {
    "domainId": "0732100f-1a38-4e49-a514-c9b44c697ab5",
    "classificationType": "Multiclass",
     :
  },
  "created": "2020-07-10T01:19:18.073Z",
  "lastModified": "2020-07-16T03:11:35.141Z",
   :
  "status": "Succeeded"
}, 
:
```

# 手順

## 1. 最新 Iteration の取得

まずは再学習をさせるモデルの最新バージョン(Iteration)を取得します。[GetIterations](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc6548b571998fddec9/) を利用します。

- URL
    - https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects/YOUR_PROJECT_ID/iterations
        - *YOUR_LOCATION* → ローカルに保存しておいた **Location**
        - *YOUR_PROJECT_ID* → ローカルに保存しておいた **projectId**
- ヘッダー
    - **Training-key**: ローカルに保存しておいた **Training Key**

```
GET https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects/YOUR_PROJECT_ID/iterations
Training-key: ••••••••••••••••••••••••••••••••
```

Response 200 が戻り、保持している Iteration の情報が表示されます。一番上(＝最新) の Iteration 情報に表示されている *id* の値を **iterationId** としてローカルに保存しておきます。 

```
[{
    "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx",
    "name": "Iteration 3",
    "status": "Completed",
    "created": "2020-07-10T02:58:20.966Z",
    "lastModified": "2020-07-16T03:12:00.621Z",
    "trainedAt": "2020-07-16T03:12:00.621Z",
    "projectId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx",
    "exportable": true,
    "exportableTo": ["CoreML", "DockerFile", "ONNX", "OpenVino", "TensorFlow"],
     :
```

## 2. プロジェクトに設定されている Tag 情報を取得する

プロジェクトで作成されている Tag (分類)を取得します。[GetTags](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc7548b571998fddedb) を利用します。

- URL
    - https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects/YOUR_PROJECT_ID/tags
        - *YOUR_LOCATION* → ローカルに保存しておいた **Location**
        - *YOUR_PROJECT_ID* → ローカルに保存しておいた **projectId**
- パラメーター
    - **iterationId**: ローカルに保存しておいた **iterationId**
- ヘッダー
    - **Training-key**: ローカルに保存しておいた **Training Key**


```
GET https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects/YOUR_PROJECT_ID/tags?iterationId=YOUR_ITERATION_ID
Training-key: ••••••••••••••••••••••••••••••••
```

Response 200 が返り、設定されている Tag の一覧が取得できます。*id* に表示される値、および *name* を **tagId**[n]、**tagName**[n] のようにセットにしてローカルに保存しておきます。

```
[
  {
    "id": "YOUR_TAG_ID_1",
    "name": "Eagle",
    "description": null,
    "type": "Regular",
    "imageCount": 5
  }, 
  {
    "id": "YOUR_TAG_ID_2",
    "name": "Swan",
    "description": null,
    "type": "Regular",
    "imageCount": 5
  }, 
   :
```

## 3. 画像データをアップロードする

前回の [画像アップロード＆タグ付け](https://qiita.com/annie/items/1abf23017831442ab1ad#3-%E7%94%BB%E5%83%8F%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%82%BF%E3%82%B0%E4%BB%98%E3%81%91) の手順で画像をアップロードすることができます。

が、今回は一旦画像を現在のモデルで分析し、その結果を確認して学習データとして登録する方法をやってみます。

### 3.1 画像データを現在のモデルで分析する

前回の [モデルのテスト](https://qiita.com/annie/items/1abf23017831442ab1ad#5-%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88) の手順で、[QucikTestImage](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc7548b571998fdded9) または [QuickTestImageUrl](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc7548b571998fdded9) を使って、追加の学習データとなる画像をテスト分析します。
以下のように分析の結果が表示されます。

```
{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx",
  "project": "YOUR_PROJECT_ID",
  "iteration": "YOUR_ITERATION_ID",
  "created": "2020-07-20T07:40:18.830Z",
  "predictions": [
    {
      "probability": 0.999974132,
      "tagId": "YOUR_TAG_ID_2",
      "tagName": "Swan",
      "tagType": "Regular"
    }, 
    {
      "probability": 2.555639E-05,
      "tagId": "YOUR_TAG_ID_3",
      "tagName": "Penguin",
      "tagType": "Regular"
    },
     :
```

正しくタグ付けされているかを確認し、*id* に表示される値を **imageId** としてローカルに保存しておきます。(追加投入したい画像の数だけ繰り返し、**imageId**[n]、正しい TagId を **tagId**[n] としてセットで 保存しておくと効率的です。) 

> テストとして投入した画像がプロジェクトで保持されて imageId が発行されるため、この imageId を使って学習データとして投入できるようになります。
Object Detection モデルの場合は、画像におけるオブジェクトの位置も推測できるため、その値を利用することで学習データとしてのマークアップの手間が省けます。


### 3.2 分析済み画像を学習データとして投入する

[CreateImagesFromPredictions](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc6548b571998fddebc) を利用します。

- URL
    - https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects/YOUR_PROJECT_ID/images/predictions
        - *YOUR_LOCATION* → ローカルに保存しておいた **Location**
        - *YOUR_PROJECT_ID* → ローカルに保存しておいた **projectId**
- ヘッダー
    - **Content-type**: application/json
    - **Training-key**: ローカルに保存しておいた **Training Key**


```
POST https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects/YOUR_PROJECT_ID/images/predictions
Content-Type: application/json
Training-key: ••••••••••••••••••••••••••••••••
```

Request Body は、imageId とタグ付けしたい tagId を以下のように設定します。(YOUR＿IMAGE_ID_x、YOUR_TAG_ID_x をローカルに保存しておいた適切な **imageId**[n]、**tagId**[n] と差し替えます。)

```
{
  "images": [
    {
      "id": "YOUR_IMAGE_ID_1",
      "tagIds": [
        "YOUR_TAG_ID_2"
      ],
    },
    {
      "id": "YOUR_IMAGE_ID_2",
      "tagIds": [
        "YOUR_TAG_ID_3"
      ],
    }
  ],
  "tagIds": [
    "YOUR_TAG_ID_2","YOUR_TAG_ID_3"
  ]
}
```

## 4. モデルの再学習

前回の [モデルの学習](https://qiita.com/annie/items/1abf23017831442ab1ad#4-%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E5%AD%A6%E7%BF%92) と同じ手順で [TrainProject](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc7548b571998fddee1) と [GetIteration](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc6548b571998fddeca) を使って、モデルを再学習させ、学習の終了を確認します。


## 5. モデルの再テスト、公開

前回の [モデルのテスト](https://qiita.com/annie/items/1abf23017831442ab1ad#5-%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88) と同じ手順で [QuickTestImage](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc7548b571998fdded9) | [QuickTestImageUrl](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc7548b571998fdded9) を使って、モデルの再テストを行います。

その後、前回の [モデルの公開](https://qiita.com/annie/items/1abf23017831442ab1ad#6-%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E5%85%AC%E9%96%8B) と同じ手順で、[PublishIteration](https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Training_3.3/operations/5eb0bcc7548b571998fdded5) を使って、画像分析モデルを利用できるように公開します。

この時、**publishName** のパラメーターで **旧モデルと同じ名前** または **異なる名前** のどちらでも設定できます。同じ名前を設定すると Prediction URL を変更することなく利用することができます。その時は **overwrite** パラメーターを **True** として忘れずに追加します。

```
POST https://YOUR_LOCATION.api.cognitive.microsoft.com/customvision/v3.3/Training/projects/YOUR_PROJECT_ID/iterations/YOUR_ITERAION_ID/publish?publishName=YOUR_PUBLISH_NAME&predictionId=YOUR_RESOURCE_ID&overwrite=True
Training-key: ••••••••••••••••••••••••••••••••
```

Response 200 が戻れば公開完了です。