orizuru

つながる.見える.わかる IoTソリュ-ション

main_contents

更新情報

工場(製造現場)向けIoTソリューション

自社のIoTシステムを利用した工場(製造業)向けソリューション「Orizuru」は、工場内の各種設備からデータを収集する「ゲートウェイ」、収集したデータ処理をする「データプラットフォーム」、リアルタイムにデータを見える化する「ダッシュボード」、3D CADデータをブラウザ上で表示する「3Dビュー」などの各システムを備えるトータルソリューションになります。

IoTソリューション「Orizuru」では、これらの各ソリューションの個別提供から、「ゲートウェイ」「データプラットフォーム」「ダッシュボード」をパッケージングした「Orizuru IoT」の提供をしております。また、3Dデータをクラウドで管理、表示、検索できる機能を備えた「Orizuru 3D」の提供もしております。

IoTソリューション全体像

IoTソリューション全体像

  • 設備のデータ収集
  • 設備の制御
  • 他のシステムへのデータ連携
  • サーバとのデータ送受信
  • リアルタイム通信
  • リアルタイム検知・通知
  • データの統計処理と機械学習
  • データ保存先選択
  • 各種データのグラフ化
  • 設備ごとの見える化
  • 設備のコントロール
  • ユーザ管理
  • 3Dデータの各種表示
  • 3Dデータの360°ビュー
  • 大容量データの表示

IoTソリューション「Orizuru」の特長

製様々な設備のデータ収集
工作機械で使用するCNCやPLC、産業用ロボット、温度や振動などのセンサーなどのデバイスから各種データを収集することが可能です。様々なデバイスからデータを集約して収集できることで、管理メリットが生まれます。
データの他システムへの連携
昨今様々なwebサービスがありますが、それらの各種webサービスへのデータ連携が可能です。例えば、見える化のwebサービスやBIツールなどへのデータ連携、それ以外にも社内システムへ連携することができます。
データの一元管理
Gateway(ゲートウェイ)から送られてくる様々なデータを一元管理します。様々なソリューションやサービスを使うことによるデータ管理コストを抑えられ、御社の貴重なデータ資産を管理します。
AI、機械学習によるデータ活用
解析したデータを活用し、不良品の検知や製品需要予測、設備異常の検知、製品の故障予測などに繋げることができます。お客様の課題にあわせて必要なデータを取得することから始めていきます。
自動化、予兆保全の実現
AI・機械学習により予測や異常検知できたことをキーとして、次のアクション、すなわち自動化や予兆保全を実現することが可能です。データ活用としてコスト削減や品質改善などを実現します。
各種データのグラフ化
データを目的に応じて表示を変えることが可能です。時系列データーであれば折れ線グラフ、累積データであれば円グラフや棒グラフなどの形式で表示でき、データの取得間隔を狭めることで、リアルタイムデータでの表示も可能です。
巨大な3Dデータをwebで表示
数十GBに及ぶ巨大な3Dデータもスムーズにレンダリングして表示することができます。また、専用ソフトを必要とせず、様々な形式のデータをWebブラウザやスマートフォンで確認することが可能です。
3Dデータの検索
管理しているデータから類似する3Dデータを検索できます。データ形式を問わず、異なる3Dデータを横断して検索可能です。3Dデータ作成前に類似データを確認することで、設計の二度手間を防ぐことができます。
点群データを扱える
CADデータだけでなく、点群データも管理できます。従来は別々に管理していたデータを結合することで、複数のソフトウェアを立ち上げてデータを検索しなければならないといった手間がなくなります。

Orizuru IoT

工場IoT

Orizuru IoTは設備を制御しているCNCやPLC、ロボット、各種センサーとゲートウェイが通信することでリアルタイムにデータを取得、蓄積していくことが可能です。 Orizuru IoTは、マルチデバイス対応ができる国内唯一のソフトウェアです。多くのお客様が実現したいと考えられている、工場、ライン、設備単体の稼働監視や故障原因の特定も、Orizuru IoTでデータを取得することで可能になります。ゼロベースからIoTシステムの開発をすると大規模投資が必要になります。Orizuru IoTならば短時間で設備との通信を確立させることが可能です。 Orizuru IoTによって工場のスマート化を実現させてください。

「Orizuru IoT」の詳細はこちら

Orizuru 3D

3Dデータのweb表示

Orizuru 3DはCAD・点群などの3Dデータを統合管理するソフトウェアです。これまで扱えなかった数十GBに及ぶ容量の巨大な3DデータをWebブラウザで表示できます。それぞれのデータ形式ごとの専用のソフトウェアを使う必要はありません。また、類似する他の3Dデータを、データ形式を問わず横断的に検索できます。クラウドサービスとして提供しているだけでなく、セキュリティや通信速度などのご要望に応じてオンプレミス環境で社内ツールとしてもご利用いただけます。​

「Orizuru 3D」の詳細はこちら

IoTソリューション紹介動画

