Taste of Tech Topics

Taste of Tech Topics

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

Elastic APMを武器にISUCONに参戦してきた話

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

9/12(土)にISUCON10が開催され、当社から3チーム参加しました。
ISUCONはLINE株式会社さんが主催でお題となるWebサービスをレギュレーションの中で高速化を図るチューニングバトルです。

開催案内 : ISUCON公式Blog

残念ながら全チーム予選落ちでしたが、今年、最も戦果を残せたのではないかと思っています。
その中でチーム「4回目の正直」が終了時点で1801点(全体48位)を獲得し、最も成績が良かったので、その取り組みについて紹介します。

チーム「4回目の正直」構成

名前からお察しですが、実はこれまで3回ISUCONに参加しています。メンバーは次の通りです。

佐々木 峻(Twitter:@Ssk1029Takashi):インフラ担当
野村 勇仁:アプリ、デプロイ担当
山本 大輝(Twitter:@tereka114):アプリ担当

当日はMS Teamsで電話会議をつなぎ、全員リモートで繋ぎながら参加しました。
自分の開発環境がそのまま利用でき、会話もできるので特に問題なかったと思います。
ただ、サーバ構成の検討のときにホワイトボード使えないのは苦労しました。

これまでと異なり、パフォーマンスを計測するのにElastic APMを利用しました。

Elastic APM

当社はElastic Stackのリセラーで、性能解析には積極的に活用しています。
JavaPython、Goなど各種言語にも対応しています。

ISUCONはまずパフォーマンスのボトルネックを素早く把握することが重要です。
そのため、Elastic Stackをベースに簡単にアプリケーションのパフォーマンスやボトルネックを計測できるElastic APMを使いました。

このElastic APMは今回の問題と特に相性がよかったです。Elastic Cloudを使うことで、環境構築も素早く行え、かつ、強力な効果を発揮していました。
Elastic CloudでのAPM構築方法はこちらを参考にしてください。

www.elastic.co

今回高速化するアプリ

今回のアプリはISUUMOと呼ばれるアプリで「イスに似合う不動産を検索できる」総合情報サイトです。
公式によれば、次の要望に基づいて高速化する必要が出てきたようです。

リモートワークの普及によって、自宅のイスが生産性に直結することがわかった。 その調査結果を受けて、よりよい座環境を求め郊外に住むことを考えるユーザーが増加。 また、注目度が増したことで bot からもアクセスが急増し、機会損失が発生している。 結果として ISUUMO にアクセスが集中し、負荷に耐えられないことが目立ってきた。

時系列での取り組み紹介

12:20

README.mdを読む&サーバ接続の設定を行いました。
このあたりでBot対策が将来的に必要そうであること、特定の加点形式を確認しました。
私達が選んだ言語は普段使い慣れているPythonです。

13:30

このあたりでデプロイツール一式、実装の確認、パフォーマンス確認の準備を行いました。
今回は実装を見るだけではボトルネックの部分の判断が難しく、明確にここの精度が低いといったことはわかりませんでした。

適用したElastic APMベンチマークの結果を見ると次のことがわかります。

  • estates/chairsに対する検索が遅い。
  • nazotteのリクエスト頻度は遅いが、回数が少ないので全体のパフォーマンスに影響度はこの時点では低い。
  • low_pricedのリクエストも負荷がかかっている。
f:id:acro-engineer:20200915000614p:plain
Elastic APMリクエスト負荷画面

例えば、/api/estates/searchのリクエスト個別で見てみるとアプリよりもSQLによる負荷が高いことが判断できます。
そのため、このリクエストを改善するためにはSQLの修正が必要です。

f:id:acro-engineer:20200915000631p:plain
/api/estates/searchの詳細画面

14:00

ベンチマークが502例外を吐いているため、復旧を運営が進めていました。
その間Elastic APMを確認しながらの机上での検討やリクエストを投げて、修正の動作確認を行ってました。
このあたりでnginxにBOT対策用の正規表現を入れていました。あまりスコアは変わらなかったので効果のほどは不明です。

15:00

テーブルのINDEXを張りをしていました。
正直あまり効果は少なかったと思っています。
リクエストの平均速度は若干伸びましたがまだまだ不十分です。

