2017年6月28日水曜日

ニューラルネットワークにおけるバッチ処理の高速化測定メモ

オライリー本で、ニューラルネットワークがバッチ処理で高速になる、という話があり(ディープラーニング/斎藤, 3.6.3章 バッチ処理)、どれほど速くなるのかを見てみました。

ソースコードはそのまま流用していますが、line_profilerでの測定用に関数にしています。
x, t = get_data()
network = init_network()
def get_accuracy_with_batch(x, t, network):

    batch_size = 100 #
    accuracy_cnt = 0
    for i in range(0, len(x), batch_size):
        x_batch = x[i:i+batch_size]
        y_batch = predict(network, x_batch)
        p = np.argmax(y_batch, axis=1)
        accuracy_cnt += np.sum(p== t[i:i+batch_size])
    print("Accuracy:" + str(float(accuracy_cnt) / len(x)))

    accuracy_cnt = 0
    for i in range(len(x)):
        y = predict(network, x[i])
        p = np.argmax(y)
        if p == t[i]:
            accuracy_cnt += 1
    print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
という関数にしておいて、バッチにしているものと、そのままのものを連続して動かします。


%lprun -f get_accuracy_with_batch get_accuracy_with_batch(x, t, network)

で測定してみると。確かに高速になっています(1/6くらい)。
Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     3                                           def get_accuracy_with_batch(x, t, network):
     4                                             
     5         1            2      2.0      0.0      batch_size = 100 #
     6         1            1      1.0      0.0      accuracy_cnt = 0
     7                                         
     8       101          115      1.1      0.0      for i in range(0, len(x), batch_size):
     9       100          176      1.8      0.0          x_batch = x[i:i+batch_size]
    10       100        58223    582.2     12.4          y_batch = predict(network, x_batch)
    11       100         1111     11.1      0.2          p = np.argmax(y_batch, axis=1)
    12       100         2029     20.3      0.4          accuracy_cnt += np.sum(p== t[i:i+batch_size])
    13                                         
    14         1          116    116.0      0.0      print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
    15                                             
    16         1            1      1.0      0.0      accuracy_cnt = 0
    17     10001         4512      0.5      1.0      for i in range(len(x)):
    18     10000       366764     36.7     77.8          y = predict(network, x[i])
    19     10000        23556      2.4      5.0          p = np.argmax(y)
    20                                         
    21     10000         9054      0.9      1.9          if p == t[i]:
    22      9352         5339      0.6      1.1              accuracy_cnt += 1
    23                                         
    24         1          171    171.0      0.0      print("Accuracy:" + str(float(accuracy_cnt) / len(x))

2017年6月21日水曜日

jupyter + lprun の設定メモ

line profilerを使って行ごとの処理時間を測ります。自分メモ。Python3, ubuntu16.04LTS

line profilerモジュールをインストール、設定

 condaでするなら。
conda install -c anaconda line_profiler   
でインストール。下記の設定をします。隠しフォルダ.ipythonの中のファイルに設定を書き込みます。ちなみに、ubuntu+jupyterではこれをしなくても動作しました。

 ~/.ipython/extensions/line_profiler_ext.py

を開きます。(なければ作成します)
import line_profiler
def load_ipython_extension(ip):
    ip.define_magic('lprun', line_profiler.magic_lprun)
と書いて保存し、マジックワードを設定。

~/.ipython/profile_default/ipython_config.py

を開いて、どこでも良いのでこれを追記します。
c.TerminalIPythonApp.extensions = [
  'line_profiler_ext',
]

lprunの使い方

1.

jupyterで使うときは、この一行を入れます。
%load_ext line_profiler
2.

測定したい部分を関数にします。
 def foo():
    list_test = []
    for i in range(1000):
        list_test.append(i)
3.

# %lprun  -f  関数名 関数(引数あれば)
を入力することで、関数の行ごとの時間を測ります。
%lprun -f foo foo()
結果はこのように出力されます。 これを見ると、どこに時間がかかっているかが分かります。

Hit: その行を通った回数
Time:その行にかかった時間(単位は上部のTimer unit: 1e-06 s→今はマイクロ秒)
Per Hit: その行を1回通るのにかかった時間
%Time: 全体の中でその行が占める時間割合




例えば今のforループをリスト内包表記に書き換えると。
def bar():
    lsit_test = [i for i in range(1000)]
速くなっているのが分かります。


Timer unit を設定するとき

デフォルトでは1e-06 s(マイクロ秒)ですが、環境によっては設定が変わって適当な値になることがあります。自分で明示的に設定するときは
# %lprun  -f  関数名 -u 0.000001 関数(引数あれば)
というように-u オプションを使います。

あるいは、このように設定します。
profiler = LineProfiler()
profiler.print_stats(output_unit=0.000001)

関数名を変数にしたいときは$を使う

func = 'some_function'
のとき、この変数funcをプロファイルするには$funcとしてlprunに渡します。
%lprun  -f  $func  関数(引数あれば)

lprunの結果をテキストに出力する

-T <filename>コマンドを使います。ファイル名はそのまま打てばよく、文字列にする必要はありません。
%lprun  -f  main -T test.txt main()
***Profile printout saved to text file 'test.txt'

と出力されます(これはソースをいじらないと消せない)。ディレクトリで指定したいときは
-T dir\test.txt
でOKです。

ファイル名を変数として渡すときは$filename のように$をつけます。

filename = 'test_var_name.txt'
%lprun  -f  main -T $filename main()

2017年6月18日日曜日

Webアプリエンジニア養成読本 PHPメモ 主に失敗箇所、本の誤字脱字

つらつらとメモ。自分の間違いもあるが、本の間違いが非常に多い・・・。


■失敗

<?php



<? php
と書いていた(スペース不要)

その他、
templates, settings のs 抜け
sqlightと書いていた
など、スペルミス多発・・・

--
サーバのターミナルに

127.0.0.1:39330 Invalid request (Unexpected EOF)

というエラーが出るが、これはPHPのビルトインサーバの意味なしエラーで対処しようがないらしい。
http://stackoverflow.com/questions/29141240/php-local-server-invalid-request-unexpected-eof

--

$ sudo add-apt-repository ppa:ondrej/php5

という部分、p34) php5と書くとエラー。phpのみで通る。