IoTのお悩み解決

 お客様からIoTに関する様々なお悩みをご相談いただいております。IoTの導入に関することやデータの取得方法、取得したデータの活用方法や見える化など多岐にわたります。このようなお悩みごとに対して弊社としてもなんとか解決したく、日々ご提案をしています。こちらでは、その内容の一部をご紹介します。

パートナー・会員

三菱電機のe-F@ctoryパートナー

e-F@ctory Allianceとは、弊社FA機器との接続親和性の良いソフトウェア・機器を提供するパートナーとそれらを活用しシステムを構築するシステムインテグレーションパートナーとの強力な連携により、お客様に最適なソリューションを提供するためのFAパートナープログラムです。

  • e-F@ctory Allianceの詳細は、こちら をご覧ください。

e-F@ctory Alliance

Aras社の公認パートナー

Aras Innovator®は米国Aras社が開発・提供している、ライセンスフリーのエンタープライズPLM(Production Lifecycle Management)ソリューションです。製品の企画・設計から生産・保守までの製品ライフサイクル全体の管理が行えます。

  • Aras Innovatorの詳細は、Aras PLMソフトウェア をご覧ください。
  • Aras®およびAras Innovator®は、Aras Corporationの登録商標または商標です。

Aras AUTHORIZED Partner 2017

BECKHOFF社の開発パートナー

2018年よりベッコフオートメーション株式会社 の開発パートナーとして、弊社はソフトウエアの開発をサポートさせていただいております。BECKHOFF社製品とソフトウエアとのコミュニケーションを円滑にできる技術支援などを行わせていただいてます。

BECKHOFF

ORiN協議会の会員

ORiN (Open Resource interface for the Network)とは,メーカ・機種の違いを超え、統一的なアクセス手段と表現方法を提供する通信インターフェースです。ロボット、PLC、NC工作機械などの制御装置の情報にアクセスするための標準仕様であり、ORiN2SDKとして実用化されています。

ORiN協議会

AWSパートナーネットワーク(APN)

弊社はAPNコンサルティングパートナーとして、AWS上での顧客のワークロードとアプリケーションの設計、開発、構築、移行、および管理を支援することが可能です。AWSのシステムインテグレーションやアプリケーション開発などご相談いただけます。

AWSパートナーネットワーク(APN)

Attention

はじめに

 今回は、翻訳モデルであるEncoder-Decoderの中で使われるAttentionメカニズムについて解説したい。LSTMなどの詳細についてここでは言及しない。

Encoder-Decoderモデル

 Encoder-Decoderモデルとは、入力系列を出力系列に変換するモデルである。その構造を以下に示す。

入力系列をx=(x_1,\cdots,x_M)、出力系列をy=(y_1,\cdots,y_N)とした。それぞれの末尾に系列の終了を表すeosを追加してある。橙色の矩形がLSTMを表し、EncoderとDecoderの役割を果たしている。EncoderとDecoderは図の赤矢印のみで接続しており、Encoder側の情報は全てこの矢印一本に集約していることになる。
 

Attentionメカニズム

 出力系列のひとつを予測する際、入力系列の各要素に重み付けを行い、これらも予測に利用する仕組みがAttentionである。

ここで

(1)    \begin{eqnarray*} \alpha_n(m)&=&\frac{\exp{(t_n^T s_m)}}{\sum_{j=1}^M\exp{(t_n^T s_j)}} \\ c_n&=&\sum_{m=1}^M\alpha_n(m)\;s_m \end{eqnarray*}

である。上図内のc_nが予測に利用されるメカニズムがAttentionである。t_n,s_mはベクトル(\mathbb{R}^d)なので、指数関数の肩に乗る量は内積であることに注意する(Tは転置を表す)。この式の意味を明確にするため、式(1)を行列で表示する。C^T=(c_1,\cdots,c_N),T^T=(t_1,\cdots,t_N),S^T=(s_1,\cdots,s_M)とし、さらにF_{nm}=\alpha_n(m)と書くことにすれば

(2)    \begin{eqnarray*} F&=&TS^T \\ C&=&{\rm Softmax}(F)S \end{eqnarray*}

と書くことができる。図で示すと以下のようになる。


例えば、Decoder側の要素t_nに注目する。このベクトルとEncoder側のベクトルs_1,\cdots,s_Mとが個々に内積を取ることになり、出力は図に示したようにM次元のベクトルになる。s_mとの相関が強ければm番目の要素が大きくなる。これにSoftmaxを施してSとかけ算を行えば、入力側の要素のうち、t_nとの相関が強い要素s_mにかかる重みが大きくなる。つまり、Attentionとは、出力系列の要素と強く相関する入力系列の要素を抽出する仕組みである。

まとめ

 今回はAttentionの意味を明確に示した。Attentionは最近の深層学習の研究においてかなり重要なメカニズムとなっている。

予測分布とハイパーパラメータについて、とにかく全力でわかりやすく説明する

こんにちは、BBです。
今を時めく予測分布とハイパーパラメータのお二人についてご紹介していきます。
この記事の目的は「予測分布についてどういうものなのかイメージがうまくできていないという方がご自身でソースコードに落とし込めるようになる」です。そもそも僕がそうなりたいと思って記事を書いてます。終盤はPythonコードの説明もあります。

