Goalist Developers Blog

Which Python Package Manager Should You Use?

f:id:vivek081166:20190612133948p:plain
source : https://realpython.com/

Nowadays Python is everywhere  - academics, data science, machine learning, enterprise application, web application, scripting... you name it python is everywhere. Whatever you do, python is there either to help you or give you a headache.

Let's say, you have learned python programming and ready to use to develop applications, surely, as that sounds great, you jump into coding python scripts and eventually start installing python packages. From there one follows a dangerous path into a developer’s nightmare.

f:id:vivek081166:20190612152119p:plain
source : https://xkcd.com/1987/

Package installation may lead to having incompatibility issues or make other applications unworkable. And you may discover that your code does not work on some machines while it just works flawlessly on your local machine. Why??? It's because of the Python environment.

To save yourself from incompatibility issues, a separate virtual python environment needs to be created for a project.

A virtual environment is a bunch of scripts and directories that can run python isolated. By using a virtual environment, each python project can have its own dependencies regardless of other projects and system python environments.

In this blog post, I would like to share with you my environment for working with data and doing machine learning. You most definitely do not need to copy anyone's setup but perhaps use the one that best fit for you.

f:id:vivek081166:20190612134946p:plain

Every programmer has different preferences when it comes to their programming environment vim versus emacs, tabs versus spaces, virtualenv versus anaconda.

To start with, we need to talk about pip. A python person {what :O} knows that pip is Python's package manager. It has come built into Python for quite a while now, so if you have Python, you likely have pip already.

pip installs packages like tensorflow and numpy, pandas and jupyter, and many more along with their dependencies. Many Python resources are delivered in some form of pip packages. Sometimes you may see a file called requirements.txt in someone's folder of Python scripts. Typically, that file outlines all of the pip packages that the project uses, so you can easily install everything needed by using

pip install -r requirements.txt

As part of this ecosystem, there's a whole world of version numbers and dependencies. You sometimes need to use different versions of a given library for different projects that you are working on.

So you need a way to organize groups of packages into different isolated environments. Otherwise, looking at the version errors you would want to bang your head against the wall.

There are two popular options currently for taking care of managing your different pip packages virtualenv and anaconda.

f:id:vivek081166:20190612145609p:plain

1) Virtualenv

Virtualenv is a package that allows you to create named virtual environments where you can install pip packages in an isolated manner. This tool is great if you want to have detailed control over which packages you install for each environment you create.

For example, you could create an environment for web development with one set of libraries, and a different environment for data science. This way, you won't need to have unrelated libraries interacting with each other, and it allows you to create environments dedicated to specific purposes.

# install
pip install virtualenv

# create environment
virtualenv venv 

# activate environment
source venv/bin/activate

f:id:vivek081166:20190612141916p:plain

2) Anaconda

Now, if you're primarily doing data science work, Anaconda is also a great option. Anaconda is created by Continuum Analytics, and it is a Python distribution that comes preinstalled with lots of useful Python libraries for data science. Anaconda is popular because it brings many of the tools used in data science and machine learning with just one install, so it's great for having a short and simple setup.

Like Virtualenv, Anaconda also uses the concept of creating environments so as to isolate different libraries and versions. Anaconda also introduces its own package manager called conda from where you can install libraries.

Additionally, Anaconda still has a useful interaction with pip that allows you to install any additional libraries which are not available in the Anaconda package manager.

Follow the instructions to download and install anaconda from here

# create environment
conda create --name test-env

# activate environment
conda activate test-env

# install additional packages
conda install tensorflow

To add more you have a nice UI to manage your projects and environment
f:id:vivek081166:20190614111628p:plain

So... which one to use, virtualenv or anaconda?

Well, it's nice to try out different libraries on both virtualenv and anaconda, but sometimes those two package managers don't necessarily play nicely with each other on one system.

In my case, I have opted to use both, but I manage the whole thing using a library called pyenv.

Conceptually, pyenv sits on top of both virtualenv and anaconda and it can be used to control not only which virtualenv environment or Anaconda environment is in use, but it also easily controls whether I'm running Python 2 or Python 3.

pyenv local 2.7.10
pyenv activate py27_tf12


pyenv local 3.5.2
pyenv activate py35_tf12

One final aspect of pyenv that it has an ability to set a default environment for a given directory. This causes that desired environment to be automatically activated when you enter a directory.

~/code $ cd myproject
(py35_tf12) ~/code/myproject $

I find this to be way easier than trying to remember which environment I want to use every time I work on a project.

So which package manager do you use?

It really comes down to your workflow and preferences. If you typically just use the core data science tools and are not concerned with having some extra libraries installed that you don't use, Anaconda can be a great choice since it leads to a simpler workflow for your needs and preferences.

But if you are someone who loves to customize your environment and make it exactly like how you want it, then perhaps something like virtualenv or even pyenv maybe more to your liking.

There's no one right way to manage Python libraries, and there's certainly more out there than the options that I just presented.

As different tools come and go, it's important to remember that everyone has different needs and preferences, so choose for yourself the best one that fits your needs.

That's it for this post, my name is Vivek Amilkanthwar. See you soon with one of such next time; until then, Happy Learning :)

