Taste of Tech Topics

Taste of Tech Topics

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

Elastic Kibana Day Tokyoに参加してきました!

こんにちは。
Elastic Certified Engineerのshin0higuchiです😊
今日は六本木でおこなわれたElastic Kibana Day TOKYOに参加してきました!

13:30 受付〜オープニング

今回の会場は六本木ヒルズ森タワーの49F、アカデミーヒルズというところでした。
f:id:acro-engineer:20190306132602j:plain:w300 f:id:acro-engineer:20190306132859j:plain:w300


割と広めの会場で、参加者は150人弱ほど。
アジェンダ

  1. Kibana Power Hour part1
  2. Kibana Power Hour part2
  3. 日本向けの特別なお知らせ
  4. クロージング

という流れでした。

f:id:acro-engineer:20190306134542j:plain:w500

Elastic社の会社紹介動画が流れて会がスタートします。

14:30 Kibana Power Hour part1

このパートは大まかには下記の2点

  1. Kibanaの歴史
  2. バージョン6の機能紹介およびデモ

が中心でした。

バージョン6の機能紹介およびデモ

紹介されたことの概要を挙げていきます。
機能の細かいところは公式ドキュメント・ブログなどに譲ります。

Spaces

Kibanaのダッシュボードなどのリソースを分けてマルチテナントでの運用が容易になる。
詳細に関しては、下記のブログを読むと良いと思います。
www.elastic.co

ロールアップ

古くなった時系列indexを集計して、サイズの削減をおこなう。
メリットとしては

  1. ディスクを削減できる
  2. indexが縮小するので高速化可能

といったあたり。
集計方法をKibanaのUIから選択して簡単に設定できるのが楽で良いです。

Beats Central Management

名前の通り、Beatsの設定をKibanaから制御できる機能。
現状対応しているのはFilebeatおよびMetricbeatのみだそうです。

Canvas

お待ちかね、Canvasのデモです。
Canvasの概要については、以前に記事を書いているのでKibana Canvasを使ってみた - Taste of Tech Topicsをご参照ください。
近頃かなり力を入れているようで、楽しみです。....と思いましたが、いったん機材トラブル発生。
急遽Elastic大谷さんによるデモが始まります。

InfraUI・LogsUI・APMのデモ
f:id:acro-engineer:20190306150542j:plain:w600


Canvasのデモ内容としては「日本各地の風速気温湿度をリアルタイムに表示する」という内容のWorkpad作成でした。
Canvasはレイアウトやデザインの柔軟性の魅力に加えて、インタラクティブな絞り込みが強化されていくようです。
(将来的にはCanvas上でAlerting設定が作れるようになるという話もちらっと聞きました。)

Reporting+Watcherで定期的にPDF送信可能というのもうれしいポイントです。

16:00 Kibana Power Hour part2

このパートでは今後のロードマップについての話がありました。

Canvas

大まかに挙げると下記のポイントになります。

  1. Canvasを一般公開
  2. カスタム操作
  3. 新しいビジュアルエディター
  4. ビジュアライズからアラート作成 
  5. fully embeddable workpads
  6. import existing visualization from kibana
  7. Geo element and location aware functions
  8. GA coming soon
  9. template
  10. クリックして絞り込んだり遷移したりするドリルダウン機能も検討中

→トリガーという形でカスタムアクションを埋め込むことができるようになる。

その他

  1. Kerberosサポート
  2. 機能コントロール (スペースごとの機能制限など)
  3. アラート管理
  4. Kibana監査ログ

 列挙しましたが、Kibanaの監査機能は以前から欲しいと思っていたので嬉しいニュースです。

Maps

現在の最新版では既に触ることができますが、複数のデータソースをマルチレイヤーで表示することができます。
軽く触っただけですが、いろいろな表現ができて、今後の可能性を感じました。
これからダッシュボード等に組み込まれるのか、まだ情報は多くありませんが要チェックです。

日本向けお知らせ

Kibana日本語化

Kibanaの日本語ローカライズ版は7.1見込み(機能自体は6.7で提供見込み)

ドキュメント日本語化

7.1をターゲットにしている
機械翻訳で実現する予定。
「Elasticsearch」→「弾性検索」のようにならないようエンジンを鍛えているところ。

17:00 懇親会

アローナさんをはじめ、色々な人とお話をすることができました。
個人的にはWatcherUIが今後どうなっていくのかなどを聞くことができて、良かったです。
(写真撮り忘れました。残念....)

まとめ

バージョン7のGAも近づき、Kibanaの大きな進化を目の当たりにしました。
今後も使い倒していきたいと思います。

(ちなみに紹介特典でElastic靴下をいただきました😊)
f:id:acro-engineer:20190306152953j:plain:w300


以上です、お読みいただきありがとうございました。


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

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

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


世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

1/30(水)にElasticテクニカルワークショップを開催します

こんにちは。
Elastic Certified Engineerのshin0higuchiです😊

現在、2ヶ月に1度開催されているElastic社の
Elasticテクニカルワークショップですが、
次回の開催は、今月末の1/30(水)の予定です。

こちらのワークショップは、
Elastic Stackの基本的な使い方を実際に手を動かして学んでいただけるほか、
利用事例などの紹介も実施されます。

参加時に質疑応答なども自由にできる為、
実際の利用・活用の参考になったと毎回好評の
無料で参加できるワークショップなので、この機会に申し込みを!
https://events.elastic.co/2019-01-30-AcroquestWorkshop-Tokyo

概要は下記の通りです。
==============================
日時:
2019年1月30日(水)12:40受付開始
13:00開始 - 17:30終了予定

