TensorFlowを使ってみる 1
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
この本を読み終わったので機械学習を実験してみようと思います。
ライブラリはGoogleが公開しているTensorFlowを使います
日本のPFI社が開発したChanierあたりも気になっているのでそのうち触ってみたいです
TensorFlowのインストール
PythonをAnacondaでインストールしているので以下のようにインストール
$ conda create -n tensorflow python=3.5
その次に環境を切り替えます
$ source activate tensorflow
ここで、私の環境ではシェルごと落ちる問題が発生しました。
調べると
pyenvとanacondaを共存させる時のactivate衝突問題の回避策3種類 - Qiita
pyenvのactivateと衝突しているらしいので、
export PATH="$PYENV_ROOT/versions/anaconda3-2.4.0/bin/:$PATH"
をshellの設定ファイルに追記しておきます 「eval "$(pyenv init -)" 」より後に記述
プロンプトが切り替わったら以下を実行
※CPUでしか使わない人は実行するらしい
(tensorflow)/Users/sode% conda install -c conda-forge tensorflow
TensorFlowを使った簡単な計算
このサイトに載ってる簡単な計算が動くか試しておきました。
Graph
import tensorflow as tf matrix1 = tf.constant([[3., 3.]]) matrix2 = tf.constant([[2.], [2.]]) product = tf.matmul(matrix1, matrix2) sess = tf.Session() result = sess.run(product) print(result) sess.close()
このサイトの説明によると、TensorFlowはNodeとedgeで構成されていて、それをGraphと呼んでいる
Graphの計算はSessionが管理している。
このコード例だとmatrix1とmatrix2がedgeでmatmul(行列積)がNode、これらを組み合わせたproductがGraphって事ですね。
計算はSessionのrunメソッドで実施し、内部的には高度な最適化がされてそう。
Interactive Session
import tensorflow as tf sess = tf.InteractiveSession() x = tf.Variable([1.0, 2.0]) a = tf.constant([3.0, 3.0]) x.initializer.run() sub = tf.sub(x, a) print(sub.eval()) sess.close()
続いての例はtensorflowのeval使ってインタラクティブに(いちいちSession.runせずに)計算させたい時に使うっぽい。
Variables
import tensorflow as tf state = tf.Variable(0, name="counter") one = tf.constant(1) new_value = tf.add(state, one) update = tf.assign(state, new_value) init_op = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init_op) print(sess.run(state)) for _ in range(3): sess.run(update) print(sess.run(state))
Variableは変数。assignもNodeの1種でSessionのrunで計算するまで評価されない。updateを評価(run)する際にassignとaddが走りstateが更新される。
Fetches
input1 = tf.constant([3.0]) input2 = tf.constant([2.0]) input3 = tf.constant([5.0]) intermed = tf.add(input2, input3) mul = tf.mul(input1, intermed) with tf.Session() as sess: result = sess.run([mul, intermed]) print(result)
Sessionのrunは同時に複数のGraphを渡し、同時に計算する事が可能
Feeds
import tensorflow as tf input1 = tf.placeholder(tf.float32) input2 = tf.placeholder(tf.float32) output = tf.mul(input1, input2) with tf.Session() as sess: print(sess.run([output], feed_dict={input1:[7.], input2:[2.]}))
GraphのEdgeは型だけ用意しておいて評価時(run)に実体を渡してもいいよという事
rails5 + puma + nginx で AWSテスト環境を構築してみる
puma
railsのAPサーバとWebサーバですが、昨今ではrails5にpumaが標準になったり、herokuがpumaを推奨したりとpumaがおすすめらしいので私のサービスのテスト環境もpumaで構築することとしました。
ざっくりとした手順は以下のような感じです
- railsの設定(ここは割愛します)
- puma.rbの編集
- puma起動ファイルの編集(/etc/init.d/puma)
- nginxのインストール&編集
pumaのコンフィグファイル修正
rails5でアプリを作るとアプリケーションがあるディレクトリのconfig/以下にpuma.rbってのが出来ています。
以下の項目を追記します
# アプリケーションがあるディレクトリと各種ファイルを生成するディレクトリを指定する # tmpディレクトリは存在していないが、手動で作成するか起動時のスクリプトで作成するようにする # socketやlogやpidファイルを格納するディレクトリも存在していないので手動かスクリプトで作成 # 存在しないと起動出来ずに落ちます app_dir = File.expand_path("../..", __FILE__) tmp_dir = "#{app_dir}/tmp" # 環境変数を指定する。起動時に変数があればそれを見る。無ければテスト環境である"staging"としている rails_env = ENV['RAILS_ENV'] || "staging" environment rails_env # socketでbindする。nginxからsocket経由で接続するため bind "unix://#{tmp_dir}/sockets/puma.sock" # ログ出力ファイルの指定 stdout_redirect "#{tmp_dir}/logs/puma.stdout.log", "#{tmp_dir}/logs/puma.stderr.log", true # pidとstateファイルの格納 pidfile "#{tmp_dir}/pids/puma.pid" state_path "#{tmp_dir}/pids/puma.state"
pumaの起動ファイルの作成
pumaの起動ファイルについてはサーバが再起動しても自動で立ち上がるようにinit.dに書きます
※upstartなどで書いてもいいいです
各種ディレクトリの生成(無ければ)と、起動ユーザーを気をつけて、起動時の環境変数に気をつけましょう
sudo vi /etc/init.d/puma
#!/bin/bash NAME=puma USER=ubuntu APP_NAME=app APP_DIR=/home/$USER/$APP_NAME TMP_DIR=$APP_DIR/tmp PID_DIR=$TMP_DIR/pids SOCKET_DIR=$TMP_DIR/sockets LOG_DIR=$TMP_DIR/logs PUMA_BIN=/home/$USER/.rbenv/shims/puma RAILS_ENV=staging sudo -u $USER -H sh -c "mkdir -p $PID_DIR" sudo -u $USER -H sh -c "mkdir -p $SOCKET_DIR" sudo -u $USER -H sh -c "mkdir -p $LOG_DIR" PIDFILE=$PID_DIR/puma.pid start() { cd $APP_DIR; sudo -u $USER -H sh -c "echo \$\$ > $PIDFILE; RAILS_ENV=$RAILS_ENV $PUMA_BIN -C $APP_DIR/config/puma.rb -d" } stop() { echo -n "Stopping puma" kill -s SIGTERM `cat $PIDFILE` } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart}" >&2 exit 1 ;; esac
これで sudo chmod +x /etc/init.d/puma をして sudo /etc/init.d/puma start でpumaを立ち上げてみましょう。
ps axu|grep pumaで
ubuntu 27220 0.0 1.6 343440 16468 ? Sl 04:26 0:00 puma 3.7.0 (unix:///home/ubuntu/app/tmp/sockets/puma.sock) [app] ubuntu 27227 0.1 10.3 830828 105096 ? Sl 04:26 0:02 puma: cluster worker 0: 27220 [app] ubuntu 27230 0.1 16.0 892820 162328 ? Sl 04:26 0:02 puma: cluster worker 1: 27220 [app]
こんな感じで立ち上がっていなかったら失敗です。
tmp, sockets, pids, logsディレクトリが存在しているかと所有者やパーミションが起動ユーザーで問題ないか確認しましょう。
ちなみにですが、bundle.jsの生成など事前に各種ファイルのprecompileはしておきましょう。
nginxのインストールと設定
nginxのインストールは以下のサイトを参考にしました
How To Deploy a Rails App with Puma and Nginx on Ubuntu 14.04 | DigitalOcean
$ sudo apt-get install nginx
続いて設定ファイルの編集
$ sudo vi /etc/nginx/sites-available/default
/etc/nginx/sites-available以下にアプリ用のファイルを新規作成してsites-enabled以下にシンボリックリンクを張ってもよいです。
upstreamのところで先ほどpumaで生成したsocketに接続する設定をしています
upstream app { # Path to Unicorn SOCK file, as defined previously server unix:/home/ubuntu/app/tmp/sockets/puma.sock fail_timeout=0; } server { listen 80; server_name app.jp; keepalive_timeout 300; client_max_body_size 4G; root /home/ubuntu/app/public; try_files $uri/index.html $uri @app; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Forwarded_Proto $scheme; proxy_redirect off; proxy_pass http://app; proxy_read_timeout 300s; proxy_send_timeout 300s; } # You can override error pages by redirecting the requests to a file in your # application's public folder, if you so desire: error_page 500 502 503 504 /500.html; location = /500.html { root /home/ubuntu/app/public; } }
あとは sudo /etc/init.d/nginx start で起動し、上記のserver_nameで指定したドメイン(もしくはIP)に接続出来れば成功です。
Deep Learning
# Deep Learning 5
逆誤差伝搬法の数学的お勉強
高卒でもわかる機械学習 (5) 誤差逆伝播法 その1 | 頭の中に思い浮かべた時には
前回見たスライドはスライド48のあたりがイマイチ分からなかったので上記で読み直し
さらに分かりやすいです
逆誤差伝搬法は計算量を如何にして減らすかという事で、N層パーセプトロンがある場合は
N層、N-1層、N-2層と逆順に、重みの微小変化(その層の重みによる勾配法で損失関数を減少させる)をみていきます。k-1層の計算時点でk層の計算結果を利用出来るようになっているとうのがキモ
本のp.148 (5.13)の補足
この式の1要素目に着目し、図5-24のX → X・W → Yの1要素目の計算の流れを見てみると
→ →
となっていてYへの出力に関しては
となっていて
を代入すると
と書ける。
※は3行2列中の1列目のみ
これを他の要素()に関しても導くと 5.13 の上の式が導ける。下の式も同様な感じで導ける
商標登録の出願
個人で作っているWebサービスのサービス名(ロゴではなく文字のみ)の商標登録出願をやってみた
結論から言うと出願自体はすごく簡単。
やりかたをざっくり書くと
1. 特許庁の商標登録出願のpdfを熟読
http://www.jpo.go.jp/shiryou/kijun/kijun2/pdf/syutugan_tetuzuki/05_01.pdf#page=5
これのp.548 ~ p.557あたりまでを熟読する
2. 出願用のwordファイルを探す
上記pdfのp.552のフォーマットのwordファイルを探す(このフォーマットを一から作ってもよい)
3. 出願用のwordを書く
個人で出願する場合は以下を記載すればOK
- 書類名
- 整理番号
- 提出日
- あて先
- 商標登録を受けようとする商標
- 標準文字
(上記「商標登録を受けようとする商標」の枠の下側に【標準文字】とだけ記載)
- 指定商品又は指定役務並びに商品及び役務の区分
- 区分(【第42類】等)
- 指定商品(指定役務)
- 商標登録出願人
- 住所又は居所
- 指名又は名称
(名前の横に自分の名前の判子を押印。印鑑登録してなくても大丈夫)
- 電話番号
全て全角(数字も)で記載し、フォントサイズは10〜12、左右の空白は2〜2.3cmとする(一番左側や右側に位置している文字からの余白)
指定商品(指定役務)の部分は以下のサイトなどから区分に該当する箇所を抜き出してくる(全部書いてもよい)
商標登録: 指定役務リスト
4. でかめの郵便局又は特許庁で特許印紙を買う
印紙代は以下のサイトを参考に。(ちなみに2区分で出願する場合は20600円)
産業財産権関係料金一覧(2016年4月1日時点) | 経済産業省 特許庁
5. 特許庁で最終確認してもらう
出願時に足りない箇所等あれば教えてもらえるので聞く
6. 出願
問題なければ印紙を貼り付けて出願。
紙で提出した場合は電子化代が必要で郵送で送られてくるそう。それを郵便局で支払う。
※電子化代はまだ払っていないが出願時にもらう紙によると1200円+(700円x枚数)との事なのでおそらく1900円。
以上終わり
おそらく弁理士に頼むメリットとしては出願しても申請が通らないケースがあるのでそれの判定や
適切な出願範囲(間違えると範囲外の権利を主張出来ない)を考えてもらえる事がある。
自分みたいにとりあえず適当な範囲でいいので出願したい場合は要らなかった。
Deep Learning
# Deep Learning 4
誤差逆伝搬法の勉強
前の章で実装した損失関数の勾配の微分計算はとてつもない時間が掛かるのでそれを早くしましょうっていう話。
計算グラフで説明するとの事だったので概要を理解したく以下のスライドを読んでみた
www.slideshare.net
かなり分かりやすい
Deep Learning
Deep Learning 勉強 3
勾配法
前回勉強した損失関数は訓練データが如何にテストデータ(正解)に近づいたかを示す関数で、2乗和誤差や交差エントロピー誤差などは0に近いほどテストデータに近いと定義されている。
最終的な目標は認識精度を上げる事なので、3.6.2 ニューラルネットワークの推論処理でやった最終的な正解の割合(accuracy)を指標としても良さそうですが、これだとパラメータ(重みとバイアス)の微小な変化に対してほとんどが変化しない事が問題となるそうです。
言い換えるとパラメータを入力、推論結果(accuracy)を出力とする関数を考えるとほとんどの入力で微分が0となり、0に近いパラメータをさがす事が事実上出来なくなる。
これらを解消するため損失関数という入力に対して連続な(微分可能な)関数を選んでいます。
勾配法はこの損失関数を入力で微分(偏微分)し、最小となる入力パラメータを探す方法の一つで
4.4.1では最急降下法というアルゴリズムが用いられていて
となってます。
この方法は極小値を探すのには向いてますが、最小値を探す場合は様々な初期値で試す必要があるとの事。
Deep Learning
Deep Learning 勉強 2
4.2 損失関数の交差エントロピー誤差
cross_entropy_errorで微小な値を追加しているので少し考察
= log(y ( 1 + delta/y))]
ここでdeltaは微小な値なのでは限りなく1に近い
これより は限りなく0に近いことになるため
といえる。
4.2.4 バッチ対応版交差エントロピー誤差の実装
tがラベル表現だったらの箇所の意味がいまいちわからなかったけど
バッチサイズが5だとすると、tがone_hot表現の時は
t1 = [[0, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 1, 0]]
という表現で行が各々のテストデータの結果で、列が出力の数。
tがラベル表現の時は
t2 = [3, 0, 1, 0, 2]
というように各々のテストデータの結果の正解インデックスの値ということ