Kerasくんとgeneratorの魔法

f:id:c-pattamada:20190530112343j:plain
魔法の書がありました

ゴーリストのチナパです!さてさて、今回は面白いのがありますよ〜

タイトルがちょっとハリーポッターっぽくて失礼します、機械学習の記事です。

機械学習というと、ビッグデータが思いつくと思います。 大量のデータで数日感学習させたり…

でも一つだけ問題があります

51ギガ?!

可愛そうなパソコンが諦めました。そんなRAM持ってませんって。

大量のデータで学習した時にこういうのもよくあります。私の場合には、数ギガバイトのcsvファイルの文字データをベクトル化しようとして、このようなことになりましたが、画像処理・音声分析の世界にはもっと頻繁でしょう。

ここではPythonの便利な機能「generator」を使うと良いです。

「generator」?なにそれ

range(10)

これもgeneratorです。何度も見たかと思います。

つまりgeneratorはループに使えるiterator系のobjectです

for x in range(10):  
    print(x)  #0~9がprintされます

上記のようにfor ループに使えますが、generator の本当の取り柄は全てのデータを同時にメモリー(RAM)にロードしていないことです。

ただし、このようにしますと:

my_gen = range(10)
for x in my_gen:
  print(x) #無事0~9がprintされます

# 二回めはうまく行かない
for x in my_gen:
  print(x)  #何もprintされない

これはメモリーに保存されてないからです。 ただし、データ量が多すぎてパソコンが泣いている私たちにはこの機能こそが素晴らしいです。

自分のgeneratorはどうやってつける?

Pythonにはメソッドの中にreturnを使う場合がよくありますが、yieldを使う場合もあります。メソッドにはyieldが使われてるとそのメソッドがgeneratorになります。

以下のメソッドが簡単なgeneratorです。nx0 からnx(n-1)までの数字を出します。

def my_generator(n):
  i = 0
  while i < n:
    i += 1
    yield n*(i-1)

for x in my_generator(5):
  print(x) # 0, 5, 10, 15, 20のようなものが順番にprintされます

でもこんなのはどうやって機械学習に活かせますか?

そうですね、本題に着きました。

keras のfit_generator()メソッドを利用します。このために、永遠までデータを出してくれるgeneratorメソッドが必要です。

つまり以下のようなものは◎です。

def gen():
  while True:
     yield 1 # ただしこんなデータ要りません!

すみません、しっかりします。前提として、データをcsvファイルであると想定しています。これはもちろん必須ではありませんが、pandasを便利に使えるし、文字データならcsvにまとめやすいので、そういうことにしましょう。

gist.github.com

ポイントとしては while Trueの中に、 pd.read_csv(skiprows=i, nrows=batch_size) があることです。 これはcsvデータの必要な部分(ここでは32行)をデータ化しようとします。 この例には、nullデータを外すための処理も入れてます、これは事前に掃除されたデータであれば無くしてもいい部分ですね。

yield data['input_x'], data['outputs_y']

もありますが、複数のインプットが必要な場合には

yield [data['input_x1'], data['input_x']], data['outputs_y']

見たいにまとめたらうまく行きます。

学習させましょう!

gist.github.com

kerasのfit_generatorメソッドで学習データとバリデーションデータのそれぞれのgeneratorを作っておきます。

ここの変わったところが

steps_per_epoch= train_size // batch_size

あたりですね。全てのデータがメモリーに入っていない上、generate_input_data() のメソッドが永遠まで続くようになってますので、1epochの大きさが分かるために、設定しないといけません。

お時間たっぷりかけると思いますが、無事大量のデータで学習できるようになってます!

まとめ

今回は

  • Pythonのgeneratorについて学びました
  • kerasで使えるgeneratorを作成しました
  • model.fit_generator() を利用しました。

ここまで読んでくれてありがとうございます。 では、また!

kerasのモデルをデプロイする手順

こんちは、ゴーリストのチナパです!

機械学習を触ったことがあるみなさんはkerasをご存知かと思います。初級から上級の方にもとても使いやすい、フレキシブルなライブラリです。学習の時に

model.save(file_name) #.h5ファイルで保存
model = keras.models.load_model(file_name) #ファイルを読み込み、モデルをロードする

のようにに楽に保存したり、保存されたファイルをロードしたりできます。

ただし、このまま本番環境に持って行こうとしたら非常に勿体無いです。なぜなら、この保存のやり方は学習中のモデルのためですので、本番環境にはいらない情報がたくさんあります。

これから、本番環境用のTenserflowのSavedModelをつくる方法を説明いたします。今回はtensorflow 1.13でやっています、tensorflow 2.0でまたちょっと変わりますので、気をつけてください。

f:id:c-pattamada:20190514144554j:plain
要注意:本番環境に写す前に、あなたのAIは人類の敗北を望んでいないことを確認しましょう: Photo by Matan Segev from Pexels

下準備

まずは、今回は学習ではないなく、本番のつもりですをkerasくんに教えましょう。(色々心の準備あるからでしょう)

import keras.backend as K
import tensorflow as tf
from keras.models import load_model