会場:
CONFERENCE BRANCH 銀座
東京都 中央区 銀座3-7-3

概要:
Elasticsearch/Kibana/Logstash/Beatsのテクニカルワークショップを開催。
ElasticのOEMパートナー企業であるAcroquest Technology社のエンジニアがElastic Stackの基礎から、オプション機能の利用までをハンズオン形式で説明致します。
ぜひこのワークショップで、星野リゾート日経新聞社、リクルートテクノロジーズが活用するElasticsearchの世界を体験頂き、

  1. システムログ分析
  2. マーケティングデータ分析
  3. 経営指標(KPI)の可視化

等の業務、プロジェクトで活用頂ければと思っております。

プログラム:

  1. Elastic 概要
  2. ハンズオン

 - Elasticsearch/Kibana/Logstash/Beatsの紹介およびElasticsearch Service環境でのハンズオン
 - ビッグデータを活用した実践講座

  1. Elastic Stackのオプション機能紹介
  2. Elastic最新動向、事例紹介 、LT、Q&A

対象者:

  1. 自社のデータ分析を行いたい方
  2. Elasticsearchの概要は既にご存知で、これから活用を検討している方
  3. 今後Elasticsearch評価を開始するにあたり、基本機能を習得されたい方
  4. お客様へ提案をされるエンジニアの方

==============================

それでは、お申込みお待ちしております。
この機会で、Elasticを学びましょう!


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

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

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


世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

2018年Advent Calendarの振り返り

皆さんこんにちは。GPUをサンタさんにお願いした@tereka114です。
今年のAdvent Calendarの時期も過ぎ去り、年末まで残すところ後数日ですね。

今年も集めてみると、かなりのブログ記事を執筆しました。
この記事でまとめて紹介させていただきます!

2018年アドベントカレンダーまとめ

はてぶTop3

記事の中で特に人気の高い記事、今年のはてぶTop3の記事を紹介します。

1位:Elastic Stackで簡単!Dockerコンテナ監視ダッシュボード作成

人気の高い2つのOSS、Elastic Stack と Docker の組み合わせはさすがに強い。
皆が使うDockerの監視といったニーズも高かったか、2位にダブルスコア以上の大差を付けて、堂々のTOP。
私も試しに使ってみたい・・・

acro-engineer.hatenablog.com

2位:キーフレーズを自動推定するPositionRankの収束性について解説

PositionRank自体が初耳で、論文でもなく、まさか自分で収束性を解析してしまうとは。
記事内容が面白く、時間をかけないと読めません。
かなりの数学・理論マニア向けと思われたこの記事が、まさかの2位にランクイン!

acro-engineer.hatenablog.com

3位:LambdaからRekognitionを使ってみたら意外なところでハマった話

AWS Rekognitonを使った画像解析を簡単なお試しではなく、実際の業務で本格的に使ってみたからこそハマった内容。
内容よりも、写真に写るボウズの人が気になってしまったのは、私だけでしょうか。。。

acro-engineer.hatenablog.com

最後に

今年のアドベントカレンダーいかがでしたでしょうか?
この中には、仕事で扱っているものも多く、なるほどと感じる内容が多く、読むのが非常に楽しかったです!

また来年、お会いしましょう!皆さん、良いお年を。

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


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

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

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

同一アプリをWeb版とElectron版の両方で作る方法

皆さん、こんにちはmiyasakagoです。
この記事はNode.js_2 Advent Calendar 2018 - Qiitaの23日目です。

0)はじめに

ここ2年くらいで私自身、Electronを実案件の中で使う機会が増えているのですが、比較的遭遇するのは、同一アプリでWeb版もElectron版(デスクトップアプリ)も両方ほしい、というようなシチュエーションです。
f:id:acro-engineer:20181224200843p:plain:h250
例えば、Electronベースで開発されているアプリの一つにSlackがありますが、SlackはWebアプリとしてブラウザ上から利用することも、デスクトップアプリとして利用することも可能になっていますよね。

こういうことを実現したいと思ったとき、どういう方法があるのかいくつか選択肢があり、迷いました。
少し探してもあまり情報がなかったため、いろいろ調べ自分なりに整理してみました。

1)Webアプリを先に作り、Electron上からURL呼び出しする方法
2)Webアプリを先に作り、Electronに移植する方法
3)Electronアプリを先に作り、Webアプリに移植する方法

では、詳細を見ていきましょう。

1)Webアプリを先に作り、Electron上からURL呼び出しする方法

1. 概要

タイトルの通り、Webアプリを開発した後、そのWebページをElectronのウィンドウ上に読み込み動作させる、という方法です。

Electronには、外部のWebページを読み込み、デスクトップアプリ上で動作させる便利な機能があります。
その機能を活用した方法になります。(本機能の概要は後述します。)

2. メリット/デメリット

この方法であれば、WebアプリのソースコードをElectron側に移植するような作業は発生せず、開発はWebアプリ側に注力できます。
一方、制約も出てきます。以下に整理します。

  • メリット
    • 開発コストを抑えられ、納期も短くできる。
    • アプリのバージョンアップが楽。わざわざ更新プログラムを配信してインストールさせなくても、Webアプリを更新すれば、自動的にElectronアプリも更新される。
    • Web版、Electron版それぞれで、同じようなソースコードを2重管理する必要がない。
  • ・デメリット
    • インターネット環境での動作が前提になる。そのため、アプリの要件として許容できるかどうか、先に確認しておく必要がある。
    • Electronのネイティブアプリ用の機能(例:ローカルファイルへのアクセス等)の利用に制限が生まれる。

