Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

GiNZAの単語分散表現にchiVeを使って精度向上のお試し

こんにちは。最近シェアハウスのネットワークをIPv6に切り替えたら快適になった@Ssk1029Takashiです。

最近は学習済み単語分散表現が日本語でも充実してきており、語彙の多いもの・ドメインに特化しているものなど選択肢の幅が広がってきています。
日本語処理フレームワークであるGiNZAからもデフォルトで単語分散表現が使用可能です。
今回はワークスアプリケーションさんが作成しているchiVeという学習済み単語分散表現を使って、機械学習の精度を向上できるかを見てみます。

はじめに

単語分散表現とは単語に対して、ベクトルを埋め込む技術で、Word2Vecなどが代表的です。
すでに学習されている分散表現を使用することで、機械学習モデルを作らなくても、近しい単語の検索・文書分類などが可能になります。
例えば、単語分散表現を使用することで「令和」という単語から「平成」という単語が近しい意味であると検索出来たりします。

しかし、単語分散表現を使うときの課題としては、未知語への対応があります。
単語をベクトルに変換するとき、事前学習したモデルが知らない単語はベクトルに変換できないため、精度が落ちてしまうことがあります。
GiNZAにはデフォルトで使用できる単語分散表現モデルがあるのですが、新語への対応に弱い部分があり、例えば「令和」がベクトルに変換できないなどがあります。

しかし、ワークスアプリケーションさんが作成しているchiVeという単語分散表現であれば、新語なども学習されているので、より精度の高い結果が期待できます。
実際に学習している単語の語彙数でも、GiNZAのデフォルトのモデルが、約12万語なのに対して、chiVeは最大360万語となっているので、カバーしている単語の範囲もよりchiVeのほうが広くなっています。

f:id:acro-engineer:20200603075346p:plain

なので、今回はGiNZAの学習済み単語分散表現をchiVeに差し替えて、機械学習の精度が向上するのか試してみます。

GiNZAとは

GiNZAについての詳細な説明は過去の記事に記載しているので、参照してください。
acro-engineer.hatenablog.com

chiVeとは

chiVeとは形態素解析器のSudachiを開発しているワークスアプリケーションさんが作成した、学習済み単語分散表現です。
github.com

以下のような特徴があります。
1. Skip-gramアルゴリズムを元に、word2vec (gensim) を使用して構築した単語分散表現。
2. 約1億のウェブページ文章を含む国立国語研究所の日本語ウェブコーパス(NWJC)から、Sudachiで分かち書きして学習している。
3. Sudachiの短・中・長単位の3つの分割単位の形態素で学習している。

上でも書きましたが、豊富な語彙数が収録されており、最大で約360万語の語彙数を持ったモデルがあります。
GiNZAがデフォルトで使用しているモデルが約12万語のモデルなので、比較すると語彙数の多さがわかりますね。

GiNZAから学習済み単語分散表現を使用する

GiNZAはspacyベースのため、vector属性から学習済み分散表現を参照できます。

import spacy

nlp = spacy.load('ja_ginza')
doc = nlp("平成の次は令和です。")
for sent in doc.sents:
    for token in sent:
        print(token.vector) #単語のベクトルを参照

また、文書や文章単位でもvector属性を参照することが可能で、その場合は、各単語のベクトルを加算平均した値になります。

nlp = spacy.load('ja_ginza')
doc = nlp("平成の次は令和です。")
print(doc.vector) #文書のベクトルを参照

文書のベクトルを簡易的に扱いたいときでも、vector属性から簡単に参照できるので便利ですね。

GiNZAからchiVeの分散表現を使用する

GiNZAからWord2Vecの形式で保存されているchiVeの分散表現モデルを読み込むことで、chiVeを使用できるようにします。
今回は、約310万語収録されている、v1.1 mc5版のモデルを使用しています。

from gensim.models import KeyedVectors

chive_vectors = KeyedVectors.load_word2vec_format('./chive-1.1-mc5-20200318.txt', binary=False) #モデル読み込み
#ベクトル入れ替え
nlp.vocab.reset_vectors(width=chive_vectors.vectors.shape[1])
for word in chive_vectors.vocab.keys():
    nlp.vocab[word]
    nlp.vocab.set_vector(word, chive_vectors[word])

実際に語彙数が増えたのか確認すると、310万x100次元のベクトルが読み込まれています。

nlp.vocab.vectors.shape

(3572384, 300)

クラス分類の精度が向上するか試してみる

単語分散表現の有効性を示すためには、文書分類でどれくらい結果が向上するかがわかりやすいです。
livedoorニュースコーパスというデータセット、ニュース記事とその記事のジャンルがそろっているので、そちらを使って文書分類を学習してみます。

データセット・手法は以下のようになります。

データセット livedoorニュースコーパス
手法 単語ベクトルの加算平均+ランダムフォレスト

まずは学習用にデータを作成します。