K.set_learning_phase(0) # 「もう学習していませんよ!」をkerasで書くとこう

これで、Dropoutレイヤーとレギュラライザーなどの、学習専用の物が無視されます。

すでにmodel.save()で保存されたモデルがありましたらそのファイルのパスを用意しまて、モデルをロードしましょう(ない方はしたの部分を見てください)

file_name = ... #あなたのモデルのパス
model = load_model(file_name)

そのようなファイルはすでに持っていない方は以下のようにモデルを作成してましたら、チュートリアルをやってみれます。
from keras.applications.resnet50 import ResNet50
model = ResNet50(weights='imagenet')

では、準備できてますね。

Signature作成

input_sig = 'my_input'
output_sig = 'predictions'
signature = predict_signature_def(inputs={input_sig: new_model.input}, outputs={output_sig: new_model.output})

簡単そうに見えますが、一体何をしているでしょう?

本番環境のSavedModelにはグラフのどのノードがinputとして使ったほうが良いのか、結果を見る時にはどこにみれば良いのかを定義するためのオブジェクトです。 今回は⓵predict_signature_def()を使っていますが、他に ⓶classification_signature_def()と⓷regression_signature_def()もあります。 違いは何なのかというと、inputのアウトプットの形に応じて使い分けられる物です。ここで定義したinput_sigとoutput_sigは後でまた使います。

(ちなみに、⓶はクラッシフィケーション専用のメソッドです、例えば、画像に対してのラベルを出したい場合などには、このメソッドで文字列のラベルまで出してくれたり便利な部分があります。⓷は同じようにregression系の機械学習に便利です。⓵の方は割と応用時なので、こちらに使います)。

モデル保存

まずは、export_path、つまり保存先のディレクトリ名を定義します。これはすでに存在しましたらエラーが発生するので、最後のフォルダーがまだ存在しないようにします(ここでは”1”となってます)。

export_path = /path/to/model/1/  #例のパスです、最後のフォルダがまだ存在しないフォルダー名(例えば、モデルのバージョン番号)を使ってください
signature_name = 'predict_output' # こちらもまた後で使います。
with K.get_session() as sess:
    builder = tf.saved_model.builder.SavedModelBuilder(export_path)
    builder.add_meta_graph_and_variables(
        sess, [tf.saved_model.tag_constants.SERVING],
        signature_def_map={signature_name: signature},
        main_op=tf.tables_initializer())
    builder.save()

そして、tensorflowのSavedModelBuilderを使って保存します。 本番環境のつもりなのでtf.saved_model.tag_constants.SERVINGのフラグを設定します。

先ほど作成したsignatureがsignature_def_map={'predict_output': signature}このように設定します。こちらの'predict_output’の文字列は自由です。

実行しましたら

f:id:c-pattamada:20190514143120p:plain
SavedModelの保存形式
のように保存されるはずです。

イエイ!これで保存できました!

グーグルのAI platformを使いたい場合にもこのような保存形式であれば大丈夫です。

モデルをロードする

さて、モデルを保存しましたが、この形式をどうやって使えるでしょうか? 自作のFlaskサーバーで利用したい場合には便利かも知れません。

いかのようにロードできますが、今までのpredictなどの昨日がうまくいきません。

with tf.Session(graph=tf.Graph()) as sess:
    model_x = tf.saved_model.loader.load(sess, [tag_constants.SERVING], export_path)

そこで、上記に定義したsignature_defを利用します。 まとめて、

my_testing_data = ... #ここでモデルのインプットデータを用意します

with tf.Session(graph=tf.Graph()) as sess:
    model_x = tf.saved_model.loader.load(sess, [tag_constants.SERVING], export_path)
    sig_def = model_x.signature_def[signature_name]
    in_name = sig_def.inputs[input_sig].name
    out_name = sig_def.outputs[output_sig].name
    # print(in_name, out_name) #きになる方はここでプリントしたら、レイヤー名が出力されます。
    result = sess.run(out_name,
                 feed_dict={in_name: my_testing_data})
    

こうして、Signature defを利用して、モデルの中のレイヤー名に依存せずにモデルの利用ができます。これは本番環境にモデル置き換えなどがある場合にはとても便利です。

まとめ

今回はkerasのモデルを本番環境のために準備するステップを説明してみました。モデルのsignatureを作成して、保存し、またロードして実行するまでやりました。ただし、tensorflow 2.0にはまたちょっと変わっていきますのでご注意ください。

本番環境を用意しましたら、cliで実行するか、flaskのサーバーに置くか、他の色々な選択肢もありますが今回はここまでにします!

AutoML:機械学習の次の波

f:id:vivek081166:20190424142833j:plain
Source: www.pexels.com

AIと機械学習は、依然として初心者が参入しにくい専門性の分野です。 豊富な専門知識と事業リソースをもった企業は少ししかありません。~Fei-Fei Li

Mercari は日本で人気のあるショッピングアプリで、画像の分類にAutoML (Automated Machine Learing) Vision(GoogleのAutoMLソリューション)を使用しています。Mercari によると、「写真をアップロードすると、12の主要ブランドのブランド名を提案する独自のMLモデルを開発しています」