3. 実現方法

このブログでは、上記の実装方法の詳細までは解説しませんが、2つの代表的な方法の紹介だけ簡単にしておきます。

a. webviewを利用する
  • webviewは、外部のWebページを読み込み、Electronのアプリ上に表示する機能。
  • webviewタグの使い方はHTMLの標準タグであるiframeに似ている。
  • Electronのプロセスとwebviewに読み込んだWebページとの間で情報のやり取りが可能であったりと、iframeには無い便利な機能性を持っている。
  • 本格利用を考える場合、webviewはChroniumが維持管理をしている為、Electronの要望通りにバグ修正が進まないという課題がある。

webviewでできることや実装方法については、以下のページなどに詳しく書かれています。
qiita.com

b. BrowserViewを利用する
  • BrowserViewは、webviewに替わる方法として実装されたもの。
  • webviewと違い、BrowserViewはElectronが維持管理をしている為、バグ修正が進まないリスクを減らせる。
  • 一方、まだwebviewほど機能が充実していないので、その点を踏まえた選定が必要。

BrowserViewの基本的な使い方については、
今年のAdvent Calendarでも紹介されていますので、ここでは割愛します。
qiita.com

参考までに

現在のSlackのデスクトップアプリ(version3.0以降)は、BrowserViewを利用して実現されている代表例の一つです。
なお、Slackは、version2.xまではwebviewを用いており、3.0へのバージョンアップ時にBrowserViewに切り替えたことが、Charlie Hess氏の以下のブログで紹介されています。
slack.engineering

webviewとBrowserViewの選定をする上では、一度読んでおくことをおすすめします。

2)Webアプリを先に作り、Electronに移植する方法

1. 概要

「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」との違いは、Webアプリを作った後にソースコードをElectronに移植する点です。

f:id:acro-engineer:20181224194201p:plain:w500

移植を前提で考える場合、サーバサイドとクライアントサイドは疎結合にしておくことが重要であるため、SPA(シングルページアプリケーション)として開発しておくことをおすすめします。

また、サーバサイドをNode.jsで開発しておけば、ElectronのMainプロセスにサーバサイドのロジックも移植しやすくなるためおすすめです。
逆に、サーバサイドはAPIサーバとしてElectronには移植せず、Electronアプリから呼び出す構成にしても良いでしょう。

2. メリット/デメリット

  • メリット
    • 同じくWebアプリを先行開発する「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」に比べ、Electronアプリへの移植後に、Electronのネイティブアプリ用の機能を追加することが容易。
    • Webアプリ先行であるにも関わらず、移植した結果としてオフラインでも動作するデスクトップアプリを作ることが可能。(※ただし、クライアント-サーバ間の通信部分などは改修する必要がある)
  • デメリット
    • 同じくWebアプリを先行開発する「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」に比べ、移植のコストがかかる。
    • Web版とElectron版でソースコードが2重管理されることになるため、メンテナンスコストが高い。

3)Electronアプリを先に作り、Webアプリに移植する方法

1. 概要

「2)Webアプリを先に作り、Electronに移植する方法」の逆方向への移植を前提とした方法です。

f:id:acro-engineer:20181224194505p:plain:w500

前提として、ElectronアプリはNode.jsによって実行され(Mainプロセスと呼ばれる)、画面描画部分はHTML5、CSS3、JavaScriptによってChromium上で動作します(Rendererプロセスと呼ばれる)。
そのため、利用言語の関係上、ElectronアプリはWebアプリへの移植をしやすい構成になっていると言えます。

2. メリット/デメリット

  • メリット
    • Electronアプリを先に作るため、Electronのネイティブアプリ用の機能(例:ローカルファイルへのアクセス等)の利用に制約が生まれない。
    • そこまで意識せずとも、サーバサイドへの依存を減らした作りになりやすく、オフラインでも動作するデスクトップアプリを作りやすい。
  • デメリット
    • Electron上では、Mainプロセス(Node.jsで動作)とRendererプロセス(Chromium上で動作)はIPC(Inter-process Communication:プロセス間通信)による通信を行う為、その通信部分はそのままWebに移植はできない。
    • Electronのネイティブアプリ用の機能は移植できない為、Web移植時に交換しやすいクラス設計をしておくことが重要。
    • Web版とElectron版でソースコードが2重管理されることになるため、メンテナンスコストが高い。

4)まとめ

ここまで3つの方法を紹介しましたので、メリット/デメリットをまとめます。

No. 方法 メリット デメリット
1 Webアプリを先に作り、
Electron上からURL呼び出しする方法
・開発コストを抑えられ、納期も短くできる
・アプリのバージョンアップが楽
ソースコードの2重管理が不要
・デスクトップ版もインターネット環境での動作が前提になる
・ネイティブアプリ用の機能の利用に制限が生まれる
2 Webアプリを先に作り、
Electronに移植する方法
・ネイティブアプリ用の機能を追加することが容易
・オフラインでも動作するデスクトップアプリを作ることが可能
・1の方法に比べ、移植のコストがかかる
ソースコードが2重管理されることになる
3 Electronアプリを先に作り、
Webアプリに移植する方法
・ネイティブアプリ用の機能の利用に制約が生まれない
・オフラインでも動作するデスクトップアプリを作りやすい
・IPCによる通信部分はそのままWebに移植はできない
・ネイティブアプリ用の機能は移植できない
ソースコードが2重管理されることになる


