ページ

2016年6月29日水曜日

Amazonプライム・ビデオで個人的に面白かった映画や番組


数ヶ月前にAmazonプライムの無料体験を経て、
晴れて(?)プライム会員になって数ヶ月。



最近あまり外に出かける事がなく、家でプライムビデオを黙々と見てたので、
個人的に見て面白かった映画や番組を書いてみたいと思います。


ハウンター

ハウンター(字幕版)()をオンラインで見る - Amazonビデオ

結構序盤の方で主人公が何故家から出られないのが分かってしまいましたが、
個人的には伏線がちょこちょこと序盤にあって、最後に向けて解決していくのが
面白かったです。
ただ主人公が現代的な感じなので、時代背景と合ってない感じもしましたが・・



ローカル路線バス乗り継ぎの旅

ローカル路線バス乗り継ぎの旅【テレビ東京オンデマンド】のシーズン1 エピソードを観る -Amazonビデオ

何も考えずに気楽に見れるんで見てましたが、
蛭子さんのたまにの毒舌っぷりが面白い。



ジュラシック・ワールド(吹替版)

ジュラシック・ワールド (吹替版)()をオンラインで見る - Amazonビデオ

これはジュラシックパーク好きだった自分としては素直に面白かったです。
吹替版反対〜な人もいるかと思いますが、
個人的にはアクションが多そうな映画は吹替版で見ます。



ジヌよさらば 〜かむろば村へ〜 

ジヌよさらば ~かむろば村へ~()をオンラインで見る - Amazonビデオ

片桐はいりさんの失神シーンには爆笑しました。
こちらも何も考えず気楽に見て笑ってましたw



HuluやNetflixに比べると作品数は少ないですが、探せば掘り出し物があるので、
これからもたまにこんな感じで紹介していけたらと思います。


2016年6月25日土曜日

機械学習のフレームワークTensorflowを試す 7 - MNIST事始め -


今回からは、機械学習のHello Worldという事らしい、MNISTをやっていきたいと思います
以前の記事でデモを実行してはいますが、 今度は実際に学びながらやっていきます。
MNIST For ML Beginners」を元に進めて行こうと思います。

MNISTでどんな機械学習をさせるか

以前も書きましたが、MNISTは手書きの数字の画像のデータセットです。
↑は0〜9まで色んなタッチで書かれてある。というのは人間からしたら簡単に予想がつきます。
ですがコンピュータからすれば数字が書かれてあるなんて分からないので
学習してもらって、何の数字が書いてあるか解析してもらおうと思います

MNISTデータ

使用するMNISTデータはYann LeCun's websiteで提供されているので、
そちらのデータを使用します。
一度ダウンロードしてデータセットがどんなものか見てみたいと思います。
提供元のページにいき、↓の4つをダウンロードし解凍します。

それぞれ
  • 手書き数字の画像データ
  • 手書き数字に対応するラベルデータ
  • テスト用の画像データ
  • テスト用の画像に対応するラベルデータ
となっています。

データ構造
  • train-images-idx3-ubyte.gz
    ファイルには28×28ピクセルの画像が60000枚分書き込まれてます。
    ・ファイルフォーマット
    [offset] [type]          [value]          [description]
    0000     32 bit integer  0x00000803(2051) magic number
    0004     32 bit integer  60000            number of images
    0008     32 bit integer  28               number of rows
    0012     32 bit integer  28               number of columns
    0016     unsigned byte   ??               pixel
    0017     unsigned byte   ??               pixel
    ........
    xxxx     unsigned byte   ??               pixel
    
    ※提供元ページから抜粋
  • train-labels-idx1-ubyte.gz
    ファイルには画像に対応するラベルが60000個書き込まれてます。
    ・ファイルフォーマット
    [offset] [type]          [value]          [description]
    0000     32 bit integer  0x00000801(2049) magic number (MSB first)
    0004     32 bit integer  60000            number of items
    0008     unsigned byte   ??               label
    0009     unsigned byte   ??               label
    ........
    xxxx     unsigned byte   ??               label
    
    ※提供元ページから抜粋

MNISTデータ読み込み

最終的には、画像データを読み込んでテンソルに格納します。
テンソルは[60000, 784(28*28)]の2次元配列で格納します。
今回は、ファイル読み込む所までやってみます。
import numpy as np