TensorFlowでトレーニングされた独自のモデルは75%の精度を達成しましたが、50,000のトレーニング画像を含むアドバンストモードのAutoML Visionは91.3%の精度を達成しました。これは15%もの大幅な向上です。そのような驚くべき結果により、MercariはAutoMLをシステムに統合しました。

これは、複雑なシナリオに対処するための機械学習モデルを進化させることによってもたらされた恩恵のほんの一例です。AutoML(Automated Machine Learning)が今日のML (Machine Learning)ベースのソリューションを根本的に変えたのです。

自動機械学習:AutoML

近年、機械学習はさまざまな分野で大きな進歩をもたらしてきました。金融サービス、医療、小売、交通などの分野では、何らかの形で機械学習システムが使用されており、その結果は有望視されています。

今日の機械学習は、研究に限定されているのではなく、エンタープライズドメインに進出しています。ただし、多くの企業は豊富なデータサイエンティストチームに投資できるだけの事業資源を持っていないために、人に依存した従来のMLプロセスでは解決できない問題が多くありました。Auto MLは、そのような状況への答えになるかもしれません。

自動機械学習(AutoML)は、実世界の問題に機械学習を適用するというend-to-end のプロセスを自動化する過程です。AutoMLは、機械学習の分野で高度な専門知識を持たない人でも、それらを利用できるようにしたのです。

機械学習モデルは、次の4つのプロセスで構成されています。

f:id:vivek081166:20190424143407p:plain

データの取り込みから前処理、最適化、そして結果の予測まで、すべてのステップを人間が管理し、実行します。 AutoMLは基本的に2つの主要な側面に焦点を合わせています 。それはデータ収集/収集と予測すす。これらの間で行われる前処理と最適化のステップは、簡単に自動化することができます。

AutoMLの必要性

機械学習システムの需要は過去数年間で急上昇しました。これは、今日の幅広いアプリケーションでのML の成功によるものです。ただ、機械学習によって特定のビジネスが促進される可能性があることが明確だとしても、多くの企業がMLモデルの展開に苦労しています。

まずは、データサイエンティストのチームを立ち上げる必要があります。第二に、チームを抱えていても、 どの問題にどのモデルが最適であるかを決めることはしばしば知識より多くの経験を必要とします。

AutoMLは、モデルのパフォーマンスを犠牲にすることなく、最小限の労力でMLパイプラインの最大ステップ数を自動化するのに役立ちます。

利点

AutoMLの利点を要約すると、次の3つになります。

  • 作業を自動化することで生産性を高めます。そうするとモデルではなく問題にもっと集中することができます。

  • MLパイプラインを自動化することで、手動時に発生する人為的なエラーを回避するのにも役立ちます。

  • 結局のところ、AutoMLは、MLの力を誰もが利用できるようにすることによって、機械学習の民主化に向けた一歩です。

AutoMLフレームワーク

AutoMLは、機械学習パイプラインの一部または全部を自動化できます。そこで、まずはフレームワークのいくつかを見てみましょう。これは完全なリストではありませんが、幅広い分野で使用されているフレームワークについて紹介しようと思います。

1. MLBox

f:id:vivek081166:20190424143752p:plain
https://mlbox.readthedocs.io/en/latest/

MLBoxは強力な自動機械学習Pythonライブラリです。 公式文書によると、このライブラリは以下の機能を提供します。

  • 高速読み取りおよび分散データの前処理/クリーニング/フォーマット

  • 非常に正確な特徴量選択、リーク検出、そして正確なハイパーパラメータ最適化

  • 分類と回帰のための最先端の予測モデル(ディープラーニング、スタッキング、LightGBMなど)

  • モデル解釈による予測

パイプライン

MLBoxのメインパッケージには、次の作業を自動化するための3つのサブパッケージが含まれています。 * 処理:データの読み取りと前処理 * 最適化:モデルのテストと交差検定 * 予測:予測をする

インストール

現在、MLBoxはLinuxとのみ互換性がありますが、WindowsとMacOSのサポートは間もなく追加される予定です。

#gcc
sudo apt-get install build-essential

#cmake
pip install cmake

pip install mlbox

デモ

ハウスプライス回帰問題で "MLBox"自動MLパッケージを実行する。

gist.github.com

2. Auto-Sklearn

Auto-Sklearnは、Scikit-learnの上に構築された自動機械学習パッケージです。 Auto-Sklearnを使用すれば、アルゴリズムの選択やハイパーパラメータの調整は不要です。 Auto-Sklearnには、ワンホットエンコーディング、PCAなどのフィーチャーエンジニアリング手法が含まれています。

Auto-Sklearnは、中小規模のデータセットではうまく機能しますが、大規模なデータセットに適用するとパフォーマンスが低下します。

インストール

Auto-Sklearnは現在Linuxマシンでのみ動作します。

#dependencies
curl https://raw.githubusercontent.com/automl/auto-sklearn/master/requirements.txt | xargs -n 1 -L 1 pip install

#auto-sklearn
pip install auto-sklearn

デモ

次の例は、Auto-Sklearnを使用して近似のデータを元に予測し、単純な回帰モデルを作る方法です。