最後に、上記のどの方法を採用するか決める上で、私が考えている判断基準を書いておきます。

  1. Webアプリ、デスクトップアプリのどちらをメインにするのか
  2. デスクトップアプリにてネイティブ機能の利用はどの程度求められるか
  3. 開発にコストと期間をどれだけ割り当てることができるか

これらの質問への回答とその優先度によって、採用する方法は概ね判断できると考えています。
例えば、分かりやすい例では以下のような具合です。

  • ネイティブ機能はあまり使う予定はなく、短期間での開発が求められる。
    →「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」が良さそう
  • Webアプリメインだが、デスクトップアプリではネイティブ機能もしっかり使いたい。
    →「2)Webアプリを先に作り、Electronに移植する方法」が良さそう
  • デスクトップアプリがメインで、ネイティブ機能をしっかり使いたい。
    →「3)Electronアプリを先に作り、Webアプリに移植する方法」が良さそう

私のように「Webアプリもデスクトップアプリもほしい」というシチュエーションになったら、是非、参考にしてみてもらえたら幸いです。

それでは!

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

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

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
自社製品の開発から活用方法の提案まで関わりたいフロントエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

今日から使えるChainerを使用する際に便利な5つのトリック

メリークリスマス。@tereka114です。
この記事は「Chainer/CuPy Advent Calendar 2018」アドベントカレンダーの24日目です。

qiita.com

Chainerを利用する際の便利なトリックをクリスマスプレゼント代わりにご紹介します。
Chainerは非常に使いやすい良いフレームワークだと思います。
使っていく中で、デバッグやパラメータのチェック、あるいは既存モデルの利用など、かゆいことが必要になる時があり、その方法を調べる事が多くありました。

Chainerはそのようなことにもサポートしており、大変助かっています。
せっかくなので、使ってきたトリックをここで紹介します。

※Chainerのバージョンは5.1.0を用いています。

1. DEBUGモード

ニューラルネットワークは学習した結果、出力が常にNaNになることがあります。
NaNになる原因はゼロ除算や値が高すぎてinfになるなど様々です。
一つ言えることとして、この原因特定は相当厄介です。特定のために、まずは、いつ、どこで発生したのかを探る必要があります。
Chainerが標準で搭載しているDEBUGモードを利用することにより、NaNを検出できます。

例えば、次の例を見てみましょう。意図的にl1レイヤーの出力のあとに、NaNとなるよう変数を代入しています。

import chainer
import chainer.links as L
import numpy as np

class MLP(chainer.Chain):
    def __init__(self):
        super().__init__()
        with self.init_scope():
            self.l1 = L.Linear(2, 2)
            self.l2 = L.Linear(2, 2)

    def __call__(self, x):
        h = self.l1(x)
        h.data[0] = np.nan
        return self.l2(h)


x = np.array([[10, 10]], dtype=np.float32)
model = MLP()
print (model(x))

計算の出力は次の通りになります。

variable([[nan nan]])

今回の例は直接埋め込んでもいるので、ソースを見れば一目瞭然です。
ただし、Residual Networkのように層の数が2桁以上で構成されているネットワークを解析するのは至難の技です。

Chainerでは標準でDEBUG機能を持っています。
各レイヤーの出力にNaNが存在するかを検知します。使い方は次の通りです。環境変数「CHAINER_DEBUG」を1にします。

CHAINER_DEBUG=1 python debug.py 

出力結果は次の通りです。NaNを検出すると、Tracebackが出力されます。
Tracebackを確認するとself.l2で検知していることがわかります。
これによりself.l2を呼び出している付近を確認すれば良いと判断ができます。

Traceback (most recent call last):
  File "debug.py", line 24, in <module>
    print (model(x))
  File "debug.py", line 19, in __call__
★    return self.l2(h) ★
  File "/Users/Tereka/anaconda3/lib/python3.6/site-packages/chainer/link.py", line 242, in __call__
    out = forward(*args, **kwargs)
  File "/Users/Tereka/anaconda3/lib/python3.6/site-packages/chainer/links/connection/linear.py", line 138, in forward
    return linear.linear(x, self.W, self.b, n_batch_axes=n_batch_axes)
  File "/Users/Tereka/anaconda3/lib/python3.6/site-packages/chainer/functions/connection/linear.py", line 289, in linear
    y, = LinearFunction().apply(args)
  File "/Users/Tereka/anaconda3/lib/python3.6/site-packages/chainer/function_node.py", line 288, in apply
    raise RuntimeError(msg)
RuntimeError: NaN is detected on forward computation of LinearFunction

2. 問題のあるパラメータチェック

1のDEBUG_MODEではNaNを検出しました。
このDEBUG_MODEはあくまで各層の出力のチェックのみです。そのため、層のパラメータのどこに影響して得られたかは不明です。
当たり前ですが、数百万の数もあるパラメータを目視で確認するのは難しいです。

そのため、NaNのパラメータを再帰的に探索し、出力するコードを作成しました。
次の関数を使えば出力可能です。モデルを引数として与えれば、パラメータを出力します。

def parameter_check(model):
    for child in model.children():
        if isinstance(child, chainer.link.Link):
            for name, param in child.namedparams():
                # NaNの判定確認
                if np.isnan(param.data).any():
                    print (name)

この関数を試したコードは次のコードです。
Chainの中にChainを作り、sub_l1の変数のWにNaNを代入しました。

import chainer
import chainer.links as L
import numpy as np


class SubMLP(chainer.link.Chain):
    def __init__(self):
        super().__init__()
        with self.init_scope():
            self.sub_l1 = L.Linear(2, 2)
            self.sub_l2 = L.Linear(2, 2)

    def __call__(self, x):
        h = self.l1(x)
        return self.l2(h)