予測分布のご紹介

そもそも予測分布とは

そもそも予測分布とはなにかというと、これです。

(1)   \begin{eqnarray*} p\left ( x_{*} \mid D \right ) = \int p\left ( x_{*} \mid D, \theta  \right )p\left ( \theta \mid D \right ) d \theta \end{eqnarray*}

突如として現れた数式に対して動揺を隠しきれませんが、これが現実です。ここで左辺のp\left ( x_{*} \mid D \right )を予測分布といい、Dを既に観測されている値、\thetaをパラメータ、x_{*}を未知の値といいます。x_{*} \mid D \rightのような縦線はDを固定したときのx_{*}という意味です。

予測分布の「分布」ってなに?

分布、分布と何度も出てきていますがこれはいったい何なのでしょうか。ここでいう分布とは「全部足したら1になる数字の並び」です。例えば\left ( 0.5, 0.5 \right )こんな感じです。\left ( 0.7, 0.1, 0.2 \right )これでもいいです。合計が1になる数字の並び、簡単ですね。 0.7 だの 0.2 だのといった個々の数値のことを「確率」といい、この分布のことを「確率分布」と言ったりします。よく知られている確率は合計が100%ですが、合計が100なのか1なのか程度の違いしかないので同じものとします。

さて、分布について説明してきましたがp\left ( x_{*} \mid D \right )で表される予測分布も同じことです。この確率分布は p\left ( x_{*} \right )のようにp\left (  \right )で書かれることが多いです。カッコの中にはx_{*}が入っているので変数 x_{*} になんかすると出てくる答えを、全パターン並べると上記の「確率分布」になっていることを示しています。注意したいのはx_{*}に適当な値を入れると出てくるのはx_{*}がその値をとりうる確率となっています。例えば\left ( 0.7, 0.1, 0.2 \right )のなかの 0.1 かもしれません。言い換えると変数 x の全パターンの「確率」を並べたのが「確率分布」ということです。

予測分布

もう一度、予測分布の式を眺めてみる

もう一度、予測分布の式を眺めてみるとすでにお気づきかもしれませんが、めっちゃ使われていますp\left ( \right )が。ここまでの知識で予測分布の式を日本語訳してみます。長いのでまずは積分\int d \thetaの中を見てみましょう。p\left ( x_{*} \mid \theta  \right )p\left ( \theta \mid D \right )=>「Dを固定したときの\thetaを変数にとる確率と\thetaを固定したときのx_{*}の確率をかけたもの」となります。Dは観測した値ですので、すでに固定されていますね。パラメータ\thetaで積分というのは\theta全パターンで出てきた値を全部足すということになります。続いて左辺p\left ( x_{*} \mid D \right )=>「Dを固定したときのx_{*}となる確率」つまり観測値をこの式に突っ込んでやると今後起こりうる事象の確率が予測できてしまうということです。さすが予測分布。名前に恥じない働きをしてくれそうです。

予測分布

ハイパーパラメータのご紹介の前に

まずはパラメータだろという話

ハイパーなパラメータの前にそもそもパラメータがよくわかってないよという声が焦燥感とともに僕の中にこだましていますので、まずはパラメータのことをもう少しまとめていきましょう。そもそもパラメータって何でしょうか。ゲームとかではよく耳にする単語ですが、現実世界にパラメータが転がっているのを見たことがありませんし、食べたこともありません。そう、パラメータは数値上でのみ存在し、目的のために作られた都合の良い数字というわけです。たいていのものは食べることで認識してきた僕にとってはなかなかとっつき難い代物です。そんな都合の良い数字ですが、その予測分布で使用されるパラメータの目的は「未知の値について何らかの知見を得る」とはっきりしています。要するに「未知の値についての確率分布を求めるために定義した数字」ということになりますね。また、手元にある情報は観測された値Dだけなのでこれを用いてパラメータ\thetaを計算していくことになります。

グラフィカルモデル

ベイズの定理でパラメータを求めよう

観測された値Dを用いてパラメータ\thetaを計算する手法、これこそがベイズの定理となります。ベイズの定理についての詳細は別の機会にまとめるとして、パラメータの求め方に注目して整理してきたいと思います。

(2)   \begin{eqnarray*} p\left ( \theta  \mid D \right ) = \frac{p\left ( D  \mid \theta \right )p\left ( \theta \right )}{p\left ( D \right )} \end{eqnarray*}

こちらがベイズの定理となりますが、いかがでしょうか。すでに式の読み方はばっちりですね!念のため日本語訳していくとこんな感じです。左辺=>「観測された値Dを固定したときのパラメータ\thetaの確率(事後分布)」、右辺=>「”パラメータ\thetaを固定したときの観測した値Dの確率”(尤度関数)と”パラメータ\thetaの確率”(事前分布)を掛けて”観測された値Dの確率(エビデンス)”で割る」となります。パラメータを求めたいのに右辺にやたらとパラメータが入っているので混乱しますが、ここは先人たちの匠の技で何とかなりますので安心してください。