gist.github.com

3. Tree-Based Pipeline Optimization Tool (TPOT)

f:id:vivek081166:20190424144939p:plain
https://epistasislab.github.io/tpot/

TPOTは、ジェネティックプログラミングを使用して機械学習パイプラインを最適化するPython自動機械学習ツールです。

TPOTはScikit-learnフレームワークを拡張しますが、独自のリグレッサおよび分類子メソッドを使用します。

f:id:vivek081166:20190424144610p:plain
TPOTによって自動化された機械学習プロセスの一部

インストール

pip install tpot

詳しい手順については、公式文書のTPOTインストール手順を参照してください。

デモ

TPOTでMNIST数字を分類する

gist.github.com

4. H2O

f:id:vivek081166:20190424145540p:plain
http://docs.h2o.ai/
H2Oは、RとPythonの両方をサポートする、H20.aiのオープンソース分散型インメモリ機械学習プラットフォームです。

H2Oは、フィーチャエンジニアリング、モデル検証、モデル調整、モデル選択、モデル展開など、最も困難なデータ科学および機械学習ワークフローの一部を自動化します。

インストール

H2Oをダウンロードしてインストールするには、以下のリンクを利用してください。

h2o-release.s3.amazonaws.com

デモ

H2OAutoML クラスをPythonで基本的な使い方は下記の通りです。

gist.github.com

5. AutoKeras

f:id:vivek081166:20190424145528p:plain
https://autokeras.com/

Auto-Kerasは、機械学習自動化するためにDATA Labが作ったオープンソースライブラリです。KerasディープラーニングフレームワークをベースにしたAuto-Kerasは、ディープラーニングモデル用のアーキテクチャとハイパーパラメータを自動的に検索する機能を、私たちに提供してくれます。

Auto-KearsのAPIはScikit-Learn APIと似ているのでとても使いやすいです。現在のバージョンでは、ディープラーニングプロセス中にハイパーパラメータを自動的に検索する機能が提供されています。

Auto-Kerasは、自動化されたNeural Architecture Search(NAS)アルゴリズムを使用してMLプロセスを簡素化します。

インストール

インストールもシンプルです。

デモ

下記はMNISTデータセットを利用したAuto-Kerasライブラリのデモです。

gist.github.com

6. Cloud AutoML

Cloud AutoML は機械学習プロダクトのスイートです。AutoML を利用すると、機械学習の専門知識があまりない開発者でも Google の最先端の転移学習とニューラル アーキテクチャ検索技術を利用して、ビジネスニーズに合った高品質のモデルをトレーニングできます。

Cloud AutoMLは、自身のデータに基づいてモデルをトレーニング、評価、改善、および展開するためのシンプルなグラフィカルユーザーインターフェイス(GUI)を提供します。現在、このスイートは以下のAutoMLソリューションを提供しています。

f:id:vivek081166:20190424150050p:plain

GoogleのAutoMLの欠点はオープンソースではないということです。 AutoML Visionの場合、モデルをトレーニングするのにかかる時間と、予測のためにAutoML Visionに送信する画像の数によってコストが異なります。詳しくはこちらをご覧ください。

cloud.google.com

7. TransmogrifAI

TransmogrifAIは、Salesforceのオープンソースの自動機械学習ライブラリです。

Einsteinと呼ばれる同社の主力MLプラットフォームもTransmogrifAIによって供給されています。 これは、Apache Spark上で動作するScalaで書かれた構造化データ用のend to endのAutoMLライブラリです。

インストール

# JAVA 1.8 インストール

# Spark 2.3.x 取得
git clone https://github.com/salesforce/TransmogrifAI.git

cd TransmogrifAI && ./gradlew compileTestScala installDist

インストール手順については、資料をお読みください。

デモ

TransmogrifAIによるタイタニック生存者の予測してみましょう。詳しくはこちらをご覧ください。

gist.github.com

AutoMLの未来

AutoMLの基本的な目的は、パイプラインの作成やハイパーパラメータの調整などの反復的な作業を自動化して、自分が解決すべきビジネス上の課題により多くの時間を費やすことができるようにすることです。

AutoMLが成功するかどうかは、多くの人に使われることと機械学習分が進歩することにかかっています。ただ、AutoMLが将来の機械学習の大部分を占めることは間違いないでしょう。

参照

  1. Efficient and Robust Automated Machine Learning
  2. Benchmarking Automatic Machine Learning Frameworks

決定境界(Decision Boundary)とニューラルネットの紹介

ゴーリストのチナパです!この度は技術的な記事ではなく、「AIに任せましょう」などを聞くときに、実際に何が起きているのかの直感を作るための記事です。(プログラミングなしです)

データでモデルを学習しそして分類の判断を行う時に、何かの規則を作ってから判断しているのが事実です。複雑な問題であるほど人間の頭で想像しにくくなるかも知れませんが、直感を作ることはできます。

f:id:c-pattamada:20190413162628j:plain
りんごが... 左!

Public Domain Pictures · Photography

簡単な問題でやってみよう

