face.py より

 

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
“””
File: face.py
Description: Face section of the Cognitive Face API.
“””
from . import util

def detect(image, face_id=True, landmarks=False, attributes=”):
“””Detect human faces in an image and returns face locations, and
optionally with `face_id`s, landmarks, and attributes.

Args:
image: A URL or a file path or a file-like object represents an image.
face_id: [Optional] Return faceIds of the detected faces or not. The
default value is true.
landmarks: [Optional] Return face landmarks of the detected faces or
not. The default value is false.
attributes: [Optional] Analyze and return the one or more specified
face attributes in the comma-separated string like
“age,gender”. Supported face attributes include age, gender,
headPose, smile, facialHair, glasses, emotion, makeup, accessories,
occlusion, blur, exposure, noise. Note that each face attribute
analysis has additional computational and time cost.

Returns:
An array of face entries ranked by face rectangle size in descending
order. An empty response indicates no faces detected. A face entry may
contain the corresponding values depending on input parameters.
“””
url = ‘detect’
headers, data, json = util.parse_image(image)
params = {
‘returnFaceId’: face_id and ‘true’ or ‘false’,
‘returnFaceLandmarks’: landmarks and ‘true’ or ‘false’,
‘returnFaceAttributes’: attributes,
}

return util.request(
‘POST’, url, headers=headers, params=params, json=json, data=data)

def find_similars(face_id,
face_list_id=None,
large_face_list_id=None,
face_ids=None,
max_candidates_return=20,
mode=’matchPerson’):
“””Given query face’s `face_id`, to search the similar-looking faces from a
`face_id` array, a `face_list_id` or a `large_face_list_id`.

Parameter `large_face_list_id`, `face_list_id` and `face_ids` should not be
provided at the same time.

Args:
face_id: `face_id` of the query face. User needs to call `face.detect`
first to get a valid `face_id`. Note that this `face_id` is not
persisted and will expire in 24 hours after the detection call.
face_list_id: An existing user-specified unique candidate face list,
created in `face_list.create`. Face list contains a set of
`persisted_face_ids` which are persisted and will never expire.
large_face_list_id: An existing user-specified unique candidate face
list, created in `large_face_list.create`. Large Face list contains
a set of `persisted_face_ids` which are persisted and will never
expire.
face_ids: An array of candidate `face_id`s. All of them are created by
`face.detect` and the `face_id`s will expire in 24 hours after the
detection call. The number of `face_id`s is limited to 1000.
max_candidates_return: Optional parameter. The number of top similar
faces returned. The valid range is [1, 1000]. It defaults to 20.
mode: Optional parameter. Similar face searching mode. It can be
“matchPerson” or “matchFace”. It defaults to “matchPerson”.

Returns:
An array of the most similar faces represented in `face_id` if the
input parameter is `face_ids` or `persisted_face_id` if the input
parameter is `face_list_id` or `large_face_list_id`.
“””
url = ‘findsimilars’
json = {
‘faceId’: face_id,
‘faceListId’: face_list_id,
‘largeFaceListId’: large_face_list_id,
‘faceIds’: face_ids,
‘maxNumOfCandidatesReturned’: max_candidates_return,
‘mode’: mode,
}

return util.request(‘POST’, url, json=json)

def group(face_ids):
“””Divide candidate faces into groups based on face similarity.

Args:
face_ids: An array of candidate `face_id`s created by `face.detect`.
The maximum is 1000 faces.

Returns:
one or more groups of similar faces (ranked by group size) and a
messyGroup.
“””
url = ‘group’
json = {
‘faceIds’: face_ids,
}

return util.request(‘POST’, url, json=json)

def identify(face_ids,
person_group_id=None,
large_person_group_id=None,
max_candidates_return=1,
threshold=None):
“””Identify unknown faces from a person group or a large person group.