なんやかんで、PHP5.6をいれる場合はこうしたらOK。
$ apt-get install php5.6-xml
https://github.com/oerdnj/deb.sury.org/issues/472

だめだったので、php7.1を入れました。

--

p40 がおかしい
リスト5は不要
autoloadの部分はリスト1で既に記述してあるのに追記という表現になっている。

--

■失敗

'Slim\Slim' not found in /dir/XXX/

というエラーでハマる

autoloadが正常に機能していない?

require '../vendor/autoload.php';

を消してしまっていたのが問題だった。
「修正し」という表現がどうにも誤解してしまったようだ。反省。

--

~/Tinitter/lib$ atom /Base/DB.php

こういう感じでフォルダを指定してphpファイルを作ったら、保存できなかった。Baseのpermissionがないという警告。

~/Tinitter/lib/Base$ atom DB2.php

であれば問題なかった。

リネーム。名前の違うファイルに移動する。
~/Tinitter/lib/Base$ mv DB2.php DB.php

--

p47
リスト22では → リスト6 ではの間違い。(別の章から通しで番号をつけていた名残の直し忘れ?)

--

$ sudo apt install composer
でインストールした
$ composer require respect/validation
でrespect/validationを入れた

--

class Post extends \Respect\Validation\Validator

というクラス継承で正常に動いている。

php ~/composer.phar update


--

■PDO driver が入っていないエラー

リスト15

Slim Application Error
The application could not run because of the following error:

Details

Type: PDOException
Message: could not find driver
File: /home/shimo/Tinitter/vendor/illuminate/database/Illuminate/Database/Connectors/Connector.php
Line: 47

というエラーが出て沈没

// githubの最終には以下が入っていない・・が関係なさそう
// $app->post('/post/commit', '\Tinitter\Controller\Post:commit');