data = open("train-images.idx3-ubyte","rb")
dt = np.dtype("int32").newbyteorder('>')
# 1.
info = np.frombuffer(data.read(16), dtype=dt)
print(info) # => [ 2051 60000    28    28]

size = info[1] * info[2] * info[3]
dt = np.dtype("int8").newbyteorder('>')
# 2.
imageBuff = np.frombuffer(data.read(size), dtype=dt)
print(len(imageBuff)) # => 47040000
1.では先頭から16バイト分読み込んで、画像の情報を出力しています
また、2.では読み込んだ画像データのサイズを出力しています。

2016年6月23日木曜日

GASのローカル開発用CLIツール(node-google-apps-script)を試す


以前GoogleAnalyticsの内容をSlackへGASで通知するBotを作成しましたが、
全てWeb上のスクリプトエディッタで作成していましたが
今回試すnode-google-apps-scriptを使う事でローカルで開発できるとの事。

という事で早速使ってみたいと思います。

インストール


まずはインストール。※ npmはインストール済みの前提です。
$ npm install -g node-google-apps-script

正常にインストールされるとgappsコマンドが使えるようになります。
$ gapps --version
1.1.5

認証トークンの取得


Google Developer Consoleで「DriveAPI」> 「有効にする」を選択し
DriveAPIを有効にします。

「認証情報」> 「認証情報を作成」を選択。

「OAuthクライアントID」を選択します。

「その他」にチェックし作成します。

作成したら認証情報のjsonファイルをダウンロードします。


初期設定