import pandas as pd
from sklearn.model_selection import train_test_split
import numpy as np

def parse_doc(sentence):
  sentence = re.sub(r'https?\S+\n', " ", sentence)
  # 解析のノイズになる特殊文字を削除する
  sentence = re.sub(r'[\._-―─!@#$%^&\-‐|\\*\“()_■×+α※÷⇒—●★☆〇◎◆▼◇△□(:〜~+==)/*&^%$#@!~`){}[]…\[\]\"\'\”\’:;<>?<>〔〕〈〉?、。・,\./『』【】「」→←○《》≪≫\n\u3000]+', "", sentence)
  return sentence


df = pd.read_csv("./text/livedoor.tsv", delimiter="\t")
df["article"] = df["article"].apply(parse_doc)

X = []
y = df["category"]

with nlp.disable_pipes(["ner", "parser"]):
  for article in df["article"].tolist():
    doc = nlp(article)
    X.append(doc.vector)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

次に、学習して、精度を確かめてみます。

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.metrics import classification_report

rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
y_pred = rfc.predict(X_test)
print(classification_report(y_test, y_pred))

GiNZAのデフォルトの分散表現で学習した結果は以下になります。

                precision    recall  f1-score   support

dokujo-tsushin       0.83      0.84      0.83       185
  it-life-hack       0.81      0.70      0.75       200
 kaden-channel       0.71      0.73      0.72       177
livedoor-homme       0.77      0.62      0.69        90
   movie-enter       0.81      0.95      0.87       163
        peachy       0.75      0.70      0.72       170
          smax       0.85      0.86      0.86       154
  sports-watch       0.90      0.95      0.92       180
    topic-news       0.75      0.77      0.76       155

      accuracy                           0.80      1474
     macro avg       0.80      0.79      0.79      1474
  weighted avg       0.80      0.80      0.80      1474

これが、chiVeを使用すると、以下の結果になります。

                precision    recall  f1-score   support

dokujo-tsushin       0.77      0.83      0.80       180
  it-life-hack       0.82      0.75      0.78       161
 kaden-channel       0.81      0.79      0.80       187
livedoor-homme       0.87      0.54      0.67        96
   movie-enter       0.81      0.95      0.88       177
        peachy       0.76      0.76      0.76       181
          smax       0.92      0.88      0.90       168
  sports-watch       0.90      0.94      0.92       171
    topic-news       0.78      0.82      0.80       153

      accuracy                           0.82      1474
     macro avg       0.83      0.81      0.81      1474
  weighted avg       0.82      0.82      0.82      1474

結果としてはF1値が0.80から0.82と0.02ポイントの精度向上ができました。
語彙数が増えた分、精度は向上できました。

まとめ

今回は、ワークスアプリケーションさんが公開している学習済み単語分散表現のchiVeを紹介して、GiNZAから使用する方法を紹介しました。
学習済み単語分散表現はクラス分類や検索など、多数の使い道があるだけに、モデル自体の語彙数が重要になってきます。
chiVeは語彙数が豊富で、使いたい場面も多そうです。
それではまた。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

CVPR2020参加記「本会議に参加、面白い論文が増えた」 #cvpr2020

皆さんこんにちは
@tereka114です。
CVPRの本会議が一通り終了して落ち着いたので、その内容を紹介していきます。

※CVPR2020については、次のリンクをご覧ください。
acro-engineer.hatenablog.com

Opening

Openingでは、参加者の統計情報やAwardなどが紹介されていきます。
ここは主要な統計情報を紹介します。
参加者数は7000人程度で、2年前のCVPRと同程度です。やはり、コロナウィルスの影響が出ています。

f:id:acro-engineer:20200619135240p:plain:w720

参加者と異なり、論文数は今年も上昇しています。
Oral/Posterへの参加者は純粋に論文の品質で決まるそうで、採択率は下がっています。
1467本の論文が採択されているため、この中から面白い論文を探し出し、チェックしていく必要があります。
(全てチェックするのはやはり無理でした)

f:id:acro-engineer:20200619135450p:plain:w720

国別の著者数です。圧倒的に中国とアメリカが多いです。
日本は1.7%程度の著者数で大きく開きがありますね。

f:id:acro-engineer:20200619135544p:plain:w720

提出された論文の領域の一覧です。
今年から、AIの説明に関するExplainable AIやFairnessといったAIの公平性に焦点を当てたものも一分野として成立しています。
f:id:acro-engineer:20200619141215p:plain:w720

参加してみて感じたこととして、特にTransfer Learningあたりは増えたと感じています。
これに類するOralのセッションが3つ開催されていました。

Oral/Poster

毎年のCVPR同様、OralとPosterがあります。
Oralでは、5分間の発表が行われ、Posterでは1分の発表が行われます。
どちらも収録済の動画を選び、各自見ていく形式での開催方式です。