尤度関数と事前分布と事後分布

式(2)で定義したベイズの定理は問題設定によって適切に尤度関数と事前分布、事後分布を設定してやる必要があります。その前にベイズの定理を使いやすいように少し変形させておきましょう。

(3)   \begin{eqnarray*} \begin{split} p\left ( \theta  \mid D \right ) &= \frac{p\left ( D  \mid \theta \right )p\left ( \theta \right )}{p\left ( D \right )}\\ &\propto p\left ( D  \mid \theta \right )p\left ( \theta \right ) \end{split} \end{eqnarray*}

最後の行では分母にあった観測された値Dの確率、エビデンスが省略されています。求めたい左辺、事後分布は合計が1になる確率分布ですので値そのものにはあまり価値がなく、それぞれの確率の相対的な大小さえ変動がなければ問題ないので固定値となるエビデンスは無視しても問題ないという考え方です。問題によって尤度関数を設定していくのですが、設定した尤度関数に応じて特定の形の事前分布を使用すると事後分布と事前分布が同じ関数形をとることができます。共役事前分布をとるとき左辺のp\left ( \theta  \mid D \right )と右辺のp\left ( \theta \right )が同じ式であらわされます。それがどうしたという感じですが、共役事前分布を使うと後ほど紹介しますが逐次学習が効率的に実施できるようになるなど学習を効率化することができます。

ハイパーパラメータのご紹介

その前に問題設定

さて、ベイズの定理まで説明できましたので具体的に問題を設定して説明していきます。ベイズの定理では問題設定に応じた尤度関数、事前分布、事後分布の設定が必要となるためです。今回はサイコロを投げてどの目が出るかの予測分布を計算したいと思います。そんなものどの目も6分の1になるだろ、と思うかもしれないですが、ここではかなり出来の悪いサイコロを仮定します。そして、そんなことは何も知らないベイズの定理が適切にパラメータを設定できるかが今回の見どころです。

サイコロ問題の尤度関数と共役事前分布

今回の出来の悪いサイコロ問題では確率分布にカテゴリ分布を使います。式にするとこんな感じです。

(4)   \begin{eqnarray*} p\left ( \vec{s}  \mid \vec{\pi} \right ) = Cat\left ( \vec{\pi} \mid  \vec{s} \right ) \end{eqnarray*}

\vec{\pi}はパラメータ、\vec{s}はサイコロの目をベクトルで表現したものになりますが、詳細は後で説明します。カテゴリ分布はサイコロの目のようなきっちり有限個に分類できる事象に対して確率分布を求めることができます。このような確率分布のことを離散確率分布といいます。対して身長が170cmとなる確率のような連続した値を扱うときは連続確率分布といい、このような問題に対しては別の関数を使用します。確率分布がカテゴリ分布の場合は尤度関数にカテゴリ分布、事前分布にディリクレ分布を使います。式(3)に突っ込んでやるとこのようになります。

(5)   \begin{eqnarray*} \begin{split} p\left ( \vec{\pi}  \mid \mathbf{S} \right ) &\propto p\left ( \mathbf{S}  \mid \vec{\pi} \right )p\left ( \vec{\pi} \right )\\ &= \left \{ \prod_{n=1}^{N} Cat \left ( \vec{s}_{n}  \mid \vec{\pi} \right ) \right \} Dir \left ( \vec{\pi} \mid \vec{\alpha} \right ) \end{split} \end{eqnarray*}

くじけず式の説明をしていきましょう。\vec{\pi}はパラメータです。パラメータはディリクレ分布で生成しているので要素の和が1になる6次元の実数ベクトルとなります。\mathbf{S}は観測値です。サイコロの出た目が観測値ですので出た目の情報が配列の形で入力されます。例えばサイコロを1回振って6が出たらこう。

    \begin{eqnarray*} \begin{split} \mathbf{S} &= \begin{bmatrix}\vec{s}_{1}\end{bmatrix}\\ &= \begin{bmatrix}0 & 0 & 0 & 0 & 0 & 1\end{bmatrix} \end{split} \nonumber\end{eqnarray}

2回振って1と3が出たらこう。

    \begin{eqnarray*} \begin{split} \mathbf{S} &= \begin{bmatrix}\vec{s}_{1}\\ \vec{s}_{2}\end{bmatrix}\\ &= \begin{bmatrix}1 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 1 & 0 & 0 & 0\end{bmatrix} \end{split} \nonumber\end{eqnarray}

このように1回振ると一つベクトルが追加され、ベクトルは出た目のところに1、他の目は0が入ります。ややこしいですね。式(5)の2行目、\left \{  \right \}が尤度関数のカテゴリ分布、右側が事前分布のディリクレ分布です。この式を変形していくと1行目左辺の事後分布は以下のように事前分布と同じ形をとることが明らかになります。先ほど説明した共役事前分布というわけですね。