class MLP(chainer.link.Chain):
    def __init__(self):
        super().__init__()
        with self.init_scope():
            self.l1 = L.Linear(2, 2)
            self.sub_mlp = SubMLP()
            self.l2 = L.Linear(2, 2)

    def __call__(self, x):
        h = self.sub_mlp(self.l1(x))
        return self.l2(h)


def parameter_check(model):
    for child in model.children():
        if isinstance(child, chainer.link.Link):
            for name, param in child.namedparams():
                # NaNの判定確認
                if np.isnan(param.data).any():
                    print (name)


model = MLP()
model.sub_mlp.sub_l1.W.data[0] = np.nan
parameter_check(model)

出力は「/sub_l1/W」となるため、発見できています。

3. 再現性の確保

CuDNNを利用する場合、ニューラルネットワークの計算では再現性を確保できないことがあります。
CuDNNを用いて計算した場合は計算順序が担保されないことが知られています。
そのため、計算による誤差が発生し、最終的な計算結果が計算のたびに変化します。

これは、大きく精度に影響する事象ではありません。
ただし、これはデバッグ時に対処に困ることがあります。
デバッグでは、問題事象が再現できなければ、修正できたのか否かの解析が難しくなります。

このCuDNNの動作を決定的に動かす設定があります。
v2以前では、Convolution系のクラスにdetermistic引数がありましたが、v3以降では、chainer.configで設定可能です。
変更するには次のコードを実行しましょう。

chainer.config.cudnn_deterministic = True

4.Fine tuningの実施

Fine tuningは既存のモデルを初期値にして再学習する手法です。
そのため、ベースはResNetを用いて、残りの出力までのネットワークの構造を変更したいといったケースがあります。

例えば、クラス数1000のImageNetの既存モデルからクラス数2のモデルを再学習させたい場合です。
Chainerでは、このようなユースケースにも対応し、簡単に実装できます。
Fine tuningの実装は次のとおりです。
ResNet50Layersのforwardメソッドの出力を"pool5"に指定するとpool5部の出力を獲得し、後の層に繋げられます。

from chainer.links.model.vision.resnet import ResNet50Layers
import chainer
import chainer.links as L
import numpy as np


class ResNetFineTune(chainer.Chain):
    def __init__(self):
        super().__init__()
        with self.init_scope():
            self.resnet = ResNet50Layers()
            self.fc1 = L.Linear(2048, 2)

    def __call__(self, x):
        h = self.resnet.forward(x, layers=["pool5"])["pool5"]
        return self.fc1(h)


x = np.random.rand(1, 3, 224, 224).astype(np.float32)
model = ResNetFineTune()
print(model(x))

5. 実行環境の確認

実行環境の確認は重要です。デバッグ時には、CUDA/CuDNNのバージョンを確認することがあります。
例えば、CUDA/CUDNNのパスを環境変数を設定しています。
しかし、問題が発生したときにどのバージョンがライブラリ内で使われているのかを確認したいです。

> import chainer
> chainer.print_runtime_info()
Platform: Linux-4.4.0-93-generic-x86_64-with-debian-stretch-sid
Chainer: 5.1.0
NumPy: 1.15.0
CuPy:
  CuPy Version          : 5.1.0
  CUDA Root             : /usr/local/cuda
  CUDA Build Version    : 9010
  CUDA Driver Version   : 10000
  CUDA Runtime Version  : 9010
  cuDNN Build Version   : 7102
  cuDNN Version         : 7102
  NCCL Build Version    : 2115
iDeep: Not Available

まとめ

Chainerのトリックを紹介しましたがいかがでしょうか?
デバッグや再現性確認など、仕事でもすぐに使えるものが中心です。
もし、このようなことに苦心しているようでしたらぜひ使ってみてください。

では、メリークリスマス!

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


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

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

Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

ZabbixのデータをElasticsearch+Kibanaで可視化してみた

こんにちは。インフラよりのエンジニアtoshikiです。
本記事はZabbix Advent Calendar 2018の23日目です。

はじめに

2018年10月にZabbix 4.0がリリースされました。
試してみたいことはいろいろとありますが、今回はZabbix 4.0でHistoryデータを、時系列データの扱いが得意なElasticsearchに保存することを試してみました。

バックエンドとしてElasticsearchを利用可能となれば、大量データでもスケールするElasticsearchのメリットを活かすことができそうです。
そして、Kibanaを利用して表現力があるグラフを簡単に作れるかもしれません(?)

なお、この機能は3.4から組み込まれていますが、

Elasticsearch support is experimental!  (3 Elasticsearch setup [Zabbix Documentation 4.0])

とのことで、現在の4.0でも実験中の機能になります。

概要

内容としては、以下の流れで説明します。

  1. Zabbixの設定
  2. Elasticsearchのマッピング定義
  3. Elasticsearchにデータ投入されたことを確認
  4. まとめ

構成として、以下に示す3台のサーバ(CentOS 7.6)を使用しました。
Zabbix, Elasticsearch(データストア), Kibana(可視化サーバ)はそれぞれ各サーバにインストールしてあります。
(Elasticsearch、Kibanaのインストールは各サイト(ElasticsearchKibana)を参照ください。)
また、Zabbix agentも各サーバにインストールしています。

種類 Hostname IP Address
Zabbix Server(MariaDB) zabbix 172.16.10.141/24
Elasticsearch elastic01 172.16.10.151/24
Kibana kibana01 172.16.10.150/24

f:id:acro-engineer:20181223214900p:plain:w500
ノード構成