この度はhttps://playground.tensorflow.org, という実験できる場所から始めましょう。ここでは、ノープログラミングでニューラルネットと遊べます。

f:id:c-pattamada:20190413162957p:plain

初めての方だと、色々がありすぎてびっくりするかも知れませんが、一歩ずつ進めて行きます!

スタート地点はこちらです。左側の「Data」のところで、写真の通り、一番簡単なデータを選びましょう。すると、右側の「Output」にそれが反映されます。(一旦、左のメニューにNoiseも0%だと確認しましょう)。

f:id:c-pattamada:20190413163035p:plain

これは二次元のグラフですのでちゃんと二つの軸があります、x軸とy軸と言われてる時もありますが、こちらで横軸がX1と縦軸がX2です。この二つを私たちが測ってます(この場合はランダムで作られてるけど、現実の状況であれば測っていたりしている)。点の種類は二つあります、オレンジと青、そしてこの例ではご覧の通り綺麗な二つの固まりになってます。

計算機を使うまでもなく、オレンジの点がX1=-2, X2=-2あたりが平均みたいだし、青の点がX1=2, X2=2の周りに集中されてます。 さて、こんな簡単の問題には機械学習がどう解決するのかも見てみましょう。上のあたりのPlayボタンを押してみてください。

押してから、すぐグラフが綺麗なオレンジと青に分けれれていきます。一瞬にでもこのパターンが見抜かれてます。ま、簡単だしな。

f:id:c-pattamada:20190413163126p:plain

グラフに左がわがオレンジになり、右側が青になりました。そして、斜め白い線がオレンジ組と青くみの間を通ってます。

「この二つの組みを分けてください」と子供に聞いたら、似たような線も書いたかも知れません。この場合、この白い一直線が「決定境界」と言います。 白い線の左はオレンジ、右が青。つまり、この線によって判断されてます。

ちょっとずるいことをしてみましょう。

こんな簡単な問題にも、情報が足りなかったら、良い判断が一気にとりにくくなります。

f:id:c-pattamada:20190413163215p:plain

「Features」の下にあるX1の変数あたりをクリックしたら、色が薄めます。これで、今回はX1の情報は機械学習のモデルに渡さないことになってます。つまり、縦軸であるX2の情報だけで、点がオレンジなのか、青なのかを判断しないといけない状況です。またPlayをおし、結果をみましょう。

f:id:c-pattamada:20190413163254p:plain