(6)   \begin{eqnarray*} \begin{split} Dir \left ( \vec{\pi} \mid \vec{\hat{\alpha}} \right ) \propto \left \{ \prod_{n=1}^{N} Cat \left ( \vec{s}_{n}  \mid \vec{\pi} \right ) \right \} Dir \left ( \vec{\pi} \mid \vec{\alpha} \right ) \end{split} \end{eqnarray*}

ここで\hat{\alpha}は以下のようなややこしい形になります。Kは観測値の次元の数となりますので、サイコロの目を考えるとK=6となります。

(7)   \begin{eqnarray*} \hat{\alpha} = \sum_{n=1}^{N}s_{n,k}+\alpha_{k},\ k=1,2,\cdots,K \end{eqnarray*}

サイコロ問題の予測分布

さて、予測分布の説明を始めます。数式はこれが最後なのでもう少し頑張りますし頑張ってください。サイコロの目問題では尤度関数はカテゴリ分布や共役事前分布はディリクレ分布というようなお約束がありますが、同じように予測分布はカテゴリ分布となります。式(1)と式(3)、式(4)、式(5)を使って以下のように書くことができます。

(8)   \begin{eqnarray*} p \left ( \vec{s}_{*} \mid \mathbf{S} \right ) = Cat\left ( \vec{s}_{*} \mid \left ( \frac{\hat{\alpha}_{k}}{\sum_{i=1}^{K}\hat{\alpha}_{i}} \right )_{k=1}^{K} \right ) \end{eqnarray*}

パラメータの形が非常にややこしいことになっておりますが、カテゴリ分布の形をとります。\vec{s}_{*}は未知の値、これからサイコロを振って何が出るかを仮定して入力します。つまり右辺に\vec{s}_{*} = \begin{bmatrix}0 & 0 & 0 & 0 & 0 & 1\end{bmatrix}を与えてやれば6が出る確率が計算できるというわけです。もちろん確率なので\vec{s}_{*}に1~6の目それぞれを入力して出力された確率は合計1になります。

ハイパーパラメータは適当に決める??

ようやくハイパーパラメータを説明する準備が整いました。今回のサイコロ問題のパラメータは式(5)の\vec{\pi}が該当します。事前分布であるディリクレ分布の変数を見てみるとパラメータ\vec{\pi}はいいのですが\vec{\alpha}を渡すことが前提となっています。これはパラメータを決めるためのパラメータが必要ということになります。つまり超パラメータ、ハイパーパラメータの登場です。サイコロの場合は6個の目がありますので6個のハイパーパラメータを適当に決めてやります。本当に適当でよいのか、非常に疑わしいのでこれから次の章で実験していきましょう。

予測分布の計算

予測分布の計算概要

言葉での説明も飽きてきたと思いますのでここからはPythonのコードを混ぜながら予測分布計算プログラムの実装と本当にハイパーパラメータは適当でいいのかを確認していきたいと思います。サイコロは1~10000回振ってそれぞれの結果に対して予測分布を計算しています。処理の流れは以下のような感じで行きます。

  1. 出来の悪いサイコロデータを生成
  2. ハイパーパラメータの設定
  3. パラメータの計算
  4. 予測分布の計算

出来の悪いサイコロデータを生成する際にどの目がどの確率で出るかを設定するのですが、この設定した確率を予測分布で求めるというのが今回の目的です。もちろん予測分布にはサイコロデータのみをあたえる為、データを作成する際の確率は知る由もありません。

出来の悪いサイコロデータ作成

出来の悪いサイコロを振ってそれぞれの目の出る確率を以下のように定義してみました。出来が悪すぎるので目が出る確率はすべて違っています。

サイコロの目 1 2 3 4 5 6
目が出る確率 0.03 0.07 0.15 0.20 0.25 0.30

データを作成するために使用したコードは以下のようになります。

saikoro_dataにはサイコロを1~10000回振った結果を格納しています。1回なら1~6の目が何回出たかがそれぞれ[0, 0, 0, 0, 0, 1]、100回なら[ 2, 8, 13, 20, 27, 30]のように順番に入っています。

ハイパーパラメータの設定

値によってどのような影響を見る為、今回はハイパーパラメータを以下1パターンで設定していきます。

パターンA [1, 1, 1, 1, 1, 1]
パターンB [11, 22, 33, 44, 55, 66]
パターンC [66, 55, 44, 33, 22, 11]

値によって計算結果にどのような差が生じるのでしょうか。

パラメータの計算、予測分布の計算

共役事前分布のディリクレ分布を使って\vec{\pi}を求め、予測分布の計算まで一気に行っていきます。コードはこんな感じのを作りました。

まずはパターンAで計算した結果です。
縦軸が確率、横軸がサイコロを投げた回数となっています。

最初はばらつきのあった確率が次第に設定した確率へ収束していく様子がわかります。正しく予測分布が計算できていることがわかりますね。次にパターンBのハイパーパラメータを用いるとどうでしょうか。

収束の速度に多少変化があるようですが、こちらも正しく予測分布が計算できているように見えます。

パターンCの結果は他のパターンと同様に収束しますが、初期の値からぐにゃりと曲がって収束しています。収束には他のパターンより多くの観測値が必要になっています。

