粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

「インターネットなし,セキュリティ保護あり」となりネットに繋がらない

上記のメッセージが出たときは基本再起動安定ですが,僕に起こった事件ではもっと面倒な事を要求されました。

多分,以下のと似たような事例なんだと思います。
windows10で最近ネットがつながらなくなったら、まず放電を試すべき - パソコンりかばり堂本舗

とにかく,放電せよとのことです。電池を抜いて10分ほど放置すれば治りました。
どうもPC本体が不調なのかな?
よくわかりませんがとにかくこういうこともあるということで。

Texで行列を楽に書く方法

Latexでの行列の書き方。

Latexで行列を書くのは面倒です。

よく使う書き方としては大体以下の2つが挙げられるでしょう,

\begin{pmatrix}
a & b \\
c & d 
\end{pmatrix}

または,

\left( \begin{matrix}
a & b \\
c & d 
\end{matrix} \right)

出力はマージンに違いこそあれこうなりますね。
f:id:ossyaritoori:20170610134858p:plain

でも正直これ,すっごく打つのが面倒くさいです。
そもそもbeginって打ちたくないんだよなぁ。

行列を簡単に書くためのマクロ

そこでマクロを組みます。

以下のような宣言を行えば,

\newcommand{\pmat}[1]{\begin{pmatrix} #1 \end{pmatrix}}%行列簡略化
\newcommand{\mat}[1]{\left( \begin{matrix} #1 \end{matrix} \right)}%行列簡略化

先程の2つは次のように書けるようになります。スッキリするし何より可読性が上がります。

\pmat{a & b \\ c & d }

\mat{a & b \\ c & d}

Shift押しながら入力する「{,},(,)」の入力が減ったので大いにストレスが減ります。オススメです。

一応マクロの解説

マクロの順番としては受け入れ関数名,引数の数,処理内容となっています。

\newcommand{受け入れ関数名}[引数の数]{処理内容,ただしn番目の引数を#nと表す}

ちょっと書きなれないけど慣れれば素早くマクロを組めるようになるでしょう。
(ただしマクロが多すぎるコードは可読性が低くなるので注意!)

Windows10のロック解除画面の壁紙抽出

Windows10から追加された謎の壁紙のありか

Windows10のOne of 謎機能ですがWindowsの起動時になんか綺麗な壁紙が設定されるようになりましたね。
時々気に入った画像とかもあるので何とかして元のファイルを手に入れたいと思っていた所,
居場所を特定したので掘り出し方を解説したいと思います。


今回の掘り出しの結果です。割りと満足。
f:id:ossyaritoori:20170606192053p:plain

綺麗な壁紙のデータのある場所

端的にいうと,ユーザー以下の,
「\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets」
という所にあります。

ぱっと言われてもわからない人のために

まず,左の欄の「PC」と書かれた所をクリックして,
下のようなものを探してダブルクリックします。
f:id:ossyaritoori:20170606193521p:plain
これが俗に言う「Cドライブ」ってやつです。

何故Cなのかは結構面白い理由があるのでぜひ調べてみてください。

次に,中を見てみると「ユーザ」と書かれたフォルダがあるはずです。
f:id:ossyaritoori:20170606193730p:plain
この中に入った後に,貴方のPCのユーザ名(PassWordを入れる時に出てくる名前)のフォルダが出てくるのでそれをクリックしてください。

その後は,「AppData],「Local」と上の赤字の¥マークで区切られている順にファイルを探していってください。

AppDataってフォルダが見つからない?

それはエクスプローラーが標準で隠しフォルダを表示する設定になっていないからです。

エクスプローラーの上の方にある「表示」というタブをクリックすると以下のような画面が出るかと思います。
f:id:ossyaritoori:20170606194402p:plain
黄色の線で強調した所がきちんとチェックされていることを確認して下さい。

また,左にある「レイアウト」で< 大アイコン >や< 詳細 >となっている箇所も後で使うので覚えておいてください。

ファイルの場所にたどり着いたら

ファイルの場所にたどり着いたら以下のような英数字の羅列が名前になったファイルが見れると思います。
f:id:ossyaritoori:20170606194722p:plain
これらが実は画像データなのです。

まずはファイルをコピーする

フォルダの中身をまずピクチャ以下のフォルダかなんかに退避させましょう。
一般的に隠しフォルダの中身をいじるのはおすすめできません。

ファイルを大きさ順にソート

ファイルをサイズ順にソートしましょう。
まずエクスプローラーの上部をクリックして「レイアウト」にて< 詳細 >をクリックしてください。
f:id:ossyaritoori:20170606194402p:plain

すると右の方に先程の画像と同じように「1090KB」などのサイズが出てくるはずです。
右上の方にある「サイズ」という欄をクリックするとサイズの大きい順,小さい順にソートする事ができます。

このうち,壁紙に使われるファイルサイズは基本的に数百KBですので2桁以下のサイズのファイルは全て削除して構いません。
必ずコピーしたファイルに対して変更を適用すること!

ファイルの復元の仕方

ファイルを復元するには適切な拡張子をつけてあげればいいです。
この場合,「.jpg」を後ろにつけます。

すなわち,「kabegami1.jpg」というように名前を変えることで画像を読み取れます。
読み取れない場合,「表示」以下「拡張子」というチェックボックスがOnになっているか(「AppDataが見つからない?」で黄色線を引いた箇所)
実は画像以外のファイルだったというのが考えられます。画像以外のファイル出会った場合は消してしまいましょう。

名前を変更する際は「F2」キーを押すとすぐ変更できて便利です。

追記:有志による名前変更用Python Script

コメントにて,自動でRenameを施してくれるPythonコードをいただきました。
先程までの冒険者の気分から一転して文明的な収穫者の気持ちになれます(?)
サイズを見て自動で切り捨てるところまで書けば口を開けていれば壁紙が手に入る,そんな夢(?)のような運用も可能ですね。
以下のスクリプトコマンドプロンプトで実行しましょう。

#!/usr/bin/env python
# coding: UTF-8
import sys
import os
import re
a = 1

files = os.listdir('.')
for file in files:
  os.rename(file, "image%06d.jpg" %(a))
  a+=1

お気に入りの壁紙を探そう!

以上になります。なんか隠されたファイルを探すワクワク感と綺麗な壁紙を掘り出す達成感でなかなか楽しい遊びではないでしょうか。

なお,今回の僕のお気に入りはこれです。
f:id:ossyaritoori:20170606195853p:plain

これらの画像は定期的に何処かでダウンロードされて更新されるので気になる画像が出てきたらこうして掘削してみるのも面白いかもしれません。
それでは。

Kerasで機械学習のモデルの保存と可視化

環境

Python3.5 の仮想環境をWindows64bit上に立てております。
環境が違う人はエラーが起こるかと。

また,基本的なコードはKerasを用います。Kerasの便利さに感動したのでしばらくTensorflowの書き方で書くことはないかも?

今回は気分で参考文献を先に挙げておきます。
www.mathgram.xyz
以下のスライドシェアの記事にはお世話になりました。
Kerasで可視化いろいろ

ここにあるLossの時系列プロットなども気が向いたら書きます。
はじめての Deep Learning - Keras で MLP for MNIST · m0t0k1ch1st0ry


作成したモデルの図示

Kerasで作成したモデルを図示する手法を紹介します。
私の環境はconda-forgeから入れた2.02が標準として使われているようです。

Kerasの設定に関して

Kerasの設定ですが,バックエンドをTensorflowで行います。その際,仮想環境を用いている方は罠にハマりうるので以下の記事に目を通しておいたほうがいいかもしれません。
ossyaritoori.hatenablog.com

モデルの図示のための下準備

vis_utilsのplot_modelというクラスを使います。
なお,こういう名前はバージョンが変わるごとにコロコロ変わっていくので注意が必要です。
少ししたらplot_mdlとかいう名前になっていそう…

pydotとgraphvizという2つのパッケージに依存するのでこいつらを入れて回ります。


パッケージの導入はいつものとおりなのでいろいろすっ飛ばすと
Anacondaの仮想環境上でのパッケージ確認と追加の方法について - 粗大メモ置き場

 conda install --channel https://conda.anaconda.org/conda-forge graphviz

これして

conda install --channel https://conda.anaconda.org/dhirschfeld pydot

こう。後半のpydotは3.5系かつwindwos64に入るものが少なくて掘り当てるのに苦労しました。


ただ,おそらく以下のエラーが出ます。
「Failed to import pydot. You must install pydot and graphviz for `pydotprint` to work.」
ということでこいつらを入れて回ります。

いろいろすっ飛ばすと

 conda install --channel https://conda.anaconda.org/conda-forge graphviz

これして

conda install --channel https://conda.anaconda.org/dhirschfeld pydot

こう。後半のpydotは3.5系かつwindwos64に入るものが少なくて苦労しました。

なお,直すところはまだまだあります^^

実行用コード

実際のコードにおいては,modelを記述した後に,

from keras.utils.vis_utils import plot_model
plot_model(model, to_file='model.png')

とすることでmodelを保存できます。

この際に

module ‘pydot’ has no attribute ‘find_graphviz

というエラーがでるはずです。これは正直古いパッケージを参照している証左なので,以下の手順で直します。

① 該当箇所のコメントアウト
Anaconda3フォルダ配下の"Lib\site-packages\keras\utils"にvisualize_util.pyがあります。このファイルのfind_graphvizを使っている13-15行目を以下のようにコメントアウトしましょう。

#if not pydot.find_graphviz():
#    raise ImportError('Failed to import pydot. You must install pydot'
#                      ' and graphviz for `pydotprint` to work.')

環境変数の追加
Anaconda3フォルダ配下の"Library\bin\graphviz"を環境変数のPATHに追加し、PCを再起動しましょう。
仮想環境で開発をしている場合はすべてenv以下のLibraryを参照するように。

正直このバグは公式で早く直してほしいところです。

以下のサイトが同様の内容についてコメントしています。
【Python】 Kerasでモデルを図に保存する - 旅行好きなソフトエンジニアの備忘録

モデルの図示結果

正直こんだけ頑張ってこれかよ…と思わなくもないですが,一応こんな感じに図が出ます。
f:id:ossyaritoori:20170602005520p:plain


学習した畳み込み層の図示

畳み込みネットワークといえば,層を図示してこういう特徴を学習したと自慢したいですよね。
それ,Kerasで結構楽にできます。

層の出力の結果

なーんかよく見るそれっぽい図です。これが畳み込みネットワークが学習した特徴というやつになります。

1層目 64カーネル
f:id:ossyaritoori:20170601211746p:plain
2層目 32カーネル
f:id:ossyaritoori:20170601212851p:plain

下準備

基本的なmatplotlibなどを用いれば作成できますが,最大値と最小値のスケーリングにおいてsklearnというパッケージを用います。

インストールするのは「scikit-learn」というパッケージです。2017年6月では以下からダウンロード可能です。

 conda install --channel https://conda.anaconda.org/Anaconda-Extras scikit-learn

書き方

以下のように書きます。

layer_num = 0; # 1st convolutional layer
print('Layer Name: {}'.format(model.layers[layer_num].get_config()['name']))
W = model.layers[layer_num].get_weights()[0]

W=W.transpose(3,2,0,1)
nb_filter, nb_channel, nb_row, nb_col = W.shape

#plot
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
plt.figure()
for i in range(nb_filter):
    im = W[i,0]
    # scaling images 
    scaler = MinMaxScaler(feature_range=(0,255))
    im = scaler.fit_transform(im)
    
    plt.subplot(8,8,i+1)
    plt.axis('off')
    plt.imshow(im,cmap='gray')
plt.show()
  • model.layers[x]でx+1番目のレイヤー情報を見れます。
  • その後,get_weightという関数で畳み込み層のカーネルを行列としてWに書き出します。
  • Wは((カーネルサイズ),(入力数,出力数))の4次元なので便宜のために順番を入れ替えます。
  • その後subfigureを開いてカーネルの要素数だけ並べてplotします。

非常に簡単で助かります。

実行コード

今回もMNISTを使って学習をしています。
コードには先程の図示の他,前回扱った各変数の保存なども組み込んでおきました。

このコードがスッキリ動く環境になればわりと何でもできそうです。


書籍

基礎知識をつけるには最低限これは読んでおくと良いでしょう。

KerasやTensorflowに関してはもっと最新情報があるはずですが以下の本でも差し支えはないかと。
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

あと,周りのDeepLearnerはChainer使いが多いです。使ったこと無いけど。
Chainerで学ぶディープラーニング入門

Chainerで学ぶディープラーニング入門

KerasのバックエンドがTheanoから変更できなくなった話

結論

結論から言うと
~\.keras.jsonを見るだけでなく,
keras_activate.batの存在にも注意した方がいいです。

Kerasのバックエンドの変え方

KerasのバックエンドはTheanoかTensorflowか選べます。
中身はたいていユーザ直下の「.keras\keras.json」を弄れば解決します。

公式の通りにやればいいでしょう。
バックエンド - Keras Documentation


ただ,今回ハマった問題としてここを変更したにもかかわらず
backendがTheanoに固定されていた問題に一時間ほど悪戦苦闘しました。

それでもうまくいかない場合

私の場合,仮想環境を立ち上げた際に次のコマンドが出力されていました。
どう見てもデフォルトバックエンドをtheanoに固定しに来ています。
許せん。

\Anaconda3\envs\tf35\etc\conda\activate.d>set "KERAS_BACKEND=theano"

どう見てもこのファイルが怪しいので現地へと調査しにいきました。
f:id:ossyaritoori:20170601225237p:plain

今回インタビューをするのは「keras_activate.bat」さん。
中身を見ると…

set "KERAS_BACKEND=theano"

はいギルティー。

set "KERAS_BACKEND=tensorflow"

上記のように書き換えておきましょう。

Kerasを用いた手書き画像認識Ⅲ:畳み込みネットワークを用いたテストコード

前回までのあらすじ

最初はTensorflowを用いて隠れ層を導入したパーセプトロンにて学習を行いました。
ossyaritoori.hatenablog.com


次に,Kerasを導入して3層のニューラルネットワークで学習を行い,改善を得ました。
ossyaritoori.hatenablog.com

今回は畳み込みニューラルネットワークを試してみましょう。



畳み込みネットワーク(CNN)について

画像の認識などにおいて強力な性能を発揮する手法で、
画像の二次元畳み込み(2D Convolution)計算を層間の伝搬に用いる手法です。
以下のサイトが図が見やすくてわかりやすいでしょう。
postd.cc

最近聞いてきた公演によるとプーリング層や全結合層はなくて,GAP層を用いるのが標準になりつつあるそうですね。

環境の下準備

前回の記事でのKerasパッケージの導入のところをきちんとこなしておいてください。
Tensorflow,Kerasを用いた手書き画像認識:MNISTを使ったテストコード - 粗大メモ置き場

KerasにおけるCNNの実装手法

以下にKerasを用いた際のモデルの生成部を示します。
Denseの代わりにConv2Dという関数で畳み込みの層を決めており,
Kernelのサイズや数などを同時に決定しています。

これだけです。まじかよ超簡単じゃん。

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

流れは,

  • 32カーネル 畳み込み層(ReLu)
  • 64カーネル 畳み込み層(ReLu)
  • プーリング層
  • 128要素の全結合相?
  • 10クラスへの出力層

と言ったところでしょう。


例のごとく他所様からコードをお借りしていますが疑問として,
どうして最初の層が32個のカーネルなのに次の層が64個なんでしょう?
(勉強不足が露呈している)

なんとなく逆の方が良さそうなもんですが何か意味があるんでしょうか。

Kerasを用いたコード

ライブラリとしてKerasをダウンロードしたPC上で動作を確認しています。
実行環境はSpyder3上のIPythonコンソール上で行っています。

詳しい環境については過去記事を漁ってください。


結果:元のコード

数回のEpochを繰り返して精度をブラッシュアップしますが今回は12回目で99%を達成しました。これだけでも十分すごいですが実用上では99.999%より上の性能が求められるようでなんというか大変だなぁ…

Epoch 12/12
60000/60000 [==============================] - 82s - loss: 0.0365 - acc: 0.9887 - val_loss: 0.0289 - val_acc: 0.9901
Test loss: 0.0288566211587
Test accuracy: 0.9901

結果:ちょっと弄ったコード

さっきの畳み込み層の順番を32→64から64→32へと変更してみました。
ほとんど差がありませんね。ただ,かかった時間はこちらのほうが長かったように思います。
確かより「深い層」の方が計算が面倒になるのでそういった事情を考慮して32→64という構造なのかもしれません。

Epoch 12/12
60000/60000 [==============================] - 102s - loss: 0.0450 - acc: 0.9869 - val_loss: 0.0287 - val_acc: 0.9904
Test loss: 0.0286987099324
Test accuracy: 0.9904

後処理

モデルの保存

せっかく作ったモデルですのでもったいないしきちんと保存しましょう。
[TF]KerasでModelとParameterをLoad/Saveする方法 - Qiita

jsonという形式を通してファイルで保存したいとすると,以下のような流れになります。
詳細は今度記事に書きます。pickleというクラスを使います。

import pickle
json_string = model.to_json()
with open('mnistmodel.pickle', 'wb') as f:
    pickle.dump(json_string,f)

学習したパラメータの保存

学習したパラメータは.hdf5という形式で保存されます。

model.save_weights('mnistparam.hdf5')

読み出し方は上のURLを参照してください。個別に記事を書くかもしれません。

可視化

可視化についてはgraphvizやらpydot_ngやらをインストールする必要があるのでまた今度書きます。
以下のサイトが役に立つことでしょう。
www.mathgram.xyz

感想

とりあえず一連の記事をもってMNISTのテストはここらへんで終了ということにしようと思います。感想として複雑な学習をするにはGPUが必須という所感を受けました。

今回のMNISTの学習では大体18分くらいかかっていましたが,コードを書いた人によるとGPUを積んだPCだと大体その1/5弱の3~4分で終えることができるそうです。

これから機械学習を始める人は是非GPUをきちんと積んだPCを使うのが良いでしょう。




Tensorflow,Kerasを用いた手書き画像認識Ⅱ:多層ニューラルネットを用いたテストコード

記事の前提

前回は隠れ層を入れたパーセプトロンを用いて手書き画像の認識を行いました。
ossyaritoori.hatenablog.com

Kerasとは

Python上で動作する深層学習用のライブラリのことです。
TensorflowやTheanoと言ったライブラリを前提にしていて,それらを用いてより高い抽象度で計算を書けるようです。

まぁつまり,「簡単」ってこと!!!(せやろか)

深層学習ライブラリ Keras - 人工知能に関する断創録
Python製深層学習ライブラリ「Keras」の紹介 (with TensorFlow) - amacbee's blog

Kerasの環境構築1

実は,Tensorflow1.0以降を入れている場合はKerasはモジュール?の一部として入っているようです。
今のところこっちで特に問題はなさそうな感じがします。

Kerasの環境構築2

先程とは別の枠組みでKerasのライブラリをインポートして記述することも可能です。
import文が簡単に書ける以外でどう違うのかは今のところわかっていません…

それにはまずKerasパッケージを入れる必要があるので,パッケージインストールの例に習って,
ossyaritoori.hatenablog.com
1.パッケージを探すために以下のコマンドを叩きます。

anaconda search -t conda keras

2.出てきた候補の中でwin64に対応していて,なるべく新しそうなものをチョイスします。2017年5月末ではconda-forgeが良さそうです。
そして以下のコマンドを叩きます。

anaconda show conda-forge/keras

3.最後に2で示されたURLをコピって貼っておしまいです。

 conda install --channel https://conda.anaconda.org/conda-forge keras

Kerasを用いた手書き文字認識 テストコード1

Tensorflowにもとから入っているKerasを用いて実行します。

コード例1

こちらのブログのコードを転用しています。
書き方が公式とちょっと違う気がしているので戸惑うかもしれません。

qiita.com


結果

以下,10000回学習した結果です。
テストの結果認識率は約97%で前回の場合よりも大分改善しました。

Training...
  step, accurary =      0:  0.025
  step, accurary =   1000:  0.910
  step, accurary =   2000:  0.935
  step, accurary =   3000:  0.955
  step, accurary =   4000:  0.940
  step, accurary =   5000:  0.970
  step, accurary =   6000:  0.985
  step, accurary =   7000:  0.965
  step, accurary =   8000:  0.970
  step, accurary =   9000:  0.975
  step, accurary =  10000:  0.980
Test accuracy: 0.9727

考察?

前回のパーセプトロンからの変化として,
多分ノード数と活性化関数が変更になったこと,活性化関数が各層にかかったことがあります。
あとドロップアウトというノードの一部をランダムに無視する手法も用いています,

関連して,学習にかかる時間も精度も大幅に上昇しました。

ドロップアウトの影響

例えばドロップドロップをなくすと次のような結果になります。
あれ?そんな変わらない?ただ,それまでの経過を見るにそれなりには差があるようです。

Training...
  step, accurary =      0:  0.155
  step, accurary =   1000:  0.935
  step, accurary =   2000:  0.915
  step, accurary =   3000:  0.950
  step, accurary =   4000:  0.955
  step, accurary =   5000:  0.945
  step, accurary =   6000:  0.960
  step, accurary =   7000:  0.955
  step, accurary =   8000:  0.970
  step, accurary =   9000:  0.955
  step, accurary =  10000:  0.965
Test accuracy: 0.9726

Kerasを用いた手書き文字認識 テストコード2

Kerasの使用法に関しては公式のDocumentがわかりやすいのでこれを見てください。
Sequentialモデルのガイド - Keras Documentation

tensorflowに組み込まれているKerasライブラリも基本的にこれらと同じ書き方が出来るようですね。

Kerasでのモデルの記述の仕方

非常に直感的な書き方になっていてmodel.addで層を加えていきます。
最初のSequencial()は言わばInitializationで
その後.addで層を入力側から見て加えています。Dence(A,input_shape=B)というのは入力の自由度がBで出力自由度がAということです。

従って入力層と隠れ層は512のノードを格納した配列ということになります。(よね?)
その後Activationで活性化関数を指定しています。前回はシグモイドでしたが,近年の深層学習ではReLu関数が主流のようです(文献1)。

# build model
model = Sequential()
model.add(Dense(512, input_shape=(784, )))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(10))
model.add(Activation('softmax'))

model.summary()

テストコード

先程のブログを参照するとこうなります。


実行の様子

正直結果はそんなに変わらないので,こちらはSpyderの表示を見せます。
f:id:ossyaritoori:20170531200353p:plain

これをずっとやった結果:Test accuracy: 0.9837とやはり98%近い性能を出せました。


今後やってみたいこと

これは結局テストデータを使っているだけなので実際にこの学習器をOpenCV等と連携して
実画像の認識をやってみたいなぁと思います。
思っているだけかもしれませんが。