16:00

nazotteリクエストを若干高速化しました。
nazotteの取得件数は最大50ですが、点が領域に含まれているかの実行が50件を超えても動いていました。
そのため、プログラムで打ち切ることで若干高速化しました。

16:30

Redisを利用した高速化を進めました。
テーブルへのレコード登録のAPIの発行回数が少なく、テーブルそのものへのレコード更新頻度が少ないことがわかりました。
また、検索は一見、連続値での条件取得に見えますが、よく見ると殆どがただの離散値です。
そのため、限られたパタンになるため、結果のキャッシュを行うのが案外容易であることがわかりました。

更新タイミングで手動ロックを実装し、この方式を実現しました。実装完了した時点でのAPMは次の通りです。
最初と比較するとかなり性能が向上しました。

f:id:acro-engineer:20200913211301p:plain
Elastic APMリクエスト負荷画面(複数台構成前)

18:20

複数台構成を検討し始めました。
複数台を構成するにあたり、DBの負荷が高いことがわかっていました。

また、chair/estatesで干渉する場所はほぼないので、完全に分断する方式を取りました。
最終的には次の構成になりました。

101:Web, Nginx, Redis, DB(chairs)
102:Web
103:DB(estates)

20:00

ここからアプリ改修ではなく、分散処理とベンチマークガチャを進めていました。
最終的にはElastic APM外しを行ってベンチマークガチャを行い1801点まで伸ばしました。

21:00以降

競技終了+参加した3チーム揃っての感想戦です。
生放送の結果報告を楽しみに待ってましたが、本選出場には届きませんでした。

まとめ

Elastic APMを利用してボトルネックは的確に当てることができました。
詳細画面でSQLが問題であり、全体的にMySQLに負荷がかかっていることがすぐに判断できました。
しかし、ボトルネックを当ててもメンバの地力が足りず、修正しきれなかった箇所があったのは反省です。
特にnazotteのN+1外しに失敗するところやMySQL8にはある降順INDEXの利用は勝敗にかなり影響したと思っています。

最後に

運営の皆さん大変な中、ありがとうございました。
今年のISUCON、これまでの参加の中で最もがんばれたと思っています。
惜しいところまで競ったからこそ悔しいと感じていますが、来年も懲りずにリベンジしたいと思います。

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


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

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

モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWebエンジニアの求人 - Wantedlywww.wantedly.com

小麦物体検出のKaggleコンペティションGlobal Wheat Detectionで6位になりました

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

先日まで開催された物体検出のコンペティション「Global Wheat Detection」で6位になりました。
これまでチームではGoldを2度獲得したことがありましたが、ソロゴールドを獲得しました。
Kaggleはじめて6年目でようやく獲得できたので感慨深いです。

本記事では簡単にそのコンペの参加状況を記載します。

コンペティションのサイト
www.kaggle.com

コンペティション概要

コンペティションは、世界各地で撮影された多種の小麦の画像から、1つのモデルで小麦の穂の部分を検出する課題です。
小麦の穂の検出精度が向上することにより、農家の収穫の品質が上がったり、研究者が穂の密度やサイズを正確に計算できたりします。
コンペティションの開催期間は3ヶ月ほどで、5月5日開始、8月4日に終了しました。私は開催の初期の頃から参加していました。
そこから、主催者による終了2週間ほどの期間で提出物のチェックがあり、8月20日に確定しました。

結果、Public 1st/Private 6thでした。後述で説明するデータセットの扱いがなかなか難しく、PrivateとPublicの順位が離れる、いわゆる、Shake upの対策に難儀していました。

f:id:acro-engineer:20200831112235p:plain:w640
Private Leaderboard

難しかったところ

今回の難しいは主にデータセットにあります。
世界中の小麦の写真を集めていますが、品種や地域によって育成度合いや形が全く違います。
また、学習データと評価用のデータには共通となる品種、地域はありません。
そのため、新しい環境でも運用できるモデルを構築しなければなりません。

小麦は環境や品種などで、想像以上に見え方に差分があります。公式の小麦画像によればこれぐらい違います。