ハイパーパラメータは適当でよいのか??

今回の実験ではサイコロを10000回振って予測分布の計算を行いました。その結果はどのパターンでも最終的には適切な値に落ち着いています。その点ではハイパーパラメータは適当な値でもよいということになります。これは式(8)で示した予測分布に使用している\vec{\hat{\alpha}}は観測値の情報を取り込んで精度が改善された為です。\vec{\hat{\alpha}}の定義は式(7)で示していますが観測値s_{n,k}が含まれていますね。このように観測値が潤沢に準備することができればハイパーパラメータは適当に設定してもいつかは精度が担保されそうです。しかし、観測値が充分に入手できない場合はどうでしょうか。サイコロを振るのに飽きてしまう場合は十分に考えられます。それぞれのパターンでは収束までの回数が異なることは先に述べました。特にパターンCのように本来の確率分布とかけ離れた値を設定してしまうと収束にはより多くの観測値が必要となります。つまり観測値が少ない場合はハイパーパラメータは適当に決めるわけにはいかないというのが結論のようです。

共役事前分布のメリット

書くのを忘れてましたが、共役事前分布を使った場合のメリットを挙げておきます。サイコロを使った今回の実験でもサイコロを投げれば投げるほど予測精度が向上するという結果を得られましたが、手元にあるデータが充分であるかどうかは計算してみるまで分かりません。もし観測値が足らなかった場合に最初から計算しなおすのは無駄ですよね。そこで共役事前分布の出番です。手持ちの観測値を使って得られた計算結果つまり事後分布を事前分布として式に与えることによって続きから計算できるというわけです。この性質からリアルタイムデータを使った学習も可能になりますね。

逐次学習

まとめ

今回は予測分布とハイパーパラメータと題してまとめてきました。サイコロの目が出る確率を計算するという問題を扱いましたが、結論としては以下のようなことがわかりました。

  1. サイコロを振れば振るほど予測分布は正解に収束する
  2. ハイパーパラメータの設定は自由度が高いが、予測分布の収束速度に影響がある場合がある
  3. 観測値が少ない場合は収束が速くなるようハイパーパラメータの調整が必要となる

ハイパーパラメータの設定によっては収束速度に影響がある為、手元にある観測値が少ない場合は調整する必要がありそうですね。長くなりましたが今回はこの辺でお開きにしたいと思います!

AIによって文から特定の情報を抽出して文章データを活用する

AIによって文から特定の情報を抽出して文章データを活用する

文からの情報の抽出

IoTとAIの話になるとセンサーから取得した時系列データや製品を撮影した画像、動画を利用するシーンが思い浮かびやすいのではと思います。弊社ではもちろんそのようなデータを用いたソリューションを提供していますが、他にも文章データに対する取り組みもおこなってまいりました。
以前頂いたご相談の中には、社内に従業員やユーザの方々が書いた文章が大量にあり、これを活用していきたいが名前や住所などの個人情報や機密情報が含まれているため、外部にデータを出すことができないといった問題を抱えていたというケースがあります。このようなケースでは文章に含まれる個人情報や機密情報を隠蔽する必要があります。また、個人情報などの隠蔽ではなく、ある種類の単語を文から抽出してシステムの中で利用したいというケースもあります。

semantic_label
個人情報隠蔽の例

 
 
このような問題にどうやってアプローチするとよいでしょうか。お客様の中には文章をそれほど活用してきていないが、文章はとりあえず大量に記録してあるという場合がありますので、それらの文章を人間が手作業で処理するというのは現実的ではないように思えます。
そこで一つ考えられるのはAI(機械学習、ディープラーニング)を利用した方法になります。

AIを使った文からの情報抽出(固有表現抽出)のアプローチ

AIを使ったアプローチではAIに文を与えることで、自動で各単語がどの種類の単語であるかということを識別することができるようになります。先程の個人情報の隠蔽の問題に当てはめると、AIに「山田太郎は人名である」といったことや、「茨城は地名である」といったことを識別させることができ、結果として「人名」や「地名」を抽出することができるようになります。このように「人名」や「地名」といった単語を抽出することを「固有表現抽出」といいます。
このAIを使ったアプローチではAIに学習というものをさせておく必要があります。学習で何をするかといえば、どのような単語がどの種類の単語になりやすいといったことや、どういう文脈のときにどういう種類の単語が出現するか、といった傾向を計算によって見出させることに相当します。このような学習の過程で見出した傾向をもとに、AIが初めて見るような文(学習に使われていない文)に対しても各単語がどの種類であるかということを識別できるようになります。

semantic_label
AIが単語の種類を識別するロジックの例

 
学習に用いるデータとしては、文とその文に含まれる各単語に対してそれぞれがどの種類かを示したラベルというものになります。学習に用いるデータは多ければそれに越したことはありません。ただし、単語に対してラベルを付ける作業は基本的には人間がおこなう必要があるため、手間がかかることになります。

semantic_label
学習に用いる文と各単語にラベルを付けた例