動画を見るだけならば、実はPDT時間で参加する必要はなく、任意の時間で見ることも可能です。
今年参加して感じたこととして、昔からのImageNetで精度が上がった、もしくは、ブロック芸のような論文は減りつつある印象です。
Oralには、Transfer Learning、弱教師なし学習、その他学習系のトリックも含まれており、非常に面白い論文も多かったです。

私自身が特に面白いと感じた論文は次のとおりです。

  • Erasing Integrated Learning: A Simple Yet Effective Approach for Weakly Supervised Object Localization
  • Few-Shot Pill Recognition
  • BBN: Bilateral-Branch Network With Cumulative Learning for Long-Tailed Visual Recognition
  • Don’t Hit Me! Glass Detection in Real-world Scenes
  • ActBERT: Learning Global-Local Video-Text Representations

※「Erasing Integrated Learning: A Simple Yet Effective Approach for Weakly Supervised Object Localization」は「第三回 全日本コンピュータビジョン勉強会(前編)」で紹介する予定です。
kantocv.connpass.com

KeyNote

今年は、KeyNoteがありました。
2年前にCVPRに参加した際にはなかったコンテンツだったように感じます。
KeyNoteとして、Microsoft社のChief Executive OfficerであるSatya Nadella氏とAmazonのVice PresidentのCharlie Bell氏のインタビューが別々にありました。
コロナウィルス下の変化、各社でのComputer Visionへ期待することの話があり、実社会と改めて近い分野であることを実感しました。

f:id:acro-engineer:20200623225517p:plain:w720

最後に

CVPR2020参加前はどうなるのだろうと思っていたところもありました。
現地の会場でなくても、論文を一気に読むことができ、トレンドを吸収できるのはやはりいいものだと思いました。
しかし、現地の雰囲気から感じられるものもあるので、無事にコロナが収まれば、来年は現地で参加したいと思っています。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

CVPR2020参加記「初めてのバーチャル開催、チュートリアルが充実」 #cvpr2020

皆さんこんにちは。
@tereka114です。

今週からCVPR2020がはじまりました。
本記事では初日と2日目に参加したWorkshop/Turtorialを紹介します。

f:id:acro-engineer:20200616135912p:plain

CVPR2020

CVPR2020の正式名称は「Computer Vision and Pattern Recognition」です。
6月14日〜19日まで開催されています(時間はPDT)
これは、アメリカのコンピュータビジョンの国内学会で、毎年非常に盛り上がっています。

今回、私は1年ぶりに参加しています。
コロナウィルスの影響で現地開催ではなく、バーチャル開催になりました。
PDT(日本から16時間遅れ)の時間とそれから12時間後に動画が放送されています。

日本にいながら、私はシアトル時間で参加しています。
普段の現地参加と異なり、太陽の時間がずれているので、体調を整えるのが難しい感覚です。

cvpr2020.thecvf.com

自動運転技術の基本を学べるチュートリアル

初日はチュートリアル「All About Self-Driving」に参加しました。
www.allaboutselfdriving.com

このチュートリアルでは、Zoomのセミナー機能を利用し、既に収録されている動画が放映されます。
途中でSlidoから質問を拾い、質疑応答を行っていました。

このチュートリアルは、自動運転技術に必要なことを包括的に紹介していました。
例えば、ハードウェア(LiDAR、RADERなど)からソフトウェア(物体検出、予測、コントロール方法など)のそれぞれの種類と長短の説明がありました。
私自身、自動運転技術の細かいハードウェアや方式にはあまり馴染みがないところもあったので、新しく得られた学びも多かったです。

f:id:acro-engineer:20200615102403p:plain:w720

2日目:深度推定と最適化

2日目は午前と午後で異なるセッションに参加していました。

Learning and understanding single image depth estimation in the wild

公式ページで動画が公開されているので、それを見てました。
質問は発表時間中にリアルタイムで受け付けていました。

単眼深度推定のチュートリアルで、深度推定を行う上での仕組み(視差)、データセット、そして、各種アルゴリズムの紹介が行われていました。
新しい分野でも包括的に学べて、資料も公開され、後で振り返られるのが良いところです。

sites.google.com

f:id:acro-engineer:20200616142257p:plain:w720

From NAS to HPO: Automated Deep Learning

このチュートリアルはハイパーパラメータとアーキテクチャのチューニングの話です。
機械学習には多くのハイパーパラメータが存在し、そのパラメータを調整する方法も知られています。
また、最近だと、ニューラルネットワークの構造を自動的に計算する方式もあるので、その件も紹介されていました。

ハンズオン付きで実装もあるので、いざ試してみたい!と思った時に便利そうなのはありがたいことです。
hangzhang.org

f:id:acro-engineer:20200616142437p:plain:w720

最後に

明日からCVPRのメインカンファレンスです。
前年よりも論文数が多く、盛り上がっているなぁと感じています。
ぱっと見面白そうな論文も見られるので、きちんと読んで楽しみたいと思います!

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

LINE BotとAmazon Rekognitionでワーク&ライフハック