Args:
face_ids: An array of query `face_id`s, created by the `face.detect`.
Each of the faces are identified independently. The valid number of
`face_ids` is between [1, 10].
person_group_id: `person_group_id` of the target person group, created
by `person_group.create`.
large_person_group_id: `large_person_group_id` of the target large
person group, createdJ by `large_person_group.create`.
max_candidates_return: Optional parameter. The range of
`max_candidates_return` is between 1 and 5 (default is 1).
threshold: Optional parameter. Confidence threshold of identification,
used to judge whether one face belongs to one person. The range of
confidence threshold is [0, 1] (default specified by algorithm).

Returns:
The identified candidate person(s) for each query face(s).
“””
url = ‘identify’
json = {
‘personGroupId’: person_group_id,
‘largePersonGroupId’: large_person_group_id,
‘faceIds’: face_ids,
‘maxNumOfCandidatesReturned’: max_candidates_return,
‘confidenceThreshold’: threshold,
}

return util.request(‘POST’, url, json=json)

def verify(face_id,
another_face_id=None,
person_group_id=None,
large_person_group_id=None,
person_id=None):
“””Verify whether two faces belong to a same person or whether one face
belongs to a person.

For face to face verification, only `face_id` and `another_face_id` is
necessary. For face to person verification, only `face_id`,
`person_group_id` (or `large_person_group_id`) and `person_id` is needed.

Args:
face_id: `face_id` of one face, comes from `face.detect`.
another_face_id: `face_id` of another face, comes from `face.detect`.
person_group_id: Using existing `person_group_id` and `person_id` for
fast loading a specified person. `person_group_id` is created in
`person_group.create`.
large_person_group_id: Using existing `large_person_group_id` and
`person_id` for fast loading a specified person.
`large_person_group_id` is created in `large_person_group.create`.
person_id: Specify a certain person in a person group. `person_id` is
created in `person.create`.

Returns:
The verification result.
“””
url = ‘verify’
json = {}
if another_face_id:
json.update({
‘faceId1’: face_id,
‘faceId2’: another_face_id,
})
else:
json.update({
‘faceId’: face_id,
‘personGroupId’: person_group_id,
‘largePersonGroupId’: large_person_group_id,
‘personId’: person_id,
})

return util.request(‘POST’, url, json=json)

cognitive_face より

 

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
“””
File: person_group.py
Description: Person Group section of the Cognitive Face API.
“””
from . import util

def create(person_group_id, name=None, user_data=None):
“””Create a new person group with specified `person_group_id`, `name` and
user-provided `user_data`.

Args:
person_group_id: User-provided `person_group_id` as a string. The valid
characters include numbers, English letters in lower case, ‘-‘ and
‘_’. The maximum length of the personGroupId is 64.i
name: Person group display name. The maximum length is 128.
user_data: User-provided data attached to the person group. The size
limit is 16KB.

Returns:
An empty response body.
“””
name = name or person_group_id
url = ‘persongroups/{}’.format(person_group_id)
json = {
‘name’: name,
‘userData’: user_data,
}

return util.request(‘PUT’, url, json=json)

def delete(person_group_id):
“””Delete an existing person group. Persisted face images of all people in
the person group will also be deleted.

Args:
person_group_id: The `person_group_id` of the person group to be
deleted.

Returns:
An empty response body.
“””
url = ‘persongroups/{}’.format(person_group_id)

return util.request(‘DELETE’, url)

def get(person_group_id):
“””Retrieve the information of a person group, including its `name` and
`user_data`. This API returns person group information only, use
`person.lists` instead to retrieve person information under the person
group.

Args:
person_group_id: `person_group_id` of the target person group.

Returns:
The person group’s information.
“””
url = ‘persongroups/{}’.format(person_group_id)

return util.request(‘GET’, url)

def get_status(person_group_id):
“””Retrieve the training status of a person group (completed or ongoing).
Training can be triggered by `person_group.train`. The training will
process for a while on the server side.

Args:
person_group_id: `person_group_id` of the target person group.