[Wed May 17 20:33:10 2017] Tinitter\Model\Post Object
(
    [connection:protected] =>
    [table:protected] =>
    [primaryKey:protected] => id
    [perPage:protected] => 15
    [incrementing] => 1
    [timestamps] => 1
    [attributes:protected] => Array
        (
        )

    [original:protected] => Array


protectedなのが問題?

と思ったが、

$post->save();
の後が現れなかったので、ここが問題であるようだ

結局、ドライバが入っていないのはそもそもインストールされていないということだった
$ sudo apt-get install php7.0-sqlite3

http://stackoverflow.com/questions/30009618/why-cant-create-the-sqlite-db-with-pdo
http://stackoverflow.com/questions/37894766/how-to-solve-php-7-not-found-sqlite3
http://stackoverflow.com/questions/35240414/laravel-5-pdoexception-could-not-find-driver

これで解決。

///別PCでは、上記では解決せず。--> phpのバージョンが違ったので、変えればOK

--

本文が現れない・・・
sqlite.dbには格納されているので表示の問題

show.twigの
<div class="body">{{ post.body|nl2br }}</div>
は|(パイプ)を読み間違えていました。


--

■失敗
page2以降が表示されない・・・
show.twigのあたりがおかしかった模様
{% if page_num == 1 %}

--

既にインストールしてあるものを再度書いてある
CSRFは slim/Extraに・・・


Exception: Sessions are required to use the CSRF Guard middleware. in /home/shimo/Tinitter/vendor/slim/extras/Slim/Extras/Middleware/CsrfGuard.php:63

となっているので、インストールしなおし?

$ php composer.phar update

でやり直してみたが、特に変更なし
CSRFのプラグイン有効化の場所が違う?

https://github.com/uzulla/Tinitter

これでphpサーバ立ち上げ
~/Tinitter/htdocs$ php -S 127.0.0.1:8080

--

二周目。新PCでやってみる

Type: Twig_Error_Loader
Message: The "./templates" directory does not exist
というエラーが出て、図6のようにならない。
templatesのディレクトリの設定が間違っている?
ディレクトリのpathの受け渡しがおかしいようだ。が、なんともならず。最初からやり直すことにする。

templates -> template スペルミスだった s抜け
autoescape -> o が抜けるスペルミスだった

Vagrant接続メモ


ローカル環境の立ち上げ方
ドットインストール通り

ログイン、ターミナル立ち上げ

$ cd MyVagrant/MyCentOS

に入る。(VagrantFileがあるところ)

$ vagrant up

でVirtualBOX立ち上げる

$ vagrant ssh

でログインする

$ cd php_lessons

で表示したいindex.phpがあるdirに移動

$ php -S 192.168.33.10:8000

でビルトインに接続

[vagrant@localhost php_lessons]$ php -S 192.168.33.10:8000
PHP 5.6.30 Development Server started at Sun May 14 21:21:12 2017
Listening on http://192.168.33.10:8000
Document root is /home/vagrant/php_lessons
Press Ctrl-C to quit.

と出たらOK
http://192.168.33.10:8000
をブラウザに貼り付ければ、index.phpが表示される


--

$ filezilla

でFileZilla起動

SiteManager の項目→Connect

RemoteSite は空白

LocalSite /home/username/

で良い



Rubyメモ Webアプリエンジニア養成読本

やったことメモ@Webアプリエンジニア養成読本のRuby編

$ gem list --local
でgemのヴァージョンを確認できる


Railsのサイトに行ってRubyをインストール
https://gorails.com/setup/ubuntu/16.04

Rubyバージョン2.1.10を選ぶ。出てきたコードをそのままコピペ
rbenvをインストールしてからruby-build

cd
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL

rbenv install 2.1.10
rbenv global 2.1.10
ruby -v


本では2.1.0なので、2.1.10から変更した
2回目では2.1.10でやってみた
Downloading ruby-2.1.0.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.0.tar.bz2
Installing ruby-2.1.0...

WARNING: ruby-2.1.0 is nearing its end of life.
It only receives critical security updates, no bug fixes.

この状態で固まったように見える・・・時間がけっこうかかります・・・10分以上待ったような気がします。ともかく完了。

$ ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]