ダウンロードしたjsonファイルを指定して初期設定を行います。
$ gapps auth {jsonファイルのパス}
Please visit the following url in your browser (you'll only have to do this once): https://XXXXXX......

上のURLを開いて下さいとメッセージが出るのでブラウザで開いて設定完了です。
成功すると以下メッセージが表示されます。


新規作成 & アップロード


GoogleDrive上で新規にGoogle Apps Scriptを作成します。

作成したファイルを開き「ファイル」> 「プロジェクトのプロパティ」を選択しプロジェクトキーをコピーします。

以下コマンドでローカルに環境を構築します。
$ gapps init {コピーしたプロジェクトキー}
構築されるとgapps.config.jsonに設定情報が、src/**.js
ソースファイルとなっています。

アップロードの際は以下コマンドを実行します。
$ gapps upload
Pushing back up to Google Drive...
The latest files were successfully uploaded to your Apps Script project.
‼️もしアップロードの際に以下エラーが出た場合
Pushing back up to Google Drive...

/usr/local/lib/node_modules/node-google-apps-script/lib/util.js:18
        file = path.parse(filename);
                    ^
TypeError: Object #<Object> has no method 'parse'
    at /usr/local/lib/node_modules/node-google-apps-script/lib/util.js:18:21
    at /usr/local/lib/node_modules/node-google-apps-script/node_modules/node-dir/lib/readfiles.js:110:34
    at fs.js:271:14
    at Object.oncomplete (fs.js:107:15)
Node.jsのバージョンが古い可能性があります。
Node.jsを最新いアップデートして再度実行すると上手くいくかと思います。

2016年6月18日土曜日

機械学習のフレームワークTensorflowを試す 6 - 変数の可視化とスコープ付け(TensorBoard) -


前回やった可視化をさらに進めてみたいと思います。
変数を可視化

前回はtf.constantで[3,4,5]のテンソル値を宣言していたのですが、
今回は可視化する為にtf.Variableメソッドを使って宣言します。
修正したコードがこちら
# coding: UTF-8
import tensorflow as tf

with tf.Graph().as_default():
    array_var = tf.Variable(tf.zeros([3]), name="array")
    square = tf.square(array_var)
    reduce = tf.reduce_mean(square)

    init = tf.initialize_all_variables()
    sess = tf.Session()
    sess.run(init)

    tf.merge_all_summaries()
    summary_writer = tf.train.SummaryWriter('report', sess.graph)

    ret = sess.run(reduce, feed_dict={array_var: [3.0, 4.0, 5.0]})
    print(ret) # => 16.6667
今回結果が16.6667となってますが、これはtf.Variable
tf.zeros([3])を使っている為です。
tf.zerosは指定しないとtf.float32でオール0のテンソルを作成します。
tf.float32で計算する為、結果も少数値になってます。
値は、sess.runfeed_dictに[3,4,5]を指定し、array_varに値を設定しています。

TensorBoardで確認

それでは実際にTensorBoardを起動して確認してみたいと思います。

真ん中にname="array"で指定したtf.Variableが表示されています。
クリックすると内容が見れたりします。

スコープ付け

処理が複雑になってくると可視化も見づらくなってくるので、
そんな時の為にスコープを設定してみたいと思います。
実際にスコープを付けてみたソースがこちら
# coding: UTF-8
import tensorflow as tf

with tf.Graph().as_default():
    with tf.name_scope('variable') as scope:
        array_var = tf.Variable(tf.zeros([3]), name="array")

    with tf.name_scope('op') as scope:
        square = tf.square(array_var)
        reduce = tf.reduce_mean(square)

    with tf.name_scope('init') as scope:
        init = tf.initialize_all_variables()
        sess = tf.Session()
        sess.run(init)

    tf.merge_all_summaries()
    summary_writer = tf.train.SummaryWriter('report', sess.graph)
    ret = sess.run(reduce, feed_dict={array_var: [3.0, 4.0, 5.0]})
    print(ret)
TensorBoardを起動して見てみると指定したスコープで
区切られているのが分かるかと思います。


2016年6月15日水曜日

Googleの新しいビルドツールBazelを試してみる


Bazelとは?
Google自信が使っていたビルドツールを公開したものです。
Android、iOSなどでも使えるとのこと。現在はベータ版。
余談
なぜBazelを試そうかと思ったかというと、、
最近やってるTensorflowでBazelが使われていたからです、、はい。

環境準備 & インストール


2016年6月現在サポートされているプラットフォームは
  • Ubuntu Linux
  • Mac OS X
です。
あとJDK8以降が必要とのこと。
今回はVagrantでUbuntuの環境を用意してそこで試してみたいと思います。
UbuntuのバージョンがTrusty (14.04 LTS)であれば以下コマンドで
JDK8をインストールします。
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer
ちなみに途中でsudo apt-get updateを実行しないと、
E: Unable to locate package oracle-java8-installer
のエラーが出るのでお忘れなく^^;
Ubuntuのバージョンが'Wily (15.10)'の場合は以下コマンドでインストール。
$ sudo apt-get install openjdk-8-jdk
正常にインストールできたか確認
$ java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
良さそうです^^
あとは一気にBazelのインストールを行います。
$ echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
$ curl https://storage.googleapis.com/bazel-apt/doc/apt-key.pub.gpg | sudo apt-key add -
$ sudo apt-get update && sudo apt-get install bazel
$ sudo apt-get upgrade bazel
インストール確認
$ bazel version
Extracting Bazel installation...
Build label: 0.3.0
Build target: bazel-out/local-fastbuild/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Fri Jun 10 11:38:23 2016 (1465558703)
Build timestamp: 1465558703
Build timestamp as int: 1465558703

簡単なJavaプロジェクト作成


試しに簡単なJavaのプロジェクトを作成し、ビルドしてみます。
  • ディレクトリ構成
.
├── BUILD
├── WORKSPACE
└── src
    └── main
        └── java
            └── com
                └── slowhand
                    └── Sample.java
Bazelではworkspace毎の場所で作業します。
workspaceにはルート直下にWORKSPACEファイルが必要になります。
WORKSPACEはライブラリの外部参照を記述したりしますが、
今回は依存は無いので空のファイルを作成します。
  • Sample.java
単純にHello bazelと表示するだけのクラスです。
package com.slowhand;

public class Sample {
  public static void main(String args[]) {
    System.out.println("Hello bazel");
  }
}
  • BUILD
BUILDファイルにはソースコードの配置や参照ライブラリなど記述します。
java_binary(
  name = "sample",
  srcs = glob(["**/*.java"]),
  main_class = "com.slowhand.Sample",
)

ビルド&実行


それではビルドしてみます。
$ bazel build //:sample
INFO: Found 1 target...
Target //:sample up-to-date:
  bazel-bin/sample.jar
  bazel-bin/sample
INFO: Elapsed time: 10.765s, Critical Path: 7.52s
ビルドが成功するとbazel-binの配下に実行モジュールが作成されます。
$ bazel-bin/sample
Hello bazel
ちゃんと実行されてます^^
ちなみに、、WORKSPACEファイルがないと以下のエラーになります。
The 'build' command is only supported from within a workspace.