Returns:
The person group’s training status.
“””
url = ‘persongroups/{}/training’.format(person_group_id)

return util.request(‘GET’, url)

def lists(start=None, top=None):
“””List person groups and their information.

Args:
start: Optional parameter. List person groups from the least
`person_group_id` greater than the “start”. It contains no more
than 64 characters. Default is empty.
top: The number of person groups to list, ranging in [1, 1000]. Default
is 1000.

Returns:
An array of person groups and their information (`person_group_id`,
`name` and `user_data`).
“””
url = ‘persongroups’
params = {
‘start’: start,
‘top’: top,
}

return util.request(‘GET’, url, params=params)

def train(person_group_id):
“””Queue a person group training task, the training task may not be started
immediately.

Args:
person_group_id: Target person group to be trained.

Returns:
An empty JSON body.
“””
url = ‘persongroups/{}/train’.format(person_group_id)

return util.request(‘POST’, url)

def update(person_group_id, name=None, user_data=None):
“””Update an existing person group’s display `name` and `user_data`. The
properties which does not appear in request body will not be updated.

Args:
person_group_id: `person_group_id` of the person group to be updated.
name: Optional parameter. Person group display name. The maximum length
is 128.
user_data: Optional parameter. User-provided data attached to the
person group. The size limit is 16KB.

Returns:
An empty response body.
“””
url = ‘persongroups/{}’.format(person_group_id)
json = {
‘name’: name,
‘userData’: user_data,
}

return util.request(‘PATCH’, url, json=json)

日本ディープラーニング協会のイベント(資格試験合格者の会)に行ってきた

7月2日、永田町にて日本ディープラーニング協会(JDLA)の「資格試験合格者の会」に参加してきました。

JDLA

今回は、ジェネラリスト資格とエンジニア資格の合格者双方が集まる初めてのイベントとなりました。

 

参加者800名。ものすごい熱気です。

 

日本ディープラーニング協会の理事長は東大の松尾豊先生です。

 

 

理事長の松尾豊先生の姿も

このイベントでは、合格者同士の交流や、JDLAのメンバーとの交流ができました。

 

今回のイベントでお会いしてきた方々からは、ディープラーニング技術の今後の発展の予感を確かに感じました。

 

JDLA

経産省からも。

JDLA、注目されていますね。

 

トヨタからも。

(先日名古屋で一緒に飲んだ方だったような・・・???)

 

「この中から10人、100人、数百人がディープラーニングで新たなビジネスを立ち上げることを期待しています」といった挨拶でした。

 

レポートは以上です。

備忘:細胞の蛍光画像の検出

ディープラーニングを用いた例。

 

 

DeepYeastも活用

Accurate classification of protein subcellular localization from high throughput microscopy images using deep learning http://www.g3journal.org/content/ggg/early/2017/04/05/g3.116.033654.full.pdf

 

”We have demonstrated that DeepYeast, an 11-layer convolutional neural network, can achieve classification accuracy of 91% for individual cells over twelve subcellular localizations, and 100% for proteins when entire cell populations of at least moderate size are considered. ”

DeepYeast モデルは、特徴量抽出器として使える。

DeepYeastモデルを転移学習することで、目的に応じた細胞検出に用いることができるとみられる。

 

 

本年度のIT導入補助金

IT導入補助金の情報が少し出てきました。

 

補助金の上限額・下限額・補助率

上限額
450万円
下限額
40万円
補助率
1/2以下

 

とのこと。

 

国として中小企業の多くにITを導入することを推し進めています。

 

昨年までは、上限が50万円(条件により100万円)だったのに対し、

今年は450万円と大幅に増額になっていることからも、

国の本気度が伺えます。

 

交付申請は5月27日開始のスケジュールです。

 

詳しくは、

 

https://www.it-hojo.jp/

 

でご確認ください。

 

VGG16 ようやく

VGG16の転移学習によるAIの学習実験が終わりました。

 