f:id:acro-engineer:20200821001705p:plain
小麦画像(Kaggle公式より)

解法

日本語で詳細を書く予定ですが、一応、英語でKaggle Discussionに書いています。
www.kaggle.com

そのため、本記述では詳細は省きますが、簡単に紹介します。
モデルはEfficientDetB3,B4,B5を利用しています。
処理は簡単に次の5段階に分かれています。

1. EfficientDetB3を使って学習データのみでモデルを構築し、評価データ(公開の10枚)に対して疑似ラベル(推論の結果)を作る。
2. 評価データと疑似ラベルに加え、学習データを入れて、EfficientDetB4とB5のモデルを作る。
3. Kernel上で予測したEfficientDetB5の結果を用いて、評価データ(全体)に対して疑似ラベル(推論の結果)を作る。
4. 3で利用したEfficientDetB5を学習データと評価データ(全体)でFinetuninigする。
5. EfficientDetB4(2) + EfficientDetB5(3) + EfficientDetB5(4)を組み合わせて最終的な予測をする。

基本的なソリューションコンセプトはいかにドメインが同じである評価データを利用するかです。
この情報をモデルに取り入れられると、ロバストなモデルの構築ができるのではと考えていました。
仕事でも違う場所にモデルを適用することに応用できそうなので、そのあたりのアプローチについて、自分なりに追求していました。

最後に

コンペ中は色々とありましたが、楽しかったです。
物体検出は仕事で使うことが多いので、仕事でも活かせると思ったテクニックは多々ありました。
仕事にも活かして、製品の改善などに貢献していきたいと思います。

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

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

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

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

ElasticStack7.9新機能紹介

こんにちはElastic Certified Engineerのノムラです。

昨日、Elastic Stackの7.9がリリースされました。
今回も魅力的な機能が追加されました。

そこで、追加された機能のうち特に面白いと思う機能をご紹介します!

EQL(Event Query Language)

エンタープライズライセンスで利用可能となったSIEM向けの新機能です。
ネットワークログやシステムログのような時系列データに対して、マルウェア等の侵入から感染、不正操作までの一連のイベントを簡単に検索可能とします。
www.elastic.co

検索方法

マルウェアが侵入、インストールされたケースを想定し検索を実行します。
以下のような独自クエリで検索が可能となります。

GET /my-index-000001/_eql/search
{
  "query": """
    sequence
      [ process where process.name == "regsvr32.exe" ]
      [ file where (file.size > 0 and stringContains(file.name, "scrobj.dll")) ]
  """
}

条件として、通常のmatch検索だけでなく、sizeの指定やstringContains等のメソッドが利用可能です。

またsequenceを利用することで、検索時の条件を時系列の順に指定可能です。
上記では、
 1ドキュメント目:process.nameが"regsvr32.exe"であるドキュメントを検索
 2ドキュメント目:fileフィールドのsizeパラメータが0より大きく、かつfile.nameフィールドの値に"scrobj.dll"を含むドキュメントを検索
と各シーケンス毎に条件を指定しています。

検索結果

検索結果は以下です

{
  "is_partial": false,
  "is_running": false,
  "took": 60,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "sequences": [
      {
        "events": [
          {
            "_index": "my-index-000001",
            "_id": "OQmfCaduce8zoHT93o4H",
            "_version": 1,
            "_seq_no": 3,
            "_primary_term": 1,
            "_score": null,
            "_source": {
              "@timestamp": "2099-12-07T11:07:09.000Z",
              "event": {
                "category": "process",
                "id": "aR3NWVOs",
                "sequence": 4
              },
              "process": {
                "pid": 2012,
                "name": "regsvr32.exe",
                "command_line": "regsvr32.exe  /s /u /i:https://...RegSvr32.sct scrobj.dll",
                "executable": "C:\\Windows\\System32\\regsvr32.exe"
              }
            }
          },
          {
            "_index": "my-index-000001",
            "_id": "yDwnGIJouOYGBzP0ZE9n",
            "_version": 1,
            "_seq_no": 4,
            "_primary_term": 1,
            "_score": null,
            "_source": {
              "@timestamp": "2099-12-07T11:07:10.000Z",
              "event": {
                "category": "file",
                "id": "tZ1NWVOs",
                "sequence": 5
              },
              "process": {
                "pid": 2012,
                "name": "regsvr32.exe",
                "executable": "C:\\Windows\\System32\\regsvr32.exe"
              },
              "file": {
                  "path": "C:\\Windows\\System32\\scrobj.dll",
                  "name": "scrobj.dll"
              }
            }
          }
        ]
      }
    ]
  }
}