Zabbixの設定

ZabbixのHistoryデータがElasticsearchに保存されるようにします。
設定については以下のページを参照しました。
https://www.zabbix.com/documentation/4.0/manual/appendix/install/elastic_search_setup

具体的には/etc/zabbix/zabbix_server.confに以下を設定します。

### Option: HistoryStorageURL
HistoryStorageURL=http://172.16.10.151:9200

### Option: HistoryStorageTypes
HistoryStorageTypes=uint,dbl,str,log,text

次にZabbixのWeb画面設定として、/etc/zabbix/web/zabbix.conf.phpファイルに以下を記述します。

// Elasticsearch url (can be string if same url is used for all types).
$HISTORY['url']   = [
        'uint' => 'http://172.16.10.151:9200',
        'dbl' => 'http://172.16.10.151:9200',
        'str' => 'http://172.16.10.151:9200',
        'log' => 'http://172.16.10.151:9200',
        'text' => 'http://172.16.10.151:9200'
];
// Value types stored in Elasticsearch.
$HISTORY['types'] = ['uint', 'dbl', 'str', 'log', 'text'];

Elasticsearchのマッピング定義

Elasticsearchにはマッピング定義(データベースのスキーマ定義に相当)を行います。

マッピング定義の内容を確認するため、以下からソースコードを取得します。
https://www.zabbix.com/download_sources

取得したソースコードのファイル(zabbix-4.0.3.tar.gz)を展開すると以下にマッピング定義が書かれたファイルがあります。
zabbix-4.0.3/database/elasticsearch/elasticsearch.map

こちらのマッピング定義の内容を参照し、KibanaのDev Toolsを利用してマッピング定義を行いました。
(以下を実行しています。)

PUT uint
{"settings":{"index":{"number_of_replicas":0,"number_of_shards":1}},"mappings":{"values":{"properties":{"itemid":{"type":"long"},"clock":{"format":"epoch_second","type":"date"},"value":{"type":"long"}}}}}

PUT dbl
{"settings":{"index":{"number_of_replicas":0,"number_of_shards":1}},"mappings":{"values":{"properties":{"itemid":{"type":"long"},"clock":{"format":"epoch_second","type":"date"},"value":{"type":"double"}}}}}

PUT str
{"settings":{"index":{"number_of_replicas":0,"number_of_shards":1}},"mappings":{"values":{"properties":{"itemid":{"type":"long"},"clock":{"format":"epoch_second","type":"date"},"value":{"fields":{"analyzed":{"index":true,"type":"text","analyzer":"standard"}},"index":false,"type":"text"}}}}}

PUT text
{"settings":{"index":{"number_of_replicas":0,"number_of_shards":1}},"mappings":{"values":{"properties":{"itemid":{"type":"long"},"clock":{"format":"epoch_second","type":"date"},"value":{"fields":{"analyzed":{"index":true,"type":"text","analyzer":"standard"}},"index":false,"type":"text"}}}}}

PUT log
{"settings":{"index":{"number_of_replicas":0,"number_of_shards":1}},"mappings":{"values":{"properties":{"itemid":{"type":"long"},"clock":{"format":"epoch_second","type":"date"},"value":{"fields":{"analyzed":{"index":true,"type":"text","analyzer":"standard"}},"index":false,"type":"text"}}}}}

Elasticsearchにデータ投入されたことを確認

上記の設定後、Zabbixを再起動し、各サーバのZabbix agentをHost登録しました。
しばらくしたのち確認すると、Zabbix側では、CPUのグラフが以下のように参照できます。

f:id:acro-engineer:20181223184146p:plain:w740
CPUグラフ

ダッシュボードは以下のようにしてみました。

f:id:acro-engineer:20181223184242p:plain:w740
Zabbixダッシュボード
Zabbix 4.0でダッシュボードがよりカッコよくなりましたよね。