今度はグラフが横に分けられてます。過ちもあるかも知れません(私の場合、一つの青点がオレンジ背景の部分にあります。なぜなら、縦軸のX2の情報しか得てないため、その情報だけで判断されてるからです。だら、横線になってます。

つまり、決定境界が使ってる変数(Feature、情報)にとても影響されます。

ま、今のところはわかりやすい、ほとんど一直線の例しかみてないので、ハードルを高くしましょう。

渦巻(ナルト?)の出番

X1をもう一回クリックし、モデルにこの情報を与えましょう。ただし、Dataの部分で右下にある渦巻みたいな物を選びましょう。そして、Noiseも入れましょう(私は30%にしましたが、お好きに選んでください)。

f:id:c-pattamada:20190413163420p:plain

Playを押したら….

f:id:c-pattamada:20190413163448p:plain

全然分からない、と言わんばかりのうすい背景と白い横線の決定境界… このうすい色は「自信度が低い」という意味です。学生に聞いて 「なんか…上の辺にオレンジがもう少しあるから…こっちがオレンジになるかな…?」みたいな答えです。

ま…一直線を書いてこのデータを分類するのが不可能だからです。渦巻だから。 では、どうしたら一直線ではない決定境界を作ることができます?

方法があります。 「Feature」の項目で一直線ではないデータで一直線的ではないデータを含めること。

Featureの項目で一番したにあるsin(X1)とsin(X2)も選択して、同じネットワークをplayしましょう。

f:id:c-pattamada:20190413163837p:plain

一気に、決定境界がとんでもないことになってます。

f:id:c-pattamada:20190413163858p:plain

しかも、割とあってるし。一体どうやってここまで分かったでしょう?「渦巻」と分かったのか?

ニューラルネットの中身の分析

ここで、真ん中にある「hidden layer」の部分を見てみましょう。

f:id:c-pattamada:20190413164931p:plain

このネットワークには2つにhidden layerがあります。一つ目には4つの「ニューロン」(神経)があって、2つめは2つの「ニューロン」があります。それぞれのものが何を「気づいている」 のかを見るために、マウスを上にホバーしましたら、右のグラフでそのニューロンのアウトプットが観れます。

みなさんとは少し違うかも知れませんが、私の場合最初のhidden layerでは、四つの「気づき」があるみたいです。

f:id:c-pattamada:20190413164827p:plain

1番と2番がとても似ています。これは、sinグラフみたいな波があるようです。この上にはオレンジ、下には青。ですが、これだけでは渦巻にはなりません。

3番目の「気づき」は上から下の階層一番上にはオレンジ、次は青、次はオレンジ、一番したは青。この中には、青が左肩よりだとオレンジは右肩よりだとも気づいているみたです、面白い。 どうやってこれができたのかが気になりましたら、このニューロンに入っていく線をホバーしてみると”weight is 〇〇”みたいのものがあります。

f:id:c-pattamada:20190413164950p:plain
ホバーしてからの写真をまとめた

ここでは、(-0.33 x X1) + (0.3 x X2) + (sin(X1) x 1.6) + (sin(X2) x 2.7)のようにこのグラフが作られてますが、数学はそこまでとしましょう。

4番目もX2の逆に似ていて、とりあえず上がオレンジ、下が青と気づいています。

この4つの気づいきを更に組み合わせて、2番のhidden layer にアウトプットを得て、またそのアウトプットを組み合わせて、結果の「渦巻」のようなデータを割と精度高く分類することができる決定境界を描くことができました。

まとめ

ここでX1とX2しか使わなかったため、綺麗な二次元グラフで写すこともできましたが、ディープラーニングのより複雑な分類問題も、結果的に似ているようなことをやっています。フィーチャ数が大きければ大きいほど描きにくい決定境界になりますし、それでこそ便利な道具になっていくこともあります。

例えば...

f:id:c-pattamada:20190413165056p:plain
結構渦巻っぽくない?

では、他の種類のデータも、遊んで観てください!hidden layer数を増やして、減らして影響を見ることもできますので、分類で使うdeep learningがどのような決定境界を作ることができるのかの直感がこれでできましたら幸いです。

Deep Learning Using Raw Audio Files

// Feed raw audio files directly into the deep neural network without any feature extraction. //

If you have observed, conventional audio and speech analysis systems are typically built using a pipeline structure, where the first step is to extract various low dimensional hand-crafted acoustic features (e.g., MFCC, pitch, RMSE, Chroma, and whatnot).

Although hand-crafted acoustic features are typically well designed, is still not possible to retain all useful information due to the human knowledge bias and the high compression ratio. And of course, the feature engineering you will have to perform will depend on the type of audio problem that you are working on.

But, how about learning directly from raw waveforms (i.e., raw audio files are directly fed into the deep neural network)?

In this post, let's take learnings from this paper and try to apply it to the following Kaggle dataset.

www.kaggle.com

Go ahead and download the Heatbeat Sounds dataset. Here is how one of the sample audio files from the dataset sounds like

clyp.it

f:id:vivek081166:20190410152348p:plain

The downloaded dataset will have a label either "normal", "unlabelled", or one of the various categories of abnormal heartbeats. 

Our objective here is to solve the heartbeat classification problem by directly feeding raw audio files to a deep neural network without doing any hand-crafted feature extraction.

Prepare Data

Let's prepare the data to make it easily accessible to the model. 

extract_class_id(): Audio file names have its label in it, so let's separate all the files based on its name and give it a class id. For this experiment let's consider "unlabelled" as a separate class. So as shown above, in total, we'll have 5 classes. 

convert_data(): We'll normalize the raw audio data and also make all audio files of equal length by cutting them into 10s if the file is shorter than 10s, pad it with zeros. For each audio file, finally put the class id, sampling rate, and audio data together and dump it into a .pkl file and while doing this make sure to have a proper division of train and test dataset.

gist.github.com

Create and compile the model

f:id:vivek081166:20190410152941p:plain

As written in the research paper, this architecture takes input time-series waveforms, represented as a long 1D vector, instead of hand-tuned features or specially designed spectrograms. 

There are many models with different complexities explained in the paper. For our experiment, we will use the m5 model. 

m5 has 4 convolutional layers followed by Batch Normalization and Pooling. a callback keras.callback is also assigned to the model to reduce the learning rate if the accuracy does not increase over 10 epochs.

gist.github.com

Start training and see the results

Let's start training our model and see how it performs on the heartbeat sound dataset.

As per the above code, the model will be trained over 400 epochs, however, the loss gradient flattened out at 42 epochs for me, and these were the results. How did yours do?

Epoch 42/400
128/832 [===>..........................] - ETA: 14s - loss: 0.0995 - acc: 0.9766
256/832 [========>.....................] - ETA: 11s - loss: 0.0915 - acc: 0.9844
384/832 [============>.................] - ETA: 9s - loss: 0.0896 - acc: 0.9844 
512/832 [=================>............] - ETA: 6s - loss: 0.0911 - acc: 0.9824
640/832 [======================>.......] - ETA: 4s - loss: 0.0899 - acc: 0.9844
768/832 [==========================>...] - ETA: 1s - loss: 0.0910 - acc: 0.9844
832/832 [==============================] - 18s 22ms/step - loss: 0.0908 - acc: 0.9844 - val_loss: 0.3131 - val_acc: 0.9200

Congratulations! You’ve saved a lot of time and effort extracting features from audio files. Moreover, by directly feeding the raw audio files the model is doing pretty well.

With this, we learned how to feed raw audio files to a deep neural network. Now you can take this knowledge and apply to the audio problem that you want to solve. You just need to collect audio data normalize it and feed it to your model.

The above code is available at following GitHub repository

github.com

That's it for this post, my name is Vivek Amilkanthwar. See you soon with one of such next time; until then, Happy Learning :)

References:

1) https://arxiv.org/pdf/1610.00087.pdf
2) https://github.com/philipperemy/very-deep-convnets-raw-waveforms
3) https://openreview.net/pdf?id=S1Ow_e-Rb