既存のQuery DSLでは実現できない、時系列の順(マルウェアの侵入から不正操作までの順)で条件を指定して検索できるのはかなり便利な機能だと思います。

Data Streams

BASICライセンスから利用可能な時系列データの読み書きを簡単に管理することができる機能です。
Data Stream機能を利用することで、1インデックスの作成単位の設定(年月日、サイズ)をILM画面から設定可能となります。
www.elastic.co

特徴

通常、時系列ログを扱うときには複数のインデックスを作る必要があり、管理が複雑化していました。
例えば、「index-a-202008」「index-a-202009」「index-a-202010」... と月毎にインデックスを作成していました。

DataStreamを利用すると、単一のインターフェースを提供し、インデックス名を意識せず単一の名前で扱うことができます。
またインデックスの作成単位や、そのローテート期間等の管理をGUIから一括で行うことが可能です。

利用方法

利用方法は以下です

インデックスの作成単位を設定する

下記の設定では、25GB毎に新しいインデックスを作成するように定義しています

PUT /_ilm/policy/my-data-stream-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "25GB"
          }
        }
      }
    }
  }
}
Index Templateを定義する

SettingsにLife Cycle Policyを定義します。

PUT /_index_template/my-data-stream-template
{
  "index_patterns": [ "my-data-stream*" ],
  "data_stream": { },
  "priority": 200,
  "template": {
    "settings": {
      "index.lifecycle.name": "my-data-stream-policy"
    }
  }
}
Data Streamを作成する

「my-data-stream-alt」が読み書きの指定対象となります。

PUT /_data_stream/my-data-stream-alt

運用がかなり楽になりそうな機能だと思っており、是非実際に導入してみたい機能です。

Wildcard Datatypeの追加

最後は、Wildcard Datatypeです。
7.9から追加された新しいデータ型でWildcard検索の高速化に利用可能なデータ型です。

特にカーディナリティが高いフィールドに対して、Wildcard Query、Regexp Queryを利用する際、このWildcard Datatypeを利用することで従来のText、Keyword型よりもかなり高速に検索できるそうです。

利用方法

以下のようにIndex Mappingのデータ型にWildcard Datatypeを指定することで、利用可能です

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_wildcard": {
        "type": "wildcard"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "my_wildcard" : "This string can be quite lengthy"
}

POST my-index-000001/_doc/_search
{
  "query": {
      "wildcard" : {
          "value": "*quite*lengthy"
        }
  }
}

より詳細が知りたい方は、昨日投稿されたElastic社のブログも参考になると思います。
www.elastic.co

最後に

今回も内容が濃いリリースでした。

特に、最近のリリースからは
 ・SIEM
 ・データ加工を簡単にする
という部分に力を注いでいるように感じます。

ますます便利になるElasticStackを引き続き使い倒していきたいです!

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


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

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

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

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

RustのCI環境でクロスコンパイルを行う

こんにちは
@maron8676です

今回は、RustプロジェクトでのCI環境構築について紹介します。
最近、自然言語処理のエンジン開発をRustで行っており、その中で実際に試した内容となっています。

Rust

Rustは安全性を担保しつつ、高速なアプリケーションを開発するのに便利なプログラミング言語です。
例えば、以下のような特徴があります。

  1. 同じ値の種類でも、不変な変数と可変な変数では別の型になっており、意図しない変更をコンパイルエラーとして検知できる
  2. ポインタの有効範囲がプログラムで示されるため、無効なアドレスへの参照をコンパイルエラーとして検知できる

公式ページには、以下のように書かれています。