AIを使った文からの情報抽出(固有表現抽出)の例

ここではAIを使った場合の情報の抽出の例を示します。
学習に用いるデータは2000文のニュース記事の各単語に「人名」、「地名」、「組織名」、「その他」のラベルを付けたものとなります(先程の”学習に用いる文と各単語にラベルを付けた例”の図において何もラベルが付いていないところが「その他」に該当しています)。もっとたくさんの文があったほうが精度の面で良くなりますが、今回はラベル付けの手間の都合でこの数にしています。
以下に学習をおこなったAIに2つの文を与えてそれぞれの単語の種類を識別させた結果を示します。単語の下にAIが識別した単語の種類を示しています(ただし「その他」は省いています)。

semantic_label

文の引用元:https://www3.nhk.or.jp/lnews/mito/20181213/1070004942.html
      https://www.sanspo.com/baseball/news/20181213/swa18121313340005-n1.html

この例は大変上手くいっています。AIで「人名」、「地名」、「組織名」と識別した単語のうち、「ヤクルト」以外は学習データには含まれていません(識別できた単語と似ている単語としては、「東京」と「水戸市平須町」が学習データに含まれています)。場合によっては「常磐神社」も「地名」として識別できると良いかもしれませんが、これは学習に用いるデータの量を増やしたり、「神社」が入っている文も学習に用いるようにすることで可能になるかと思います。

終わりに

今回は文から何かしらの情報を抽出する例についてご紹介しました。しかしながら、このような話に限らず社内に眠っている大量の文章をお持ちでそれらを活用したいと考えている方はぜひ一度ご相談ください。AI部分の検証だけやりたい、システム化までやりたいといったご希望の粒度に応じて対応させていただきます。

Tesseract OCR

はじめに

 Tesseract-OCRはオープンソースの文字認識エンジンである。文字認識を担うライブラリとそれを用いたコマンドラインツールが提供される。C/C++APIを用いてプログラム内に組み込むことができるが、そのほか多くの言語によるラッパーも提供される。最近リリースされた最新版(4.0)には、従来の認識エンジンに加え、LSTMベースのニューラルネットワークによる認識エンジンが搭載された。今回の記事では、この最新版の導入手順と使用方法を概説する。私の環境がMacであるので、以下の説明は全てMac環境での動作事例である。

インストール手順

 ビルド済みパッケージをHomebrewを用いてインストールする方法と、ソースからビルドする方法を示す。

Homebrew

 以下のコマンドでインストールできる。

--HEADをつけないと1つ前の3系がインストールされてしまうので注意が必要である。

Macports(ソースのコンパイル)

 Macportsでインストールできるのは3系のみなので、ソースをコンパイルする必要がある。詳細な手順はこちらに記載されている。私が行った手順は以下の通り。最初に依存ライブラリを入れる。

次に、ソースをダウンロードしコンパイルする。

OpenMPを組み込むこともできるが、Macのコンパイラ(clang)がオプション-fopenmpをサポートしておらず今回は割愛した。必要であれば別のコンパイラ(gcc)を用いれば良い。

 ここまでの作業で本体のインストールは完了した。コマンドラインに以下を打ち込んでみる。

訓練済みモデルの導入

 Homebrewによるインストールであれば必要ない作業であるが、ソースから導入した場合は訓練済みモデルをここから別途ダウンロードする必要がある。サポートされる言語は161個である。ダウンロードしたファイルは/usr/local/share/tessdata/に置く。このディレクトリはtesseractがデフォルトで見に行く場所であるので、環境により異なるだろう。

今回は英語(eng.traineddata)と日本語(jpn.traineddata)を用いる。

 ここまでの作業でtesseractを使う準備は整った。