また、Elasticsearch側でも各Index(uint,dbl,str,log)にデータ(ドキュメント)が入っていることをElasticsearchのcat APIsを利用して確認できます。(#Elasticsearch の cat APIs にまじめに入門する話 - Taste of Tech Topics
※textのIndexは対応する監視アイテムがなかったため、docs.countが0になっています。

f:id:acro-engineer:20181223184208p:plain:w760
ElasticsearchのIndex


Kibanaは簡単にグラフを作成できるため、Zabbixのデータ保存数等をグラフ化してみました。

f:id:acro-engineer:20181223184304p:plain:w740
Zabbixデータのカウント

KIbanaはグラフを簡単に作成できますが、当然ながらZabbixのデータはKibanaでグラフを作成するためのデータ構造にはなっていません。
たとえば、上記グラフでは"dbl"インデックスに保存されたNumeric (float)型のデータ件数をカウントするぐらいはできますが、各データ(ドキュメント)にはホスト情報はなく、アイテムIDが格納されいます。
このため、現状では各ホスト毎や、意図した監視アイテムを簡単に選択してグラフ化するのは難しいですね^^;

まとめ

experimental扱いの機能ですが、ZabbixのバックエンドとしてElasticsearchを利用する設定について試してみました。
対象としてはHistoryデータだけですが、Elasticsearchにデータが保存され、Zabbixの画面でグラフを参照できることを確認できました。
いずれ監視対象が多く、大量データを保持するようなケースがあった場合に、Elasticsearchが一つの選択肢になるかもしれませんね。

追加で、上記で試したのは、各データタイプごとに1つのIndexを作成していますが、Zabbix 4.0では日付でIndexを分ける対応が追加されています。(HistoryStorageDateIndexパラメータを有効に設定)

また、Elasticsearchは、ZabbixによるHousekeeperの対象外となっています。
運用で利用するには、まだ機能的な対応が必要ではありますが、Zabbixの進化を期待している私としては、今後どのように開発が進むのか楽しみなところです。

それでは。

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

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

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
顧客のビジネスをインフラから加速するエンジニア募集! - Acroquest Technology株式会社のインフラエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

キーフレーズを自動推定するPositionRankの収束性について解説

こんにちは。
学生時代に信号処理で使っていた数学の知識を生かして、機械学習関連の仕事をしている3年目の@maron8676です。

本記事はAdvent Calendar 機械学習の数理の21日目の記事となります。

0. はじめに

本記事では、文書からキーフレーズを抽出するアルゴリズムであるPositionRankの収束性について解説します。
原論文[1]には収束について書かれていませんが、アルゴリズムを使うにあたり収束性があるかどうかは気になるところだと思います。
機械学習では初期点によって結果が変わるなんてことはよくある話ですよね
そこで、今回はPositionRankの収束性について関数解析の視点から検証してみます。
結果として、PositionRankのアルゴリズムが作る点列は、任意の初期点に対し唯一つの点に収束するという、とてもよい性質を持っていることが分かります。

1. PositionRankについて

1.1. 目的

PositionRankは文書からキーフレーズ(文書のトピックを表すフレーズ)を抽出するためのアルゴリズムです。
キーフレーズが文書から自動で得られれば、文書を読まなくてもトピックが分かるため便利です。
また、自動で得られたキーフレーズをクラスタリングや、レコメンデーションへ応用することも考えられます。

1.2. 特徴

PositionRankはPageRankから影響を受けているアルゴリズムです。PageRankのページリンクに相当するものが、単語の共起情報となっています。
つまり、重要な単語と共起する単語は重要な単語であるという考えでキーフレーズの抽出を行っていると言えます。
PositionRankでは、単語の共起情報に加え、単語の出現位置を重要度に反映させることによって、共起情報だけを使った場合より精度を高めています。
それでは、PositionRankではどのようにしてキーフレーズを求めているのか見ていきましょう。

1.3. アルゴリズム

PositionRankでは、図1のような流れで各単語の重要度を算出し、高い重要度の単語を使ってキーフレーズを構築します。
単語の重要度が出てしまえば、高い重要度の単語を使ってキーフレーズを構成できます。
そのため以下では、各単語の重要度を導出するアルゴリズムについて注目していきましょう。

f:id:acro-engineer:20181217200127p:plain
図1. PositionRankで単語の重要度を導出するアルゴリズムの流れ

1.3.1. 文書から単語の共起情報を表すグラフを作る

ある単語とある単語が同じ場所で使われることを共起と言います。この共起情報を使って文書からグラフを作ることができます。
例えば、2つ隣までの単語は共起していることにすると、「PositionRankは文書からキーフレーズを抽出するためのアルゴリズムです」という文から
以下のグラフを作れます。

f:id:acro-engineer:20181217194955p:plain
図2. 例文から構成されるグラフ

図2では辺の重みが全て1のため省略しますが、辺の重みは共起回数となります。
実際にはいくつかの文があるため、さらに大きなグラフとなります。

1.3.2. グラフから各単語の重要度を計算する

作ったグラフの隣接行列M \in \mathbb{R}^{|V| \times |V|}と、単語の出現位置から構成したベクトルp \in \mathbb{R}^{|V|}を使い、初期点x_0 \in \mathbb{R}^{|V|}|V|はグラフの頂点数=単語の種類)から以下の計算を繰り返し行うことで各単語の重要度を求めます。
x_{n+1} = \alpha \widetilde{M} x_n + (1-\alpha)p \qquad (0 < \alpha <1)
\widetilde{M}はグラフの隣接行列Mの各行を和が1になるようにl_1ノルムで正規化した行列であり、
p=\Bigl [ \frac{p_1}{p_1+p_2+ \ldots +p_{|V|}},\frac{p_2}{p_1+p_2+ \ldots +p_{|V|}}, \ldots ,\frac{p_{|V|}}{p_1+p_2+ \ldots +p_{|V|}} \Bigr ]^T.
ここで、p_iは単語の出現位置から計算される値です。例えば、i番目の単語が文書の5番目と7番目に出現した場合はp_i=\frac{1}{5}+\frac{1}{7}=\frac{12}{35}となります。

2. アルゴリズムの収束性

それでは、1.3.のアルゴリズムによって作られる点列が唯一つの点に収束することを確認していきましょう。
図3の流れで確認を進めていきます。

f:id:acro-engineer:20181218073153p:plain
図3. 収束を証明する流れ

2.1. 行列\widetilde{M}による線形写像は非拡大写像である

行列\widetilde{M}の各行がl_1ノルムで正規化されていることを使って、非拡大写像であることを示します。
ここでの非拡大写像とは、完備なノルム空間における任意の  x, y \in \mathbb{R}^{|V|} に対し、以下が成り立つ写像A : \mathbb{R}^{|V|} \rightarrow \mathbb{R}^{|V|}のことです。
\|x-y\| \geq \|Ax-Ay\|
\|\cdot\|はノルムです。これ以降はノルムをl_{\infty}ノルム*1として進めていきます。最終的な収束の結果については、ノルムの等価性*2を使うと\mathbb{R}^{|V|}上の全てのノルムについて成り立つことが確認できます。
\widetilde{M}が線形写像であることに注意すると、
\begin{align}\|\widetilde{M}x-\widetilde{M}y\|_{\infty}&=\|\widetilde{M}(x-y)\|_{\infty}\\
&\leq\|\widetilde{M}\|_T\|x-y\|_{\infty}\end{align}
となります。\|\cdot\|_T作用素ノルム
\|A\|_T:=\max_{\|x\|_{\infty}=1}\|Ax\|_{\infty}
です。行列\widetilde{M}の各行はl_1ノルムで正規化されているため、\|\widetilde{M}\|_T = 1となります*3。したがって、行列\widetilde{M}による線形写像は非拡大写像です。