とりあえずわかったのは、

  • 計算がめちゃ大変
    • ちょっとのデータを学習するのに数日かかった
  • イチからネットワークを作るのに比べてVGG16の転移学習の方がかなりいい
    • イチから作った場合、すぐに過学習になりがち
    • VGG16の転移学習の場合、過学習になりにくい

 

といったところ。

 

今回は実験のためデータ数が少なく、転移学習の挙動を見るにとどまりました。

 

農作物の等級分類

農作物の等級分類のAIが入り始めていますね。

 

有名なところでは、きゅうりのAIがあります。

 

AIを用いてきゅうりの等級分類を行うものです。

 

さて、以前、試しに作ってみたのですが、

学習の経過に応じて

学習データでは損失関数の値が減少していくものの、

評価用データではロスが途中から増加していく、

いわゆる「過学習」が起きました。

 

原因として考えられるのは、

・そもそもデータ数が少ない

・画像サイズが小さい

・ニューラルネットの構成が適切でない

といったことです。

(きゅうりのデータはネットから拾って加工したもの)

 

こういった問題にたいしては、転移学習を用いるのが良いであろうと気づきました。

 

転移学習の場合は、既に大規模データで学習済みのモデルを使います。

 

しかも、多くのモデルはいわゆる「深い」モデルです。

 

「深い」モデルでは、入力データが層と経過していくに従い、

特徴が抽出されていきます。

 

特に、大規模なデータで学習を行ったモデルは、

特徴抽出器として、大きな威力を発揮します。

 

今回、VGG16というモデルを使用してAIを作成してみてます。

なお、VGG16は、下の図のような感じのモデルです。

 

この図の緑色の部分が、全結合層になっています。

この、緑色の部分は、画像の特徴量を抽出した後で、

その特徴量をもとにそれが何であるのかを判断する層です。

 

VGG16はImageNetの画像を学習していますので、

分類はその1,000分類です。

 

しかし、実用面では、

その1,000種類に名札に分類できる必要は必ずしもなくて、

実際に使うカテゴリにのみ分類できれば良いのです。

 

その部分は、おそらく、ニューラるネットワークのうち、

最後の全結合層で行われています。

 

今回の転移学習では、

その全結合層の部分のみを入れ替え、学習を行います。

 

MobileNet で転移学習

先日書いた物体認識は、

ml5.js で MobileNetというモデルを

クラウドから読み込んで動いていました。

 

さてそのMobileNetのモデルですが、

そのままでは認識精度がいまいち、

独自のモノの認識ができない、

といった問題があります。

 

今回は、このMobileNetを用いて

転移学習を行うアプリを作ってみました。

 

「転移学習」というのは、簡単にいうと、

既存の認識モデルをベースに改造をしたモデルを作ることです。

使用目的に合わせてカスタマイズする、というとわかりやすいかもしれません。

 

こちらです。パソコン用。

なお、クリックする前に使い方を説明しておきます。

クリックすると、パソコンのWebカメラにアクセスし、画面に映像を表示します。

そのカメラに向かって手で方向を指示します。

8方向ありますので、

それぞれの方向を指さしながら、

画面上の同じ方向のボタンを

それぞれ20回くらいずつ押します。

これで、その方向を示す手の画像を取り込みます。

真ん中の「〇」のボタンは、どちらの方向も指さしていない状態です。

これも、20回くらい押します(もちろん、手はどちらの方向もさしていない状態です)。

その後、画面右下の train ボタンを押すと、転移学習が行われます。

パソコンの性能にもよりますが、数十秒で転移学習が終わると思います。

その後は、指さす向きに応じて、画面のボールが移動します。

 

なお、この転移学習と認識はブラウザ上で行われています。

データがどこかにアップロードされるようなことはありませんのでご安心ください。

 

追記:

このアプリは手の画像でなくても転移学習できます。

試しに、「顔の向き」で転移学習をしてみたところ、うまく動きました。