プログラム内での実装例

 C++による実装例は以下の通り。

  • 7行目:読み込む画像へのパス
  • 11行目:OCRオブジェクトを作成
  • 14行目:OCRオブジェクトを初期化。Initの第1引数には言語ファイルが存在するディレクトリへのパスを記載する。デフォルトのディレトリに格納した場合はnullptrにする。第2引数には言語ファイルの種類を記載する。第3引数には認識エンジンの種類を書く。ここではLSTMを用いたエンジンを選択した。
  • 18行目:画像のレイアウト解析のためのオプションである。APIリファレンスを読んでも良くわからないが、このページが参考になる。
  • 21行目:画像を読み込む。
  • 24行目:OCRオブジェクトに画像を設定する。第1引数は画像データ、第2引数は画像の高さ、第3引数は画像の幅、第4引数は1画像あたりのバイト数、第5引数は画像の幅をバイト数に換算した値である。今の場合は幅に3を掛けた値になる。
  • 27行目:OCRを実行する。Getの付く関数は何かを返すだけの処理にすべきである。この関数で認識処理までさせるのはどうかと思う。また、この関数はcharのポインターを返し、メモリ管理はユーザに委ねられる仕様となっている。なのでユーザ側がメモリ解放の責任を負う。std::stringで受けても良い。
  • 31行目:初期化前の状態に戻す。
  • プログラムの実行例

     使用言語をengにし、次の画像を与える(このページから切り出した画像)。

    実行結果は以下の通り。

    全文字正解。

    次は手書き文字を試してみる。ここの画像を用いた。

    結果は以下の通り。

    ところどころ余計な文字や行があるが、ほぼ正解。

    次はこれ。ここから切り出した。

    結果は以下の通り。

    良くない。筆記体は無理なようだ。出力先頭に「Detected 7 diacritics」が出ている。diacriticとは文字の頭につく記号のこと。

     次は日本語で。使用言語をjpnに変更し、以下の画像を読み込む。このページから切り出した。

    結果は以下の通り。

    ” 「 “が” ` “として認識されている。3Dの” 3 “も間違っている。余分な行が挿入されている。

    次は青空文庫から切り出した画像。谷崎潤一郎「痴人の愛」より。

    結果は以下の通り。

    先頭に「Detected 8 diacritics」が出力されているが全文字正解である。

    次は手書き。ここから切り出した。

    結果は以下の通り。

    無理。切り出し元のページではGoodNotesなるメモアプリの紹介をしている。上の手書き文字を難なく認識している。

    まとめ

     今回は、文字認識エンジンTesseract-OCRを紹介した。その最新版にはLSTMベースのニューラルネットワークが搭載されている。使用事例としてC++APIを用いた実装を示し、いくつかのサンプル画像について認識結果を見た。くずれた手書き文字(例えば筆記体など)を除けば、そこそこの精度で認識できている。
     今回は紹介していないが、他言語(例えばPython)による実装も可能である。また、訓練のためのライブラリも提供されている。詳細は本家のサイトを見て欲しい。

    参照文献

    本家以外で参照したページはここである。

    【C#】行列の計算速度比較

    お久しぶりです、エンジニアのMasashiです。

    今回は機械学習の計算処理などでよく使用される行列の積に関する速度比較を行いました。

    自分が関わってきた案件内では、行列の積を求めるような計算処理を使用することはありませんでしたが、
    計算処理として非常にポピュラーなものであるので、単純な2つの方法から計算速度を比較してみたいと思います。

    測定までの流れ

    今回測定を行うのは、1000行1000列の行列と1000行1100列の行列の積を実行した場合の計算完了までに要した時間になります。
    行列内のデータは0~99までの乱数を入れています。

    比較対象としてシングルスレッドで計算処理を実装した場合、マルチスレッドで計算処理を実装した場合の2つについて検証します。
    また、ソースコード上ではGPUを使用した計算処理を実装したものがありますが、実行環境がなかったため、
    ソースコードだけ残しておき実行環境ができたら試してみたいと思います。

    測定環境

    • CPU:Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz (4 CPUs), ~2.9GHz
    • メモリ:16GB
    • Visual Studio 2015

    対象データ

    • 計算を実行する行列:1000行1000列・1000行1100列
    • 行列内データ:0~99までの乱数
    • 計算内容:積

    測定対象

    • シングルスレッドで計算処理を実装
    • マルチスレッドで計算処理を実装
    • GPUを使用して計算処理を実装(ソースコードのみ)

    テストコード

    行列の積を求める計算の測定結果

    10回試行した結果の平均値が下記になっています。小数点第1位で四捨五入しています。

    ここをタップして表示Close
    計測項目 計測時間(s)
    シングルスレッドで計算処理を実装 33
    マルチスレッドで計算処理を実装 17

    計測結果についてはマルチスレッドを使用して計算させるとシングルスレッドで計算させた場合と比べておよそ半分の処理時間で計算を終了させることができました。
    処理として行っていることは非常にシンプルですが、マルチスレッドで行わせることで速度が非常に速くなることがわかります。
    また書き方も非常にシンプルであるため書きやすい点も素晴らしいです。

    行列の積を求める計算のまとめ

    シングルスレッドで計算処理を実装する場合は、行っていることが単純なLoopだからこそ非常に処理に時間がかかってしまうことがわかります。
    マルチスレッドで計算処理を実装する場合は、マルチスレッドを利用してLoop処理を行うことでシングルスレッドで行うよりも速度が速くなることが結果としてわかります。
    上記以外にGPUを使用して計算処理を記載することでさらに速度が向上する結果を載せたかったのですが、こちらは実行環境が整い次第試してみたいと思います。単純なLoop処理等での処理速度について解決を行う場合は、マルチスレッドを利用した記載方法に変更してみるのがいいでしょう。また、GPUを利用できる環境がある場合は、C#もGPUを利用して処理する方法が充実してきていますので利用して実装してみてはいかがでしょうか?

    今回は行列の積に関する速度比較というよりシングルスレッドを利用した場合とマルチスレッドを利用した場合の速度差の比較記事みたいになってしまいましたが、マルチスレッドを利用するだけで速度は非常に上がります。
    処理速度がネックになっている場合は、処理方法をマルチスレッドを利用したものやGPUを利用したものに変更してみてはいかがでしょうか?
    今回の記事が皆様のお役に立てば幸いです。