2.2. 実数 0 < \alpha < 1 によるpとの凸結合は縮小写像である

単語の出現位置から構成したベクトルpとの凸結合が縮小写像であることを示します。
ここでの凸結合とは、実ベクトル空間の任意の点x,y \in \mathbb{R}^{|V|}と実数0 < \alpha < 1から得られる
\alpha x + (1-\alpha)y
のことを言います。また、写像fが縮小写像であるとは、完備なノルム空間における任意の点x,y \in \mathbb{R}^{|V|}に対しあるk \in [0,1)が存在して、
\|f(x)-f(y)\|\leq k\|x-y\|
が成り立つことです。
fpとの凸結合
f(x)= \alpha x+(1-\alpha)p \quad (0 < \alpha < 1)
とすると、
\begin{align}\|f(x)-f(y)\|_{\infty}&=\|\alpha x+(1-a)p-\alpha y-(1-\alpha)p\|_{\infty}\\
&=\|\alpha x-\alpha y\|_{\infty}\\
&\leq|\alpha|\|x-y\|_{\infty}\end{align}
となるため縮小写像となります。

2.3. バナッハの不動点定理[2]を適用する

バナッハの不動点定理[2]は以下が成り立つことを示しています。
Tを完備距離空間における縮小写像とすると、Tは唯一つの不動点を持つ
点列x_n=T(x_{n-1})は唯一つの不動点に収束する。
2.1.と2.2.より、PositionRankの1イテレーション
g(x_{n}) = \alpha \widetilde{M} x_n + (1-\alpha)p \qquad (0 < \alpha <1)
は縮小写像であるため、バナッハの不動点定理[2]より唯一つの不動点が存在し、イテレーションを繰り返すことでその不動点に収束します。
   

3. アルゴリズムの収束速度

バナッハの不動点定理[2]により、収束速度も以下のように得ることができます。
\|x^* - x_k\| \leq \frac{\alpha^k}{1-\alpha}\|x_1 - x_0\|
ここで、x^*不動点k \in \mathbb{N}イテレーション回数であり、\alphaは2.2.の凸結合に登場する\alphaです。
実際の例として、距離がl_{\infty}ノルムで\alpha = 0.85*4とした場合を見てみましょう。
ランダムに決める初期値としては、原論文[1]で使われている、全ての成分が\frac{1}{|V|}のベクトルを使うことにしましょう。すると、 \|x_1 - x_0\|_{\infty} < 1となるため、100回イテレーションを回して得られるベクトルx_{100}
\begin{align}\|x^* - x_{100}\|_{\infty} &\leq \frac{\alpha^{100}}{1-\alpha}\|x_1 - x_0\|_{\infty}\\
&=\frac{0.85^{100}}{0.15}\|x_1 - x_0\|_{\infty}\\
&< 5.8 \times 10^{-7}\end{align}
を満たします。100回のイテレーションで十分収束していると言えますね。

4. まとめ

キーフレーズを抽出するアルゴリズムであるPositionRankの1イテレーションが縮小写像であることを示して、唯一つの点に収束することと収束の速度を確認しました。任意の初期点から始めて収束する+指数オーダで収束速度もいいという結果で、安心して使えます。実用上いい結果が出ることも大事なのですが、今回のように収束を検証できることも重要なことなので、何となく使っていたアルゴリズムを見直してみるのもよいのではないでしょうか。

5. 参考文献

[1] Corina Florescu and Cornelia Caragea, PositionRank: An Unsupervised Approach to Keyphrase Extraction from Scholarly Documents
[2] S. Banach, Sur les operations dans les ensembles abstraits et leur application aux equations integrales, Fund. Math. 3(1922), 133–181
[3] 山田 功, 工学のための関数解析, 数理工学社
[4] Sergey Brin and Lawrence Page, The anatomy of a large-scale hypertextual Web search engine

*1 ベクトルx \in \mathbb{R}^{|V|}l_{\infty}ノルムは\|x\|_{\infty} := \max_{1 \leq i \leq |V|}|x_i|です。

*2 ベクトル空間Xに定義されたノルム\|\cdot\|_Aとノルム\|\cdot\|_Bが等価であるとは、ある実数M_2 \geq M_1 > 0が存在して、すべてのx \in Xに対し、M_1 \|x\|_A \leq \|x\|_B \leq M_2 \|x\|_A
が成り立つことを言います。有限次元ベクトル空間に定義可能なノルムはすべて等価であることが知られています([3]を参照されたい)。

*3 証明は省略しますが([3]を参照されたい)、行列とベクトルの積を成分で展開し、
1. (積の絶対値)\leq(絶対値の積)から上界
2. 単位ベクトルとの積から下界
を作って挟み込むことで、l_{\infty}ノルムに対応する行列A \in \mathbb{R}^{|V|}作用素ノルムは
\|A\|_T:=\max_{1 \leq j \leq |V|} \Sigma_{k=1}^{|V|}|a_{jk}|
となることを示せます。

*4 PageRankのdamping factor[4]にならって0.85を設定することが多いようです。

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


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

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

Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com