2016年6月11日土曜日

機械学習のフレームワークTensorflowを試す 5 - データフローグラフを可視化(TensorBoard) -


前回やった配列[3, 4, 5]の2乗した値の平均値を算出するデータフローグラフを
可視化してみたいと思います。
可視化するに当たってTensorBoardというツールを使用します。
Tensorflowをインストールすると使えます。
基本的な使い方は
$ tensorboard --logdir=<ログディレクトリのパス>
として実行し、ブラウザでhttp://0.0.0.0:6006にアクセスすると
可視化されたものが見られます。

可視化する為にコード修正

まずは修正前のコードです。
# coding: UTF-8
import tensorflow as tf

array = tf.constant([3,4,5])
square = tf.square(array)
reduce = tf.reduce_mean(square)
sess = tf.Session()
ret = sess.run(reduce)
print(ret) # => 16
このコードを可視化する為にちょこっと修正します。
# coding: UTF-8
import tensorflow as tf

array = tf.constant([3,4,5])
square = tf.square(array)
reduce = tf.reduce_mean(square)
sess = tf.Session()
ret = sess.run(reduce)
# 以下の行を追加
tf.train.SummaryWriter('report', sess.graph)
print(ret) # => 16
tf.train.SummaryWriterクラスを作成する行を追加のしています。
上では第一引数でイベントファイルを出力するディレクトリ名を、
第二引数でセッションのグラフを渡しています。
今回は単純にグラフを表示させるだけです。

TensorBoardで確認

修正したコードを実行するとreportディレクトリが作られているかと思います。
--logdirにreportディレクトリのパスを指定してTensorBoardを起動してみます。
↓ブラウザでアクセスしGRAPHのタグを表示させた結果です。

それっぽいのが表示されています。
丸が定数のノードで、楕円が計算処理を行うノードです。
次に各ノードをクリックして詳細を見てみます。
まずはConstつまりは配列の[3,4,5]です。クリックすると

右上に詳細が表示されています。Attributesにデータ型と値が確認できます。
次はSquareをクリックしてみます。二乗の計算処理を行うノードです。

Inputが先ほどのConstでOutputがRankMeanとなっています。
Meanは最終的な平均値を求める計算処理を行うノードというのは想像できるんですが、 他のRankrangeは、、?
調べてみると、
tf.reduce_meanは引数としてreduction_indiceskeep_dims
の引数を与えることができるようです。
例)
>>> import tensorflow as tf
>>> array = tf.constant([[3.,4.],[5.,6.],[7.,8.]])
>>> reduce = tf.reduce_mean(array)
>>> reduce0 = tf.reduce_mean(array, 0)
>>> reduce1 = tf.reduce_mean(array, 1)
>>> sess = tf.Session()
>>> ret = sess.run(reduce)
>>> ret0 = sess.run(reduce0)
>>> ret1 = sess.run(reduce1)
>>> print(ret)
5.5
>>> print(ret0)
[ 5.  6.]
>>> print(ret1)
[ 3.5  5.5  7.5]
tf.reduce_meanの第二引数で渡しているreduction_indicesの値が
何も指定しない場合は、 (3 + 4 + 5 + 6 + 7 + 8) / 6 = 5.5となります。
0の場合、(3, 5, 7), (4, 6, 8)の平均値を求めます。
(3 + 5 + 7) / 3 = 5(4 + 6 + 8) / 3 = 6
1の場合、(3, 4)、(5, 6), (7, 8)の平均値を求めます。
(3 + 4) / 2 = 3.5(5 + 6) / 2 = 5.5(7 + 8) / 2 = 7.5
どういった平均を求めるか設定してるようです。

今回のサンプルではreduction_indicesに値を
設定していない為、[9,16,25](square)(9 + 16 + 25) / 3 = 16.66...
として計算されています。
Ranktf.rankという次元数を求めるもので、rangetf.rangeという
その名の通り範囲を求めるものです。
reduction_indicesを指定しなかった場合のみ表示されるので、
tf.ranktf.rangeの結果を内部で使っているのではないか・・・と思います。

具体的にここで使ってる!!というのを見つけたかったのですが今回はここまで。