2回目
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux]


■rackのインストール
gem install rack

とやると下記エラー

ERROR:  Error installing rack:
rack requires Ruby version >= 2.2.2.

https://github.com/phusion/passenger/issues/1710

$ gem install rack -v=1.6.4

とすると1.6.4をバージョン指定して入れることができました。


sinatraも同様のことがおきたのでバージョンを下げてインストール

$ gem install sinatra
ERROR:  Error installing sinatra:
rack requires Ruby version >= 2.2.2.


$ gem install sinatra -v=1.4.4


本p86,87 リスト10,12の誤植?
<ul> -> </ul> では?






ドットインストールのレッスンの人気ランキング

最近、dotinstallをやっているのですが、レッスン数はトータルで306、ビデオ5000超ということで非常に多いな、と。

各レッスン毎に「全ユーザーの学習状況」という項目があり、「HTML入門」であれば、

完了済
16,451
学習中
40,135
閲覧数
3,916,075



となっています。

これを306レッスンで比較してみよう、という試みです。データはBeautifulSoupを使って抜き出し(省略)

完了済のレッスンを上位10まで並べてみます。

lesson name 完了済
【サポート終了】ドットインストール入門 (全1回) 37597
【旧版】HTML入門 (全22回) 19330
HTML入門 (全24回) 16316
JavaScript入門 (全24回) 13449
【旧版】CSS入門 (全20回) 13116
【旧版】JavaScript入門 (全25回) 12960
【旧版】HTML入門 (全16回) 10885
【旧版】実践!ウェブサイトを作ろう (全16回) 9076
【旧版】CSS3入門 (全19回) 8894
UNIXコマンド入門 (一般ユーザー編) (全16回) 8252

・・・やり初めてから気づいたのですが。旧版は別名のレッスンとしてカウントされているようで、少し考えどころかもしれません。

2017年6月17日土曜日

Vostro Desktop 3268 開封の儀

デルのデスクトップPC(Vostro Desktop 3268)買いました。ちょっとうれしいので開封の儀をします。

発注から15日で到着、価格ドットコムの割引も使えたので税込み7万円くらいでした。

スペックは
338-BKWB 第7世代 コア i7-7700 プロセッサー (8MB キャッシュ, 最大 4.20 GHzまで可能) 1
370-ADJY 8GB DDR4 2400MHz
400-AMXY 1TB 7200 rpm SATA HDD

届いた感想。「思っていたより軽い」



段ボール箱を開けたところ。キーボードなどの付属品の梱包が見えます。



さらに開けたところ。本体があります。小さい。



Vostro 3268本体です。


背面側。


付属品は電源ケーブルとDVDソフトとマウス。


付属キーボード。良さそうでしたが、使わずマウスと一緒に譲渡。

とりあえずWindows10も設定しておきます。ubuntuはあとで。

初期設定では「とにかく情報公開」という方向になっているような・・・オフにしておきました。

初期設定は完了です。ubuntuしか使ってませんけど。


--



概ね不満はないのですが。あるとすれば、、bluetooth出力の音質が悪すぎる。。iPhone等とは比べ物にならないくらい悪いです。

(このサイズのデスクトップを使った経験がないので不明ですが)たまにカタカタ音がしていて何だろう、と思います。

あれば追記します。

2017年6月9日金曜日

クローラ、スクレイピングのメモ

■Cookieの情報を使ってログイン必要なWEBページを読みたい

chromedriverを使ったら解決。Chromedriverを適当にqiitaに書いてあったコードを使って入れたら動作せず。バージョンが古かったのか、最新のものを入れたら動いた。きちんと確認しましょう。

Chromdriver起動、入力してsubmitしてログイン、
そのままURLに移動、抽出、(次のURL・・・)、保存。

出力はテキストで。
savefile = test.txt
f = open(savefile,"w")
f.write(output_string)
f.close()


■Chromdriver起動
chromeを起動して、検索文字列を入力、Submit
# tutorial from chromdriver