こんにちは、DevOpsエンジニアの横山です。

今回は、LINE BotAWSの画像分析サービスを使って社員のワーク&ライフハックを行った内容を紹介したいと思います。

一緒に飲みに行きたい!

※ここで紹介する件は、2019年12月頃のことで、今はコロナのため、会社として飲み会は禁止されています。

Acroは、社員同士で夕食や飲みに行く機会が多く、私が所属するグループの上司もよく飲みに行っています。
ですが、私は上司と一緒に行く機会が減っていました。

そのため、何かしらの方法で「私も一緒に飲みに行きたい」という思いを上司に伝えられないかと考えました。

そこで目を付けたのが、AcroのLINEグループです。
Acroでは、社員の日常を共有する目的で、ランチや夕食などの様子をLINEに投稿する文化が根付いています。
やるなら面白く盛り上がりそうな方法でできないかと思い、LINEで投稿されてくる写真をうまく活用して、自動で上司にメッセージを送れないかと考えました。

調べてみたところ、LINE BotAmazon Rekognition(画像解析サービス)でできそうでしたので、それを使って一気に作ってみてました。

f:id:acro-engineer:20200331183152p:plain:w400

飲みに行ってそうな時間帯に上司が映っている写真が流れてきたら、何かしら返信する、というBotです。
Amazon Rekognition(画像解析サービス)は、思っていたよりも簡単に使えて、週末4日くらいで上記ができました。

Botのおかげもあり、一緒に飲みに行く機会も増えました^^
(直接伝えにくかったわけではないですよ。)

また、以下のような写真にも反応して、Bot自体を楽しむことも増え、盛り上げにもなっています^^
f:id:acro-engineer:20200331183210p:plain:w400
(社員旅行で酔いつぶれているときの1シーン)

笑顔で一日をスタート!

次は「笑顔で一日をスタートする」ために取り組みました。

Acroでは、朝のミーティングをチームごとに毎日行っていて、その時にチームの写真をLINEに投稿しています。
これもみんなで共有するというAcroの文化の一つです。
その写真を見て、一日の最初は笑顔で始めたいよね、という声も出てきていました。

上に書いたLINE Botがここでも使えそうと思いました。

今度は、「笑顔」がキーポイントになりますが、これもAmazon Rekognitionで実現できました。
いい笑顔の人には「褒めの言葉」を、笑顔でない人には「声かけ」をするようにしました。

f:id:acro-engineer:20200331183231p:plain:w400
f:id:acro-engineer:20200331183246p:plain:w400

これにより、みんな笑顔で始めようと意識したり、お互いにコミュニケーションも増えました。

今回は、対象者も多くなり、写真の構成も複雑になるため、社員からもいくつか要望があり、細かいチューニングもしています。
(運用するって、やっぱり大変ですね^^)

やってみて感じたこと

このように、LINE BotAWSのサービスを組み合わせることで、これまで開発がメインではなかった私でも、効果を発揮するサービスを作ることができました。

この一連の流れで大事だと思ったのは、「こんなことをしたい(要求)」からスタートすることでした。
これがあったから、手段にハマることなく、要求の実現にフォーカスし、最速でサービスを作ることができたんだと思います。
(実際、思った以上に受けてもらえたので、私自身驚いています^^)

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

顧客のビジネスをインフラから加速するエンジニア募集! - Acroquest Technology株式会社のインフラエンジニアの求人 - Wantedlywww.wantedly.com

ANGEL Dojo最終発表で「アライアンス賞」を受賞しました!

こんにちは!
2年目エンジニアの古賀です。

先日ブログで紹介したANGEL Dojoですが、 2020年3月6日、最終発表があり、AWSの審査員の方々が選ぶ「アライアンス賞」を受賞しました!
上位3チームに選ばれると貰える賞の1つで、 今回がんばってきたことが1つの形になって、とても嬉しいです。
アライアンス賞の詳細は後ほど^^