Teachable Desktop Automation

// Teach your computer to recognize gestures and trigger a set of actions to perform after a certain gesture is recognized.//

Hello World! I'm very excited to share with you my recent experiment wherein I tried to teach my computer certain gestures and whenever those gestures are recognized certain actions will be performed.

In this blog, I'll explain all you need to do to achieve the following

IF: I wave to my webcam
THEN: move the mouse pointer a little to its right

I have used power for Node js to achieve this. The idea is to create a native desktop app which will have access to the operating system to perform certain actions like a mouse click or a keyboard button press and also on the same native desktop app we'll try to train our model and draw inferences locally.

To make it work, I thought of using tensorflow.js and robotjs in an Electron App created using Angular.

f:id:vivek081166:20190329175638p:plain

So, are you ready? let's get started…

Generate the Angular App

Let's start by creating a new Angular project from scratch using the angular-cli

npm install -g @angular/cli

ng new teachable-desktop-automation

cd teachable-desktop-automation

Install Electron

Add Electron and also add its type definitions to the project as dev-dependency

npm install electron --save-dev

npm install @types/electron --save-dev

Configuring the Electron App

Create a new directory inside of the projects root directory and name it as "electron". We will use this folder to place all electron related files.

Afterward, make a new file and call it "main.ts" inside of the "electron" folder. This file will be the main starting point of our electron application.

Finally, create a new "tsconfig.json" file inside of the directory. We need this file to compile the TypeScript file into JavaScript one.

Use the following as the content of "tsconfig.json" file.

gist.github.com

Now it's time to fill the "main.ts" with some code to fire up our electron app.

gist.github.com

Visit electronjs for details

Make a custom build command

Create a custom build command for compiling main.ts & starting electron. To do this, update "package.json" in your project as shown below

{
  "name": "teachable-desktop-automation",
  "version": "0.0.0",
  "main": "electron/dist/main.js", // <-- this was added
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "electron": "ng build --base-href ./ && tsc --p electron && electron ."  // <-- this was added
  },
  // ...omitted
}

We can now start our app using npm:

npm run electron

f:id:vivek081166:20190329180447p:plain

There we go… our native desktop app is up and running! However, it is not doing anything yet.

Let's make it work and also add some intelligence to it…

Add Robotjs to the project

In order to simulate a mouse click or a keyboard button press, we will need robotjs in our project.
I installed robotjs with the following command

npm install robotjs

and then tried to use in the project by referring to some examples on their official documentation. However, I struggled a lot to make robotjs work on the electron app. Finally here is a workaround that I came up with

Add ngx-electron to the project

npm install ngx-electron

And then inject its service to the component where you want to use the robot and use remote.require() to capture the robot package.

import { Component } from '@angular/core';
import { ElectronService } from 'ngx-electron';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(private electronService: ElectronService) {
   
   this.robot = this.electronService.remote.require('robotjs');
// move mouse pointer to right
   const mousePosition = this.robot.getMousePos();
   this.robot.moveMouse(mousePosition.x + 5, mousePosition.y);
}
}
Add Tensorflow.js to the project

We'll be creating a KNN classifier that can be trained live in our electron app (native desktop app) with images from the webcam.

npm install @tensorflow/tfjs

npm install @tensorflow-models/knn-classifier

npm install @tensorflow-models/mobilenet

A quick reference for KNN Classifier and MobileNet package

Here is a quick reference to the methods that we'll be using in our app. You can always refer tfjs-models for all the details on implementation.

KNN Classifier

  • knnClassifier.create() : Returns a KNNImageClassifier.
  • .addExample(example, classIndex) : Adds an example to the specific class training set.
  • .predictClass(image) : Runs the prediction on the image, and returns an object with a top class index and confidence score.

MobileNet

  • .load() : Loads and returns a model object.
  • .infer(image, endpoint) : Get an intermediate activation or logit as Tensorflow.js tensors. Takes an image and the optional endpoint to predict through.

Finally make it work

For this blog post, I'll keep aside the cosmetics part (CSS I mean) apart and concentrate only on the core functionality

Using some boilerplate code from Teachable Machine and injecting robotjs into app component here is how it looks

gist.github.com

and now when running the command npm run electron you see me (kidding)

f:id:vivek081166:20190329181118p:plain

Let's Test it

I'll train the image classifier on me waving to the webcam (Class 2) and also with me doing nothing (Class 1).

Following are the events are associated with these two classes

Class 1: Do nothing
Class 2: Move mouse pointer slightly to the right

youtu.be

With this, your computer can learn your gestures and can perform a whole lot of different things because you have direct access to your operating system.

The source code of this project can be found at below URL…

github.com

I have shared my simple experiment with you. Now it's your turn try to build something with it and consider sharing that with me as well :D

I have just scratched the surface, any enhancements, improvements to the project are welcome though GitHub pull requests.

Well, that's it for this post… Thank you for reading until the end. My name is Vivek Amilkanthawar, see you soon with another one.