RustはMozillaとコミュニティによって作成された、オープンソースプログラミング言語です。
開発者が最新のマルチコアプロセッサの強力な機能を最大限に活用して、高速で安全なアプリケーションを作成できるように設計されたおり、セグメンテーション違反を防ぎ、スレッドの安全性を保証します。

バイナリの自動作成

Rustで書かれたプログラムを実行するには、実行環境に合わせてコンパイルを行い、実行可能バイナリを作成する必要があります。
Rustのコンパイルは他言語と比較して遅めなので、pushなどをトリガーにしてコンパイルを行います。
実行可能バイナリを作成できるとすぐにバイナリを利用できて便利です。
ここでは、GitLab CI/CDを使ってWindows用バイナリを自動作成する方法を紹介します。

通常のビルド、実行手順

CI環境のビルド方法を見る前に、通常ローカルPCで行うビルド、実行手順について見ていきましょう。
Rustには、cargoというコマンドが含まれています。
このコマンドでビルド、パッケージ管理、ドキュメント生成といった、開発に必要な作業を簡単に行うことができます。

では、ビルド手順を見ていきます。コマンドプロンプトでプロジェクトディレクトリまで移動して、

cargo build

を実行することで、プロジェクトをビルドできます。
--release オプションを付けると、プロダクションビルドできます。
ビルドが成功した場合は、

cargo run

でプログラムを実行できます。
ビルドが成功した時点で、プロジェクトディレクトリのtarget配下にexeファイルが作成されています。
そのため、その場所まで移動したり、ファイルを移動したりして、直接実行も可能です。

CI環境でのビルド手順(GitLab CI/CD パイプライン設定)

全体としては以下のようになります。
こちらを実行することで、GitLabCIのPipelinesからビルド結果のファイルをダウンロードできるようになります。
f:id:acro-engineer:20200509104404j:plain

image: ubuntu:18.04  # 1. image選択

variables:
  TOOLCHAIN: "1.41.1"
  TARGET: "x86_64-pc-windows-gnu"

build:
  script:
    - apt update && apt install -y --no-install-recommends ca-certificates curl gcc g++ g++-mingw-w64-x86-64 # 2. 必要なパッケージのインストール
    - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $TOOLCHAIN -t $TARGET # 3. Rustのインストール
    - export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc-posix CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++-posix # 4. 環境変数の設定
    - cargo build --target $TARGET # 5. ビルド
  artifacts:
    paths:
      - target/x86_64-pc-windows-gnu/release/my_project.exe # 6. 成果物の保存

各要素の説明

  1. image選択
    実はRust公式のdockerイメージ(debianベース)があるのですが、
    debianベースで試行錯誤してもwindowsコンパイルを成功させることができなかったため、
    cross*1を参考にして、ubuntuベースで作ることにしました。
     
  2. 必要なパッケージのインストール
    scriptの1行目では、Rustのインストールに必要なca-certificatesとcurl 、ビルド時に必要なgcc関連をインストールしています。
     
  3. Rustのインストール
    scriptの2行目では、Rustをインストールしています。
    インストール時に--default-toolchainオプションでRustバージョンを、
    -tオプションでビルドターゲットに加える内容を指定できます。
     
  4. 環境変数の設定
    scriptの3行目では、ビルド設定に関わる環境変数を設定しています。
     
  5. ビルド
    scriptの4行目でビルドを行っています。
    cargo buildコマンドに--targetオプションを付けることで、ビルドターゲットを指定できます。
    今回はWindows64bitをターゲットにしています。
     
  6. 成果物の保存
    ビルド結果は所定の場所にできるため、成果物として登録しています。
    ファイル名がmy_project.exeとなっていますが、これはCargo.tomlのnameに書かれた文字列が使われます。

まとめ

本記事では、RustプロジェクトをクロスコンパイルするCI設定について紹介しました。
ビルドの遅さをカバーして、実行時だけでなく開発や動作確認のスピードも上げていきたいですね。

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


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

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWebエンジニアの求人 - Wantedlywww.wantedly.com

*1:crossは実行環境でdockerが使えることを前提としているので、
CIジョブのランナーとしてdockerコンテナを使用する場合は、docker in dockerとなってしまいビルドできません。