※ANGEL Dojo とは、AWS様主催の疑似プロジェクトを通して、 クラウド開発力とAmazonの文化を学び、ビジネスで日本を元気にしよう! という企画です。
 詳細は、以前のブログ(http://acro-engineer.hatenablog.com/entry/2020/02/21/170000)を是非読んでください。
acro-engineer.hatenablog.com

会議の"質"を向上させる HuNam

私たちのチームが何をつくっていたのかというと、会議の"質"を向上させるためのサービス「HuNam」です!
※HuNam(ヒューナム)という名前は社内公募で決まりました。Human Nature Meeting の略で、人間の本質、人間らしい、といった意味合いです。

日本中にあるとされるムダな会議を、生産的かつ心理的安全性の高い、会議の"質"が高い状態にしたい、という思いでこのサービスを作りました!

会議の参加者が、以下のようなHuNam画面を見ることで、自分の行動をその場で改善し、自律的に会議の"質"を向上させていくことができます。

f:id:acro-engineer:20200308144735p:plain:w400
HuNamの画面

最後まで楽しみながらやりきりました!

発表は、コロナウイルスの影響で、完全リモートで行われました。
リモートの分、どう発表したらインパクトが残せるか試行錯誤した結果、プレゼンをライブ中継しました。

少しトラブルもありましたが、プレゼン形式にしたぶん、プレゼンの臨場感や勢いをアピールできた気がします!

ちなみに、今回我々が作ったサービスは、会議を効率化するためのサービスなので、今後Web対応して、リモートでも使えるようにしたいですね^^

f:id:acro-engineer:20200308064158j:plain:w400
プレゼンの様子

f:id:acro-engineer:20200308064227j:plain:w400
配信風景

アライアンス賞とは?

最終発表を聞いた、AWSの審査員の方々が、以下の観点で選んでくださった賞です。

アライアンス賞
• Working Backwards に沿った企画ができているか
• ビジネス的に興味深い/価値がある内容か
• ソリューション全体の完成度

サービスのコンセプトや、技術面までを総合して選んでくださったようです。
特に今回は、「何をしたらお客様は嬉しいのか」というところを、一生懸命考えたので、そこをしっかり評価して頂き、本当にうれしいです!!

また上位3チームに選ばれたので、2020/3/25に開催される AWS Partner Summit Tokyo で発表するチャンスを頂きました。
頑張って作ったサービスを多くの人に見て頂ける場なので、最後までやり切り、より良いものにしたいです!

f:id:acro-engineer:20200308145817p:plain:w400
アライアンス賞を受賞

f:id:acro-engineer:20200308064345j:plain:w400
受賞を喜ぶAcro ANGEL チームのメンバー

Still Day One

今回のANGEL Dojoをきっかけに、お客様視点に立つことや、クラウド開発のイロハを学ぶことができ、とても貴重な経験でした。
企画してくださったAWS様、支えてくれた先輩方、本当にありがとうございました!

また何より、今回のANGEL Dojoに送り出してくれた社長・副社長に受賞の報告ができ、喜んでもらえたので、嬉しかったです。
最後まで応援してくださり、ありがとうございました!

最後に、今回のANGEL Dojoの企画者の方からお祝いのメッセージと共に頂いた、以下の言葉を紹介したいと思います。

'Still Day One'

Amazonの企業理念で、直訳すると「まだ1日目」。意味としては、「毎日が新しい挑戦の始まり」というところでしょうか。
いい言葉ですね。
よりよいエンジニアになれるよう、謙虚に、チャレンジしていきたいと思います!

技術的な詳細な内容は、また後日ブログにする予定なので、お楽しみに!


Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Java/PythonでモダンなWeb開発をしたいエンジニアWanted! - Wantedlywww.wantedly.com



AWS主催「ANGEL Dojo」へのチャレンジ & 中間発表で1位になりました!!

皆さん、こんにちは!
最近機械学習エンジニアからDevOpsエンジニアにキャリアチェンジをしつつある渡邊(@move_fastest)です。
月日が流れるのが早く、昨年3月に入社して、早くも1年が経とうとしています。

実は昨年の年末からAWSジャパン様で企画された、「ANGEL Dojo」に会社の若手を代表して参加させて頂いています!
※ANGEL は APN((AWS Partner Network)Next Generation Engineer Leaders の略

2/14(金)に中間発表を終え、ANGEL Dojoも終盤に差し迫ってきたということで、これまで取り組んできたことを振り返ってみたいと思います!

クラウド開発で日本を元気にする ANGEL Dojo

AWS様公式のHPに「ANGEL Dojo」の定義が書いてあったので引用します。

ANGEL Dojoでは次世代を担うAPNの若手のエンジニアの方々に、擬似プロジェクトを通じてアジャイル、DevOps、モダンなアプリケーション開発などのクラウドネイティブな手法と、様々なInnovationを作ってきたAmazonの文化と考え方を体験いただくことで、お客様にクラウドの価値を100%届けるための基礎的なスキルを実践を通して身につけていただきます。参加者の皆様はここで培ったスキルと、各パートナーの皆様がお持ちのそれぞれの強みを活かすことでお客様のビジネスを成功に導き、日本のITや経済をさらに成長させる主役、すなわち「APN Next Generation Engineer Leader」になっていただきます。

要するに、AWS様主催の疑似プロジェクトを通して、クラウド開発力とAmazonの文化を学び、ビジネスで日本を元気にしよう! という企画です。
IT経験1-3年以内の人が対象で、3月初旬に最終発表があります!

ちなみに、ANGEL Dojoの企画が始まるきっかけとなったのは、ある日AWSのマネージャーの方が「日本を元気にしたい!」と言い出したのがきっかけだそうです。
「日本を元気にしたい!」と思うだけではなく、それを実際に企画してしまう行動力、そしてそれを許容する柔軟な組織文化が凄いなぁと思いつつ、感謝の気持ちでいっぱいです。

↓詳しくはこちらをご覧下さい↓
「日本を元気にする」APN Next Generation Engineer Leaders(ANGEL) Dojo のご紹介


知らないことだらけの疑似プロジェクト

サービスの企画から検討するのって楽しい、けど、難しい

年明け(1/6(月))からプロジェクトがスタートし、最初の2週間は企画のフェーズでした。
"Working Backwards"(逆向き解決法)と呼ばれる、Amazonが実際にサービス企画をする際に使用するフレームワークで、お客様を起点にサービスの企画を行い、それをもとにPR(プレスリリース)を作成しました。

一からサービスを企画するのは想像していたよりもずっと難しかったです。
気づくといつも「お客様が必要としているもの」ではなく、「自分達が作りたいもの」になってしまっていました笑。
そんなとき、「自分達が企画するサービスは、本当にお客様が求めているものなのか?」 この問いに何回も立ち返り、メンバ同士で議論することで、徐々に、お客様が求めているもの(課題)やそれを解決するサービスに対する理解が深まりました。

結果として、(多くの時間を費やしたお陰もあり、)サービス内容をブラッシュアップすることができたので、非常に合理的なフレームワークだと感じました。
何を作っているかというと、みなさんの会社でも(おそらく)非効率になりがちな会議を効率化するためのサービスです。詳細は今後のお楽しみに♪

f:id:acro-engineer:20200219022002p:plain:w400
サービス企画風景

良いサービスを開発したい!

1月終盤より、企画したサービスをもとに、アーキテクチャを考え、実装に入ります。
しかし、自分達で考えたアーキテクチャ、DBスキーマ、レポジトリがナンセンスで、何度もリファクタをする羽目に・・・
普段のプロジェクトでは上司が設計してくれている部分なので、改めて無駄がなく整理されたアーキテクチャを考えてくれている上司の偉大さが身に染みました。ありがたや・・・

本当は1月中にMVP(Minimum Viable Product)を社内リリースして運用してみたかったのですが、間に合わず断念。
その後も中間発表の準備に加え、セキュリティ観点での課題も見つかり、まだ社内リリースができていません。
早く社内にリリースして実際に使ってもらいたいです。

ということで、現在も機能の作成は続けています、正直トライ&エラーの繰り返しですが、より良いサービスを作りたいという思いが強いので、とても楽しい時間です!

f:id:acro-engineer:20200219023423p:plain:w400
もくもくと実装している風景

中間発表で1位に選んで頂きました!

最終発表は3月初旬ですが、2/14(金)に中間発表がありました!
発表は午後からだったのですが、発表で使用するデモ動画、発表資料の修正を当日のランチ頃まで行っており、かなりドタバタしてしまいました。

中間発表では、全15チームが揃って発表することもあり、そこで初めて他の参加企業が作ろうとしているサービスを知ることができました。
どの企業もWorking Backwardsでお客様が日頃感じる不満から逆算した、サービス内容だったので、聞いていて素直に、「このサービス欲しいなぁ」、「このサービスが実在したら、日頃困らなくなるなぁ」と納得させられるものがほとんどでした。

私達の発表では、実際に利用してもらうシーンを想定してもらうため、作成したサービスを使用したデモ動画を紹介しました。
苦労して作成したデモ動画が好評だったこともあり、ありがたいことに中間発表では参加者投票で1位を取ることができました。
ただ、どのチームのサービスも魅力的だったので、本番発表まで残すところ2週間弱、より良いサービスを作れるよう頑張ります!

f:id:acro-engineer:20200219025513j:plain:w400
アクロ発表者(古賀)

f:id:acro-engineer:20200219025655j:plain:w400
アクロ発表者(渡邊)
f:id:acro-engineer:20200219025728j:plain:w400
中間発表見事1位

周りの方々のサポートに感謝

このチャレンジをするにあたって、多くの方々のサポートがあります。
AWS様は、週2~3回の講義、ハンズオンなど多くの企画も実施して頂いており、とても勉強になっています。また、クラウド開発のアーキテクチャやお客様視点で考えるためのコツなど、アドバイスやレビューを何度も実施してもらっており、とても助かっています。本当にありがとうございます!

さらに、この企画は1チーム5人での参加が基本となっていますが、1社で5人というのはなかなか難しく「混合チームとして参加」という案で考えていた中、「どうせやるなら5人でやった方が良い」と送り出してくれた社長・副社長には感謝です!

このように、年始から始動し、色々な方のサポートの元開発を進めているサービスなので、世の中に役立つものとして今後公開できるようにしたいと考えています!
そして、最終発表では1位になって周りで支えてくれた人に恩返しがしたいので、最終発表の3/6(金)に向けて、ラストスパートをかけていきます!
(実は、上位のチームは AWS Partner Summit Tokyo で発表する機会を頂けるので、それもモチベーションになっています)

最終発表の結果もこのブログにて報告するつもりなので、みなさん、お楽しみに!!


Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Java/PythonでモダンなWeb開発をしたいエンジニアWanted! - Wantedlywww.wantedly.com



Deep Java Library(DJL)を使ってみた

hayakawaです。
今回はJavaディープラーニングを実装できるOSSであるDeep Java Library(DJL)を使ってみました。

https://djl.ai/


ディープラーニングで何かをやるとしたら、現状ではPythonで開発するケースが多いですが、
システム全体としてはJavaで開発をしたいが、ディープラーニングの処理を利用したい場合、
これまでだと良いソリューションがなく、別サービスとしてAPI呼び出しをしたり、
JavaからPythonのプロセスを呼び出したりするようなことが必要でした。
ただこれだと、パフォーマンスが求められる場合、なかなか厳しいものがあります。

このOSSはそのようなケースで、Java上でのディープラーニング処理も実行できるようにすることを目指しているようです。

aws.amazon.com

Pythonで学習・モデル作成を行い、それをJavaで推論する、ということもできるようですが、
今回は、基本的な判定処理と学習処理を、Javaのサンプルコードから読み解いてみます。

判定処理

判定処理は、物体の種類と位置を検知する物体検知タスクのサンプルを見てみました。
プリトレーニングモデルを用いて、短いコードで判定を実現しています。

サンプル(ObjectDetetion.java)

    public static DetectedObjects predict() throws IOException, ModelException, TranslateException {
        Path imageFile = Paths.get("src/test/resources/dog_bike_car.jpg");
        BufferedImage img = BufferedImageUtils.fromFile(imageFile);

        Map<String, String> criteria = new ConcurrentHashMap<>();
        criteria.put("size", "512");
        criteria.put("backbone", "resnet50");
        criteria.put("flavor", "v1");
        criteria.put("dataset", "voc");

        try (ZooModel<BufferedImage, DetectedObjects> model =
                MxModelZoo.SSD.loadModel(criteria, new ProgressBar())) { //(1) 

            try (Predictor<BufferedImage, DetectedObjects> predictor = model.newPredictor()) { //(2)
                DetectedObjects detection = predictor.predict(img); //(3)
                saveBoundingBoxImage(img, detection);
                return detection;
            }
        }
    }
(1)モデルの読込み

モデルの読込みは

MxModelZoo.SSD.loadModel(criteria, new ProgressBar()))

というコードでやっています。

最初の MxModelZoo.SSD というところで、物体検知用のアルゴリズムであるSSDを指定し、
さらにSSDのバックボーンとなる画像判定モデルを何にするかを、
上のcriteriaというMapに詰めて指定して渡しています。
今回は"VOC"(PASCAL VOCのデータセット)で学習されたResNet50 v1のモデルを指定しています。

学習済みモデルは、名前の通りMXNet上の物がサポートされているようです。
AWSさんですし、MXNetになりますよね。

MxModelZooで指定できるモデルは以下のページに表で一覧されています。

djl/mxnet/mxnet-model-zoo at master · awslabs/djl · GitHub

表の各列の意味は次の通りです。

説明
Application 画像分類(Image Classification)やポーズ検知(Pose Estimation)などのタスクの種類。
Model Family SSDなどのモデルの分類名。この名前をMxModelZoo.~のところに指定します。
CriteriaとPossible values サンプルコードであったcriteriaに指定できる条件と値の組み合わせです。

今回やっている物体検知(Object Detection)は現在SSDのみをサポートしており、
バックボーンはVGGやMobileNetが使えるようです。

(2)判定器の生成
Predictor<BufferedImage, DetectedObjects> predictor = model.newPredictor()

で、新しい判定器を生成しています。

(3)画像の判定

メソッドの先頭の

Path imageFile = Paths.get("src/test/resources/dog_bike_car.jpg");
BufferedImage img = BufferedImageUtils.fromFile(imageFile);

で読み込んだ画像を、(2)で生成した判定器に

predictor.predict(img);

で渡し、さらに結果をsaveBoundingBoxImage()というprivateメソッドに渡して、
画像上に検知結果の名称と枠線を描画させています。

得られた画像が次のものです。

f:id:acro-engineer:20200214101006j:plain

リポジトリ内の djl/examples/src/test/resources/ ディレクトリに、
試し斬りに使える画像が置いてあるので、

Path imageFile = Paths.get("src/test/resources/dog_bike_car.jpg");

のところを書き換えて試してみましょう。

学習処理

学習の方は、伝統的なMNISTのサンプルがあったので試してみました。

サンプル(TrainMnist.java)

    public static ExampleTrainingResult runExample(String[] args)
            throws IOException, ParseException {
        Arguments arguments = Arguments.parseArgs(args);

        // Construct neural network
        Block block =
                new Mlp(
                        Mnist.IMAGE_HEIGHT * Mnist.IMAGE_WIDTH,
                        Mnist.NUM_CLASSES,
                        new int[] {128, 64}); //(1)

        try (Model model = Model.newInstance()) {
            model.setBlock(block); //(2)

            // get training and validation dataset
            RandomAccessDataset trainingSet = getDataset(Dataset.Usage.TRAIN, arguments);
            RandomAccessDataset validateSet = getDataset(Dataset.Usage.TEST, arguments); //(3)

            // setup training configuration
            DefaultTrainingConfig config = setupTrainingConfig(arguments); //(4)
            config.addTrainingListeners(
                    TrainingListener.Defaults.logging(
                            TrainMnist.class.getSimpleName(),
                            arguments.getBatchSize(),
                            (int) trainingSet.getNumIterations(),
                            (int) validateSet.getNumIterations(),
                            arguments.getOutputDir()));

            ExampleTrainingResult result;
            try (Trainer trainer = model.newTrainer(config)) { //(5)
                trainer.setMetrics(new Metrics());

                /*
                 * MNIST is 28x28 grayscale image and pre processed into 28 * 28 NDArray.
                 * 1st axis is batch axis, we can use 1 for initialization.
                 */
                Shape inputShape = new Shape(1, Mnist.IMAGE_HEIGHT * Mnist.IMAGE_WIDTH);

                // initialize trainer with proper input shape
                trainer.initialize(inputShape);

                TrainingUtils.fit( //(6)
                        trainer,
                        arguments.getEpoch(),
                        trainingSet,
                        validateSet,
                        arguments.getOutputDir(),
                        "mlp");

                result = new ExampleTrainingResult(trainer);
            }
            model.save(Paths.get(arguments.getOutputDir()), "mlp"); //(7)
            return result;
        }
    }
(1) レイヤ構造を定義

ニューラルネットワークのレイヤ構造を、MLPというクラスに生成させています。
MLPクラスのコードはこちらです。
お手軽に多層パーセプトロンを作ってくれるようです。中は次のようになっていました。

public Mlp(int width, int height) {
    add(Blocks.batchFlattenBlock(width * (long) height))
            .add(new Linear.Builder().setOutChannels(128).build())
            .add(Activation.reluBlock())
            .add(new Linear.Builder().setOutChannels(64).build())
            .add(Activation.reluBlock())
            .add(new Linear.Builder().setOutChannels(10).build());
}

width×heightの入力を受け取り、各層で128個、64個、10個の出力をする層を重ねたネットワークを構築しているようです。
層の内容を変えたければこのクラスでやっているようにadd()メソッドで積み重ねて作れます。

(2) モデルの生成

(1)のレイヤ定義を使って

try (Model model = Model.newInstance()) {
    model.setBlock(block);

で初期状態のモデルを生成しています。

(3) データの準備

getDataset()というprivateメソッドを呼び出して、MNIST用のデータを取得します。
Argument(プログラム引数)を渡しているのは、引数で指定したエポック数とバッチサイズに応じたデータ数を引っ張ってくるためのようです。

RandomAccessDataset trainingSet = getDataset(Dataset.Usage.TRAIN, arguments);
RandomAccessDataset validateSet = getDataset(Dataset.Usage.TEST, arguments);

getDataset()の内部では、 Mnist.builder() という組み込みのMNISTデータロード用クラスにデータを作らせていました。

(4) 学習の設定

setupTrainingConfig()というprivateメソッドの内部で、

return new DefaultTrainingConfig(Loss.softmaxCrossEntropyLoss())
        .addEvaluator(new Accuracy())
        .setBatchSize(arguments.getBatchSize())
        .optDevices(Device.getDevices(arguments.getMaxGpus()));

という処理で学習用の設定インスタンスを生成しています。
プログラム引数のバッチサイズや利用してよいGPU数などをセットし、Softmax関数、クロスエントロピー誤差を指定しています。

(5) 学習器の初期化

(4)で生成した環境設定で、学習器を生成しています。

Trainer trainer = model.newTrainer(config))
(6) 学習開始

学習器やデータを渡して、実際に学習を開始します。

TrainingUtils.fit(
        trainer,
        arguments.getEpoch(),
        trainingSet,
        validateSet,
        arguments.getOutputDir(),
        "mlp");
(7) モデルの保存

model.save()を呼ぶとファイルに学習済みモデルを保存できます。

model.save(Paths.get(arguments.getOutputDir()), "mlp");

感想

基本的な判定と学習を見てみましたが、APIの構成内容がオーソドックスで名前にクセも無いため、
他のディープラーニングフレームワークを知っていれば習得は速そうです。

またGPUは勝手に見つけて勝手に使ってくれるらしく楽です。

OpenCVなどを用いる画像処理ライブラリは、DJL側でラッパーを用意しており、
基本的な操作であれば独自にOpenCVを触らないでよさそうです。

上で紹介した以外のサンプルも同じディレクトリに配置されており、
基本的にはサンプルを真似して使えば一通りのことはできそうだと感じました。
Java上のディープラーニングライブラリとしては、良い候補になりそうです。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com