import time
from selenium import webdriver
driver = webdriver.Chrome('/usr/local/bin/chromedriver')  # Optional argument
driver.get('http://www.google.com/xhtml');
time.sleep(5) # Let the user actually see something!
search_box = driver.find_element_by_name('q')
search_box.send_keys('うへへへ')
search_box.submit()
time.sleep(5) # Let the user actually see something!
driver.quit()

2017年6月6日火曜日

Deep Learningの本はじめました

最近の勉強メモ:

ゼロから始めるDeep Learning(斎藤:オライリー)をはじめました。なんとなく知っている内容で、Pythonで1から(0から、は厳しいのでは?)やるのはなかなか楽しそうです。日本語ネイティブが書いているはずなのに、英語からの翻訳口調に見えてしまうのが不思議。

・・・Deep Learningが出てくるのは最後の1章だけで、ニューラルネットワークの話が基本なんだよなぁ。。

ubuntuコマンドのメモ

Ubuntu Linuxのコマンドをメモしていきます。自分用・・・

ファイルから文字を検索する


grep string filename

ls コマンドの結果からパイプする...該当のファイル名だけが出力される


ls directory | grep filename

ls filename でワイルドカードを使う


ls *file* とやると前後に何か文字があってfileを含むものを検索する

ディレクトリのファイルを対象に、中の文字を検索してファイルを探す

find ./ -type f | xargs grep -l -s "string"

※-l は該当するファイル名だけを出力するオプション
※-s はエラーを出力しないオプション
※stringはダブルクォーテーションが必要

ヘルプを読むときのgrep


--helpで使い方を調べたいとき、対象を絞るためにgrepをすると便利。ls でsortの仕方を知りたいときは。

$ ls --help | grep sort

とすると、長いヘルプを全部読まなくてもよくなります。

コマンド履歴を調べるhistory


入力したコマンドをあとで使いたいとき、historyが便利でした。

$ history

で番号でこんな感じで出てきます。

  348  ls /usr/share/X11/xkb/symbols/
  349  cd /.xkb/
  350  cd ~/.xkb/
  351  ls
  352  cd keymap
  353  ls
  354  cd ../
  355  ls symbols
  356  cd ../
  357  setxkbmap -print

$ history | grep [command]

で使ったcommandを検索できます。

!351

と351番コマンドが実行されることになります。

ファイルをバイナリ単位で比較するcmpコマンド


ファイルが同一かどうかを比べるには、cmpを使います。

$ cmp file1 file2 | echo "files different"

ちなみに、同一のときは何も変えらないです。
https://stackoverflow.com/questions/12900538/fastest-way-to-tell-if-two-files-are-the-same-in-unix-linux

ubuntuで再起動が必要になっているかどうかを知る


/var/run/reboot-required

というファイルが存在するかどうかを確認します。存在していれば、
stat /var/run/reboot-required
とやって中身を見ると、

 File: '/var/run/reboot-required'
  Size: 32        Blocks: 8          IO Block: 4096   regular file
Device: 13h/19d Inode: 327         Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-08-26 12:51:09.226219216 +0900
Modify: 2018-08-26 12:44:15.434398888 +0900
Change: 2018-08-26 12:44:15.434398888 +0900
 Birth: -

というように、いつのファイル操作(更新など)で必要になったかが判ります。
再起動のあと見てみると、ファイルが見つからないというメッセージが出ます。

$ stat /var/run/reboot-required
stat: cannot stat '/var/run/reboot-required': No such file or directory

https://askubuntu.com/questions/164/how-can-i-tell-from-the-command-line-whether-the-machine-requires-a-reboot


更新時間を指定してファイルをfind検索する


2019/05/15の0時以降に更新したファイルを検索
$ find . -type f -newermt "2019-05-15 00:00:00"

2019/05/15の0時から翌日0時までに更新したファイルを検索
$ find . -type f -newermt "2019-05-15 00:00:00" ! -newermt "2019-05-16 00:00:00"

https://superuser.com/questions/580273/ubuntu-linux-find-files-between-specific-times