2016/02/29

[nfc]カードを置いた時間を記録するWindowsアプリ

ここのところ、土日も仕事してしまっている。
平日よりは早めに切り上げているし、少し外出くらいはしているが、どのくらい何をしているのかわからなくなってきた。

そういう話をしていると「うちは作業時間を記録しているよ!」という方が。
なるほど、外勤だとやっていたけど、家の中でもそういうのをやらないと、本当に働いてるのかわからないですな。

というわけで、PC/SCのことを調べていたこともあり、Windows向けに超簡易勤怠管理・・・という名の、単にNFCカードを置いた時間をテキストファイルに出力するアプリを作った。

GoogleDrive/公開用/WorkTime.zip

zipファイルだけど、見えるかな?
うちは、RC-S380/Sと、Windows7 64bitおよびWindows10 32bitで動かしてみた。
起動すると、見つけたNFC R/Wが出てくるので「Watch」というボタンを押すと監視開始(開始すると、ボタン名がカードIDになる)。

image

あとは、R/Wの上にNFCカードを置くと、たぶんNFCIDを取ってきて、取れたらその時間をテキストボックスに出している。
ついでに、同じフォルダにファイル出力もしている(追記するだけ)。
カードが一度抜かれると「NoCard」で記録、違うIDになったらまた記録。
監視は2秒周期。

やっているのは、これだけだ。
私はNFCカードに付箋で「メイン作業」「事務作業」「休み」みたいなのを貼って、そのときに置くようにしている。
IDでわかりにくければ、あとで一括置換すればいいのだ。

なので、勤怠管理ではないですな。
単なる時間記録だけど、まあ、このくらいでいいや。

あ、マイナンバーカードみたいなType-Bだと、置くたびにIDが変わるから今ひとつかも。
カードが1枚しかなくて、「置いた」「置いてない」みたいな使い方もできるから、ご自由にどうぞ。

2016/02/27

[ble][android]BDSのAndroidアプリ (3) - 最終回のような中断

飽きた・・・。

いつかAndroidアプリもやるかも、と思って調べていた分をアップしていたのだが、アプリは専門の人に任せるのがよいと考え始めたのだ。
テストで使う分には、nRF Master Controlアプリで十分すぎる。

次回はPeripheralControlActivityと言ってしまった手前、どういう関数があるかくらいは載せておこう。

image

onRead, onWrite, onNotifyがあるから、この辺をうまいこと変更すればいいのかも。


Androidアプリのコード生成プラグインはNordicとは関係ないから、ATTテーブルだけわかるBLEのPeripheral機器があれば、Androidアプリを作ることができるはず。

まあ、ちょっと、生成されるソースが汚いので、もうちょっとどうにかしてからリリースすればよかったんじゃないのか、とは思う。
自前できれいにしたけど、またすぐリリースされたりして意味が無くなるのだろうなぁ。

2016/02/24

[ble][android]BDSのAndroidアプリ (2)

前回は、AndroidManifest.xmlを見た。
次は、MainActivity.java。

 

ctagsが抽出してくれたメソッドは、これら。

image

一番下のgetView()は、リストにスキャンして見つかったデバイス名を設定している。
ListViewのことを調べたときにやった気がしなくもない。。が、覚えてない。
このときにはListAdapter<>をextendsしていたが、ここではListAdapterのインスタンスを作ってsetAdapter()している。

ListAdapterってなんじゃ、と思ったら、BaseAdapterをextendsしたクラスだった。
さっき「getView()は」と書いたが、メソッド名一覧のListAdapter~getViewまではListAdapterクラスのメソッドだった。

Bluetooth機器制御に使いそうな名前のBluetoothDeviceクラスのインスタンスは、ListAdapterが持っている。
それに設定をするのは、BLEのスキャン結果コールバックであるScanCallback#onScanResult()のようだ。
結果がBluetoothDeviceのインスタンスで渡されるので、それをそのまま設定しているようだ。

 

私が作るんだったら「ListAdapterは名前と、オブジェクトと紐付けるインデックスみたいなのだけ持っておけばいい」って作ってしまいそうだ。
でも、スキャン結果として渡されるBluetoothDeviceも、ListAdapterで持つBluetoothDeviceも、結局ポインタでしかないので、本体はここにないのだ。
だったら、まあいいか、と思ってしまう。

でも、自分で管理してないメモリがあると、なんかもぞもぞしますな。

 

さて、スキャンした結果がリストにずらずら出てくる。
それを1つタップしたときの動作は、onCreate()に定義してある。
タップした位置のBluetoothDeviceをListAdapterから取得して、デバイス名とアドレスを引数にしてPeripheralControlActivityをstartActivity()する。

 

Androidに慣れている人だったら、さらっと見ておしまいなんだろうね。

[ble][android]BDSのAndroidアプリ (1)

まさかの続きだ。
BDSで自動生成したAndroidアプリがどうなっているか見ていく。
あまり見たいわけでもないのだが、記事にでもしないと見ようとしないので。


前回と同じく、com.blogpost.hiro99ma.bdsclient01を例にする。
ソースファイルは、こうなっている。

image

自動生成したときもMainActivity.javaという名前だったから、Android Studioで生成するときもMainActivityにしておいた方が楽だろう。

AndroidManifest.xmlを見ると、こういう感じ。

  • Activity
    • MainActivity
    • PeripheralControlActivity
  • Service
    • BleAdapterService
  • uses-permission
    • BLUETOOTH
    • BLUETOOTH_ADMIN
  • uses-permission-sdk-m
    • ACCESS_COARSE_LOCATION

“sdk-m”?
検索すると、Android-MのPreview版の時がそうだったらしいが、今はsdk-23だとか。
ビルドはできているし、うちのNexus5/7で動いているから、sdk-mでもいけるのか。
(コマンドラインでビルドするとlintエラーになったので、app/build.gradleで回避。)

 

Advertisingしている一覧を出すのがMainActivityで、Characteristicへの操作画面がPeripheralControlActivityであろう。

 

というところで、今日はおしまい。

2016/02/23

[nfc]個人番号カード来たる (昔の私)

何が「昔の私」かというと、昔書いたPaSoRiを動かすライブラリを使って個人番号カードをポーリングしたのだ。

https://github.com/hirokuma/libhknfcrw_c

2013年10月だから、2年半といってもよいかな。
ソースを整理していたら、出てきたのだ。
Cygwinで動くから、LinuxでもMacでも動くだろう。

動かしてみると、カードのあるなしだけじゃなくてレスポンスも解析していて驚いた。
やるな、私!

 

AFI : 00
CRC_B(AID) : 0041
Number of application : e0
Bit_Rate_Capability : b3
FSCI : 8
Protocol_Type : 1
FWI : a
ADC : 0
FO  : 1
[ATTRIB_RES]01

 

だいたいhiro99ma blog: [nfc]個人番号カード来たる (1)と同じ情報が取れているようだ。
InListPassiveTargetするとATRが返ってくるということかな。
だから、PC/SCといえども、R/Wにそういう命令を出しているのではなく、命令を解釈してR/Wがわかる言葉に置き換えているんじゃなかろうか。
実は取説に書かれていない「PC/SCモード」みたいなのがある、なんてことはないと思うのだ、たぶん。

2016/02/20

[ble]Chrome 48のPhysical Web対応はどうなった?

以前、こういう記事を書いた。
hiro99ma blog: [ble]Chrome 48 for Android

Chrome48ではPhysical Webに対応するから、Eddystoneのビーコンを出したら受けとってくれるようになるのかな?と思っていた。

が、48が出た後、そういう記事が出た形跡がない。
私の読み間違えだったのだろうか。。。

 

さっき「chrome eddystone」で検索すると、こういう記事が出てきた。

Chromium Blog: The Physical Web expands to Chrome for Android

2016年2月10日の記事で、version 49になってる。
いまNexus5のChromeを見たが、48.0.2564.95だった。

まだ、待ちのようだ。

2016/02/15

[ble][android]Bluetooth Developer StudioでAndroidアプリ(Client)を作る

Open Live Writerが更新されてtagが入力しやすくなったので、記念にBLE記事を書いておこう。

 

今まで、Bluetooth Developer Studioの記事をいくつか書いたが、どれもnRF51822でPeripheralになるときの話だった。

しかし、Peripheralだけでは世の中が成り立たず、Centralが相手として存在してこそBLEの世界が成立するのだ。
だから、私もCentral側をBlueZで作ったりしたことがあった。

とはいえ、やはりBLEはスマホとお話しすることが多い。
だから、スマホのアプリを作った方が何かと便利がよい。
私はおしゃれなアプリを作ることもないので、とりあえず読み書きしてくれるだけでよい。

 

となると、Bluetooth Developer StudioでAndroidアプリを作る、というのが自然な流れだ。


Android Client Plugin 1.0 (2016/02/15)

これをダウンロードして、解凍して、Bluetooth Developer Studioのpluginsフォルダに放り込む。
うちのWindows7 64bitだと「C:\Program Files (x86)\Bluetooth SIG\Bluetooth Developer Studio\Plugins」だった。

名前の通り、これはClient側のプラグインだ。
今まで作ったのが、nRF51822がServerになるものだったのでちょうどよいのだが、AndroidをServerにする場合には、今回の記事は役に立たないだろう。
すまぬ。

 

注意点は1つ。
NAMESPACEだ。
nRF51822のときには使っていなかったけど、Androidアプリの場合にはこれがアプリのnamespaceと一致するようになっていた。
例えば、BDS側で「com.blogpost.hiro99ma.bdsclient01」という設定にしておくと、Android側でも「com.blogpost.hiro99ma.bdsclient01.MainActivity」のような配置になる。

あとからBDSのNAMESPACEを変更する方法がわからなかったので、私は直接BDSのプロジェクトファイルをテキストエディタで開いて、<namespace>のところだけ書き換えた。
とりあえず、そういうのでもよさそうだ。

そして、BDSで「TOOLS > GENERATE CODE」を選ぶ。
ダイアログが出るが、このときは「Server」になっているので、コンボボックスで「Client」を選ぶ。

image

そうすると、こんな感じでAndroid Client Pluginが出てくるので、選択して生成。


次は、Androidアプリの生成をする。

ここで必要なのは、プロジェクト設定ファイルだけのようだ。
なので、Android Studio(私はv1.5.1を使っている)を起動し、「Start a new Android Studio project」で新規生成し、Company Domainを「bdsclient01.hiro99ma.blogpost.com」として、あとはデフォルトで進めた。

  • Phone and Tablet : API23 : Android 6.0 (Marshmallow)
  • Blank Activity

なお、うちのAndroidはNexus5だ。

 

これで生成すると、画面などが開くが、Projectを閉じる。
開いておいてもいいのかもしれないけど、よくわからんので閉じた。

そして、BDSで生成したファイルに戻る。
この中に「copy_to_android_studio.bat」というファイルがある。
これをコマンドプロンプトで実行すればよいのだが、引数が必要。
その引数は、Android Studioで生成したプロジェクトのルートフォルダだ。
バッチファイルの中を見ると、コメントがあるから何となくわかると思う。

そして実行すると、ファイルがAndroid Studioのプロジェクトにコピーされる。
これで終わり。
あとは、またAndroid Studioに戻って、先ほどのプロジェクトを開く。
そうすると、layoutがどうのと警告が出るが、気にせずMakeしてやると、エラーも出ずにビルドでき、スマホに転送すると動いた。

image

 

「SCAN」を押すと、スキャンする。
対象のものだけ出てくるかは不明だが、そこまでフィルタリングはしないのではないか。

image

 

見つかったデバイス名をタップすると、こういう画面になった。
うむ、これは確かにBDSで作った内容だ。

image

 

CONNECTすれば、読み書きはこれでできそうだ。

まだ、CONNECTからDISCONNECTに戻す方法はわかってないのだけど、ベースがないよりもあった方がよいのだ。
おしゃれじゃない私は、これにボタンとかべたべた貼り付けて、動けばよかろうなのだ。

2016/02/11

[nfc]個人番号カード来たる (5) 最終回

まだ、メールのデジタル署名用に使えないか調べている。

お、何かあるではないか!

image

えい!

image

・・・
世の中、そんなもんだ。

名前の通り「公的個人認証サービス」だから、公的なもの以外では使えないと考えた方がよいのか。
よいのだろうな。

メールって、なんか不安ではないか。
読まれてないんじゃないかとか、出し間違えたんじゃないかとか。
かといって、いきなりSkypeとかSlackとかでやるのも、まだそんな仲じゃないし・・・みたいな間柄ってあると思う。
知り合い以上、顧客未満、みたいな状態だ。

いかんいかん、話が逸れた。
とりあえず、個人番号カードをメールの電子署名に使うのはあきらめよう。


となると、あとは個人番号カードの使い道がない。
e-Taxで今年は確定申告するつもりだから、封筒を郵送する120円が毎年お得になるくらいか。
5年間有効だから、600円くらい得するのかな?
200円で更新だから、それ以後は400円お得になるくらいだ。

 

それで納得いくだろうか?
いや、もうちょっと使いたいというのが人の性だろう。

とりあえず私としては数少ないType-Bなので、基本的な使い方の勉強くらいはできるだろう。
あ、セキュリティを破ったりとか、そういうのは好みじゃないので、何ができるか調べるだけですわ。
まあ、本業の方が忙しいから、そんな暇ないかもしれんけど。

[nfc]個人番号カード来たる (4)

三菱東京UFJ銀行(名前が長い・・・)のメールは、デジタル署名されている。
Thunderbirdだと、ヘッダに封がされた手紙アイコンが出てくる。

image

これをクリックすると、

image

「署名証明書を表示」を押すと、

image

などなど、いろいろ情報が出てくる。
これだと、VeriSignだかSymantecだかが認証局になるのだろうか?

昨日の話からすると、この「署名証明書」は、公開鍵の証明書みたいなものなのだろう。
電子メールだから、ちょっとやり方は違うのかもしれないが、個人番号カードを使って自分のメールに署名できないものだろうか?
そういう方向も今後は調べてみよう。


メールをテキストエディタで見ると、こういうパーティションがあった。

Content-Description: S/MIME Cryptographic Signature

添付ファイル扱いになっていないから、これが証明書の部分なのだろう。
S/MIMEがキーワードか。

S/MIMEとは | SSL・電子証明書ならGMOグローバルサイン
これの「S/MIMEによる電子署名の流れ」の④にある「Aさんが送り主と確認」というのが証明書の役割なのだろう。

でも・・・国の証明書がそういうのに使えるようなしくみを持っていなさそうな気がしてきた。
あるなら、住基カードのときに誰かがやってそうだし。


ちょっと気になって、オフライン状態でさっきのメールの署名証明書を確認したが、特にエラーは出なかった。
つまり、認証局のサーバに問い合わせているわけではないのだ。

Thunderbirdのオプションに「証明書を表示」があるので見てみると、「個人証明書」のタブに東京三菱UFJ銀行のメールがあり、表示させると先ほどの証明書と同じものが見えた。
OSとかメーラとかが、安全な証明書についてはあらかじめダウンロードしてためているということか。

信頼できるかどうかを設定できるので「信頼しない」にしてみると、メールのアイコンがこうなった。

image

おお、信頼してない感じがする!
こうなるのねー。

じゃあ、信頼性を元に戻そうとしたら・・・あ、あれ、証明書がいなくなった。。。
削除していたらインポートすればよいのだろうけど、信頼しなくしているからインポートしても蹴られるのよねぇ。

2016/02/10

[nfc]個人番号カード来たる (3)

「マイナンバーカード」に改名します 総務省、普及狙い:朝日新聞デジタル

そうっすか・・・。
途中で変えるのって、混乱するのよねぇ。
もう「こじばん」とかでいいやん、と思ってしまう。


さて、個人番号カードの使いどころがよくわかっていないが、コンビニで住民票を取れるとか、そういうのがあるようだ。
住民票なんて引っ越しとか役所関係のことじゃない限り取らないのだが、そういうのが取れると言うことはこのカードに何か情報が入っているのだろう。

こういうのを見るのは、総務省のPDFになるんだけど、これがまた数が多くてめんどくさい。
しかも、どれも同じようなページがあって、訳がわからなくなる。

この図は、「公的個人認証サービス利用のための民間事業者向けガイドライン1.1版」から持ってきた。

image image

前の記事で取得したのは、JPKI AP(公的個人認証AP)だ。
ここには、電子証明書が入っているとのこと。

電子証明書というとHTTPSとかを思い出すのだが、ああいう公開鍵とか秘密鍵とか、そういう話だろうか?


予防線を張っておくと、私はこういうセキュリティのことに強くない。
なので、私は調べてこう思う、という記事になるので、みんな自分で調べよう。

総務省|マイナンバー制度とマイナンバーカード|公的個人認証サービスによる電子証明書(民間事業者向け)

ここの真ん中あたりに、電子証明書の使い方の例が出ている。
「署名用電子証明書」と「利用者証明用電子証明書」が別になっている。
たしかに前記事のJPKI利用者ソフトも、証明書の種類を選んで、その次に証明書選択のダイアログが出ていた。

署名用電子証明書は、「署名用」。
説明には「マイナンバーカードに格納する秘密鍵で文書を暗号化」と書いてある。
電子署名は、「この書類は私が書きました! 改ざんもされてません!」ということを示すものだ。

どうやるかというと、署名したい文書を【秘密鍵】で暗号化する(このデータが電子署名)。
【秘密鍵】で暗号化したデータは、秘密鍵で作った【公開鍵】で復号化できる。
なので、文書を作った人は、文書と電子署名をセットで相手に渡す。
相手は正しい【公開鍵】を手に入れ、電子署名を復号化して、文書と一致していれば「ああ、秘密鍵で暗号化した人が作ったのと同じ文章なんだ」と安心できる。

うん、胡散臭い。
これが成り立つには、前提条件がいろいろいるからだ。
でも、ここではそこは省略する。
出てきた話の登場人物は、【秘密鍵】と【公開鍵】。
この【秘密鍵】が個人番号カードに入っているから、電子署名ができるということになってるはず。
【公開鍵】は、【秘密鍵】を持っている人は作ることができるということになっている(逆は、できない)。
たぶん「~なことになっている」が胡散臭く感じるところなのだけど、数学とか何とかいろいろ入ってくるので、賢い人達がよってたかって考えた結果そうなっているのを信用することにしている。
だけど、公開鍵も一緒に渡してしまうと、そのセットをまるまる盗み取って、別の秘密鍵で署名して、その公開鍵を添付してすり替えてしまうと、相手は改ざんに気付かないことになる。
「正しい【公開鍵】を手に入れ」としたのは、その辺を気にしているのだ。

【公開鍵】は公開と名前が付いているだけに、別に公開してしまっても構わない運用になる。
だから、公開鍵だけネットでばらまいてもいいのだけど、そうするとどれがその人の本物の公開鍵かわからなくなってしまう。
なので、公開鍵が添付されていてもネットにあってもよいけど、その公開鍵が正しいものかどうかを誰かが確認してくれるとうれしい。
その確認してくれる人も、かなり信用できる人じゃないと、相手とぐるになってたら意味が無い。

そういう確認してくれる人を【認証局】とか【CA】とか呼んでいる。。。。
だめだ、そろそろ付け焼き刃がはがれてきた。
PKI関連技術に関するコンテンツ
ここの「認証局モデル」というやつだな。
公開鍵が正しいかどうかではなく、公開鍵の所有者を保証してもらう、という考え方のようだ。

それで、ようやくこの図の意味がわかる。

image

左端がユーザが作った文書、真ん中が電子署名、右端のアイコンが公開鍵、青いのが公開鍵の証明書、というわけだ。
文書が改ざんされていないかどうかは、電子署名を公開鍵で復号化して、文書と比較する。
その公開鍵が正しいかどうかは、公開鍵と証明書を認証局に問い合わせる。
ということだろう。

『暗号技術入門』によると、こういう証明のしくみをPKIと呼ぶようだ。
公開鍵基盤。
PKIという名前から、前記事のアプリをJPKIが出していたことを思いだした。
でも、本によると、GPKIというのが出てきた。
JPKIは「公的個人認証サービス」で、GPKIは「政府認証基盤」となっている。
ああ、もうなんだかわからないわ・・・。

こうやって、証明書とかを勉強しようとして、めんどくさくなってやめてしまうんだろう。


そういう人をなるべく気楽にさせようと考えてか、こういうものもあるらしい。
だれだ、お前は!
http://www.soumu.go.jp/kojinbango_card/kojinninshou-01.html#rogo
公的個人認証サービス広報用キャラクター「マイキーくん」の画像

マイキーくんだって。

[nfc]個人番号カード来たる (2)

個人番号カードを取得した目的は、もともとe-Taxを使ってみたいというなのだ。
け、決してType-Bが無料で手に入るとかじゃないぞ。

まずは、電子証明書として確認できるかどうか確認しておこう。
アプリは、ここからダウンロード。

公的個人認証サービス ポータルサイト

image

「自分の証明書」か「認証局の証明書」を選ぶと、こういうダイアログが出てくる。

image

上の方は、アルファベットと数字で決めた方のパスワードだ。
下の方は、数字4桁。数字4桁の方は同じパスワードでも良いよって言われたけど、別の数字にしている人は選ぼう。

パスワードが正しければ、該当する情報が表示される。
「自分の証明書」には、こういう情報が出てきた。

image

発行年月日は、昨日じゃなくて1月だった。
本当に発行した日なんだな、きっと。
発行者は、こちら。
地方公共団体情報システム機構 地方公共団体情報システム機構
マイナンバーのサイトによく出てくる、J-LISというところだ。
なんか、こういうのって、利権だとかなんとかが気にならないでもないが、今回は忘れよう。
建物はここらしい。
一般財団法人 全国町村議員会館
そんなのあるんだ。
議員手帳も600円で買えるようなので、興味がある方はどうぞ。

 

認証局の証明書は、こんなの。
伏せなくてもよい情報である気はするが、まあいいや。

image

 

ふーん。

[nfc]個人番号カード来たる (1)

ばーーん!

image

効果音付きで登場したのは、個人番号カードだ。
私が福岡市民であることはわかると思うので、それ以外は隠した。

なお、グレーになっているところは、福岡市配布の個人番号カードカバーが隠している。
裏も個人番号か書かれているところは隠れている。
さっきわかったけど、裏の左下にあるQRコード、あれは個人番号だ。
これも隠しておいてくれると、さらによかったんだけどね。
マスキングテープがある人は、貼っておくとよいのでは。
私はそういうのがないから、ガムテープを切って貼ったけどね。


前回、IC運転免許証をNexus5にかざしたとき、私のでは認識してくれなかった。
そういうものかと思ったが、どうも反応する人もいるようだ。地域によるのかも。

そして今回のもダメだ・・・と思い込んでいたが、認識した!
NXPのTagInfoアプリで解析してくれるのですよ。
いやぁ、興奮しますな。

TagInfoは一般的な解析情報しか見えないが、一般的な情報なら解析できるのだ。
ならば、見てみるしかないだろう。

 

image

はい、ATRの情報です。
運転免許証の場合は、こちら。

[nfc]PC/SCを試す (5)
image

違うのは、ここだ!

  • Application Data from ATQB : 00-00-41-E0
    • AFI : 0x00
    • AID : 0x00 0x41
    • Number of Application : 0xE0
  • Protocol Info Byte from ATQB : B3-81-A1
    • FWI : Frame Waiting Time Integer : 0xA

 

「ここだ!」と力強く書いてみたが、よくわからん。
まあ、いつものことだ。

FWIはなんかのタイミングだからよしとして、AIDとNoAだ。
AIDは、Application ID。
2byteしかないので、Bluetoothのように共通で管理しているとは思えないが。。。

探していると、こういうのが出てきた。
https://www.jisc.go.jp/newstopics/2000/tp004icc.pdf
が、この資料では、16バイトある。
AIDにもいろいろあるということか。

 

眠たいので、残りはまた。

2016/02/09

[ai]『深層学習』の8章に挫折してCNTKを試す (4)

PCが復旧したので、Simple2dサンプルを動かしてみた。

ログがだーっと出るので、ファイルに保存したい。
リダイレクトしようかと思ったが、標準出力か標準エラー出力かわからんし、混ぜた方が良いのか片方だけがよいのかわからん。

検索すると、stderrというオプションを付けると、そこに書込むらしい。

> cntk configFile=Config/Simple.config currentDirectory=Data stderr=.\log

こうすると、Dataフォルダの中に「log_Simple_Demo_Train_Simple_Demo_Test.log」というファイルができた。
logというフォルダまで作ってやったのに、Dataフォルダの直下にこのファイルができていたのだ。
currentDirectoryでデータフォルダの場所を指定してるけど、これはconfigファイルに書いているパスがそうなっているからだろうか。

細かいことだが、今のgithubに上がっている設定ファイルは、Simple.configではなくSimple.cntkになっている。
「CNTKBook-20160121.pdf」という説明っぽいファイルもconfigになっているので、注意しよう。
まあ、エラーが出るだけなんだけど。

 

ログの見方はよくわからんが、最初の半分くらいはSimple.configの中身を展開したもののようだ。
なんというか、コンパイル前のプリプロセスみたいな感じで、デフォルト値などが見えるようになったのかもしれない。
「>>>>>>>>>」がセクションの開始で、「<<<<<<<<<<」が終わりなのだろう。

  • RAW CONFIG (VARIABLES NOT RESOLVED
  • RAW CONFIG WITH ALL VARIABLES RESOLVED
  • PROCESSED CONFIG WITH ALL VARIABLES RESOLVED

ここまでが展開部分かな。
「SimpleNetworkBuilder Using CPU」などと出ているから、あれだけ苦労してインストールしたCUDAを使ってくれていないということか。
configファイルに「deviceId = -1」という行があり、コメントに「-1だとCPU」と書いてあるから、そうなのだろう。
”auto”とかにしておけば、勝手に使ってくれるのかもしれない。

ここから先は「Validating」のログがわーっと書いてあるのだが、さっぱりわからん。
一番最後に、結果らしきものがあるのだけど・・・これも見方がわからん。
「レコードが603見つかった」とあり、DataTest.txtも603行だから、これはそうなのだろう。

Minibatch[1-1]: Samples Seen = 603    EvalErrorPrediction: ErrorPrediction/Sample = 0.04145937    CrossEntropyWithSoftmax: CrossEntropyWithSoftmax/Sample = 0.096707169   

Final Results: Minibatch[1-1]: Samples Seen = 603    EvalErrorPrediction: ErrorPrediction/Sample = 0.04145937    CrossEntropyWithSoftmax: CrossEntropyWithSoftmax/Sample = 0.096707169    Perplexity = 1.1015378   

まだブログエディタが整ってなくて、こういうログが載せづらい。。。
Final Results、とわざわざ書いてあるから、下の方が最終結果なのだろう。
これが、0.99とかそういう値があったら「あ、99%は正解してるんだ」などと想像できるのだけど、0.04とか0.09、1.10とかになるとそういう意味じゃないんだろう、くらいはわかる。
あー、でも誤認識が9.6%とかだったら、まだわかるかも。

きっと、境界線付近の座標は正解率が悪くて、離れていくほど高くなっていくに違いない。
・・・とロジックで組んでるのだったら思うのだけど、どうなのかな?

https://github.com/Microsoft/CNTK/blob/master/Examples/Other/Simple2d/AdditionalFiles/SimpleDemoOutputReference.png

この画像が、たぶん結果をグラフにしたものなのだろうけど、色見本の見方がわからん。
+25~-30くらいだけど、単位がないとねぇ。

画像はさっきのPDFのFigure 1.2と同じもの。
「Trained output values over the region of interest for the first (of two) output neurons」
「ROIをトレーニングした出力値」というのはなんとなくわからんでもないが、「最初の2つのニューロンの出力」は何だろう?
”output neurons”は、出力ノードのことか?
文章の方に「optimized output (before sigmoid) of one of the two output nodes」とあるから、そういう気がする。

 

が、今日はもう寝よう。

2016/02/07

[ai]『深層学習』の8章に挫折してCNTKを試す (3)

Simple2dがどういうサンプルなのか気になってきた・・・。
まだメインPCのバックアップ処理などやっているので、調査を続けておこう。

https://github.com/Microsoft/CNTK/blob/master/Examples/Other/Simple2d/Config/Simple.cntk
L.29~30にこういうコメントがある。

# Notation xxx:yyy*n:zzz is equivalent to xxx, then yyy repeated n times, then zzz
# Example: 10:20*3:5 is equivalent to 10:20:20:20:5

???

xxx = 10
yyy = 20
n = 3
zzz = 5

というのは、わかる。
「xxx:yyy*n:zzz」が「xxx, then yyy repeated n times, then zzz」というのもわかる。
「10:20*3:zzz」が「10:20:20:20:5」というのまでわかる。
しかし、この「10:20:20:20:5」って、なんだ?
これがSimple2dなのか??

 

そういえば、AdditionalFilesにMATLABのファイルがある。
https://github.com/Microsoft/CNTK/blob/master/Examples/Other/Simple2d/AdditionalFiles/MakeData.m
これで訓練データなりテストデータなりを作成しているようだ。

L.27にファイル出力部分があり、3列のうちの最初2つが(x, y)座標、3列目がlabelになっている。
座標(x, y)の値は-1.0~+1.0の乱数。
labelはsin波を元にしていて、imageという式らしい。
Excelで左辺をグラフにした。

image

この線よりyが下にあれば条件を満たす。
例えばx=0のとき、yが0より小さければ真、0以上なら偽となる。
yが-0.25より小さければ必ず真だし、yが+0.25以上ならば必ず偽だ。
まあ、左右対称だから、確率として半々なのかな。
たぶん、真=1、偽=0というラベルだろう。

こういう式で表せるものは、当然ロジックで評価できて、結果も100%にできる。
だから、機械学習の結果を判断しやすいのだろう。

 

ああ、そういえばこの式とコメントの関係はわからないままだ。
たぶん、データについてのコメントじゃなくて、ネットワークについてのコメントなんだろう。
だから、まだわからなくて大丈夫だ。

[ai]『深層学習』の8章に挫折してCNTKを試す (2)

今日はメインPCの復旧処理をやっているので、今回はCNTKについて調べるだけだ。

前回、MicrosoftのCNTKを入れてみて、CaffeでやったことのあるMNISTのサンプルがあったので動かして、「で?」で終わってしまった。
CNTKのインストールで注意するところだけわかった。

  • WindowsかLinux
  • どちらも64bitのみ
  • Windowsは、ビルドするなら英語localeがよいらしい(試してない)
  • [win]ビルド済みを使うなら、CUDAバージョンはファイル名を見よう


前回わからなかった、あの実行結果をどうしてよいのかを調べたい。
ただ、何をキーワードにしてよいのかもわからない。。。

日本語でCNTKを動かしている人を探していると、ようやく見つかった。
CNTKのチュートリアル(MNIST)の読み解きに挑戦 - FPGA開発日記
そうそう、こういう「使ってみました」を探していたんです。

この方も「全然面白くないよ!」と書かれているから、やり方は間違ってなかったようだ。
ただ、結果はlogファイルに入ってたんだな・・・気付かなかった。
いまはPCが使えないので、あとで見ることにする。

そして、Simple2dのように出力を出すように変更なされてる。
Wikiにも一番上にあったのだが、Others/Simple2dと「その他」みたいな扱いだったのでスルーしたのだ。
順番にも意味があったのか・・・。


Simped2dサンプル

MNISTはpythonでデータ取得から始めていたが、Simple2dのデータは既にDataフォルダに入っているとのこと。
見てみると、txtファイルが3つある。
SimpleDataTest.txtとSimpleDataTrain.txtは3列のデータがだーっと入っている。
SimpleMapping.txtは、0と1と書いてある行があるだけ。

Trainは訓練用、Testは評価用だろう。
3列のデータも、(x, y) = z、みたいなことじゃなかろうか。
本来は、Test.txtの3列目はないのだろうけど、正答率を計算するために付いてるだけだと思う。
だって、ニューラルネットだろうとなんだろうと、自分が判定した結果が正しかったかどうかを自分で知る方法はないのだ。
人間が自分の意見が正しいのかどうかを考えるため他の人の意見を聞くように、誰かに頼るしかない。
そして聞いた中の意見で一番多いものを採用する、くらいしかやりようがない。
「でもやっぱり自分はこう思う!」という意見を貫きにくいだろうな、やつらは。


なので、当たり前だけど、機械学習が正しく学習するためには、正しい結果を教え続ける、少なくとも正しい結果が間違った結果を上回るようにしないといけない。
間違ったことだけ教えていたら、その学習結果は間違った方に進んでしまい、正しい結果を受け入れなくなってくるんじゃなかろうか。

Train.txtは正しい結果という前提の元、Test.txtが評価されることになる。
なので、悪意でTrain.txtが正しくない結果だった場合、Test.txtは正しくない評価をされることになる。
今は、機械学習は「当てにならないもの」という前提の世界だからよいけど、もし機械学習が正しい前提の世界になったら、ロジックで生み出された結果ではないため、混乱するだろうな。
そういう意味では、判定がロジックで評価できるしくみとセットになっていた方が安全だと思う。

いかんいかん、脱線してしまった。
だけど、ロジックで作っていない動作が不安な理由って、制御ができないことだと思う。
もしロジックで作った部分と併用して、機械学習の結果がロジックと異なった場合に拒否させようとしても、ロジックの方が「異なる」と判定できないんじゃなかろうか。
そもそも、ロジックでそういうのが出せないから、機械学習させようとしてるのだと思うし。

今は「よくできましたね~」という子供の成長を見てるようなレベルだからいいけど、盲目的に信用できるくらいになったらそういう心配もしないといかんでしょうな。


脱線続きだ。。。

Simple2dのReadmeでは、Simple.cntkをconfigファイルとして動かすように書かれている。
このconfigファイルが、ニューラルネットのネットワーク構成だろう。
文法はわからんが、以下の3つがある。

  • Simple_Demo_Train
  • Simple_Demo_Test
  • Simple_Demo_Output

これを、L.15のcommandで指定して実行しているのだろう。
Outputはcommandに入ってないから、これは実行されないのかな。

 

SimpleNetworkBuilderがネットワークのテンプレートみたいなものなのかな。
読んでわかる単語は”Sigmoid”くらいだ。
シグモイド関数は、ロジスティック関数とも呼び、活性化関数としてよく使われるもの(『深層学習』p.10)。
活性化関数は、ユニットの出力(『深層学習』p.8)。
コメントに、inputが2つ、50要素の隠れたものが2つ(50シグモイドノードの隠しレイヤーが2つ)、outputが2つ、と書いてある。
隠しレイヤー(hidden layer)は、中間レイヤー(internal layer)のこと(『深層学習』p.12)。

”Softmax”という単語も覚えている。
結果がクラスごとの比率になっていて、「このクラスに属する可能性が一番高い」みたいな目安になる関数だ(『深層学習』p.19)。
円グラフみたいなもんだな。
これがtrainingCriterionだから、訓練時の判断基準ということだろう。

もう1つevalCriterionがあるが、違いは何だろうか?
そのまま訳すと、評価での判断基準となりそうだが、trainingCriterionと同じ気がしてしまう。
https://github.com/Microsoft/CNTK/wiki/Simple-Network-Builder
Simple.cntkでは”ErrorPrediction”が設定してある。
predictionは「予言」だから・・・エラーが起こりますぞ(ムック風)?
値の選択はtrainingCriterionと同じ、と書いてあるが、trainingCriterionの説明にはErrorPredictionは出てきていない。
https://github.com/Microsoft/CNTK/blob/master/Documentation/Documents/Network%20Description%20Language.md#error-prediction
こっちだと、ErrorPrediction()という関数があるように見える。
ということで、さっきのtrainingCriterionでの”CrossEntropyWithSoftmax”も、evelCriterionの”ErrorPrediction”も、関数名が書いてあるだけということか。
Googleで「prediction error」で検索していると「予測誤差法」という言葉が出てきた。
prediction error methodの意味 - 英和辞典 Weblio辞書
『深層学習』p.15に「誤差関数(error function)」とあるから、これと同じ意味だろうか。

 

もう1つ、SGDというものがある。
インストールするときに別途やらんといかんかったやつだ(1-bit SGD)。
Stochastic Gradient Descentの略。
確率的勾配降下法 - 機械学習の「朱鷺の杜Wiki」
これは『深層学習』p.23で章を割いてまで説明してあるやつだ。
順伝播型ネットワークの教師あり学習の方法の1つで、ディープラーニングでよく使われているらしい。
パラメータを見てもわからんが、minibatchは『深層学習』p.26に出てくる。
一度に処理すると大変なので小分けしましょう、ということだと思っている。
他のパラメータもPerMBとあるので、MiniBatch単位であれするこれする、ということなのだろう。

 

readerは、TestにもOutputにもあるが、データファイルの読み込みだろう。
TrainではTrain.txt、TestではTest.txt、OutputでもTest.txtを指定している。
前回のMINISTサンプルでは、Output/Modelsに01_OneHidden.xxというファイルが多数できていたが、それはOutputのoutputPathに書くようだ。
50Elementsだから、50ファイルできるのかな?

TestとOutputは、そのoutputPath以外は同じ設定値だ。
L.15のcommandではTraingとTestだけになってるけど、TestをOutputに置き換えるとファイルができるのか。

 

それで、そもそもこのサンプルがどういうものなのかは、先ほどの方が読もうとされている。
CNTKのチュートリアル(Simple2d)の読み解きに挑戦 - FPGA開発日記
CNTKのSimple2dに対して別のデータセットを与えて特徴を掴む(はずが謎が深まる) - FPGA開発日記

まだ私は理解がついて行ってないので、そういうのは次回以降で。。。

2016/02/04

[esp8266]気になっていることを確認(don’t use rtcとリンクサイズ)

ESP8266で、気になっていることを確認しておく。

確認したバージョンは、Non-OSのV1.5.2だ。


”don’t use rtc mem data”は私が原因なのか?

起動すると「don't use rtc mem data」というメッセージがコンソールに出てくる。
直訳したら「RTCメモリデータは使うな」だけど、何だかよくわからない。
前回は「なんだったんだ」で終わらせたけど、もう少し見ておく。

 

以前書いたHello Worldに、少し出力を追加した。
https://github.com/hirokuma/esp8266_helloworld/commit/fb870850fd9d9468e119e7b928055826525ecff6
user_rf_pre_init()とuser_init()で出して、どこら辺で出ているのかを確認する。

image

通信速度があっていないところは文字化けしているが、こちらで出しているコンソールログは化けてない。
これを見ると、user_rf_pre_init()とuser_init()の間で出していることがわかる。
なので、実装した箇所で出力する可能性があるのはuart_init()だけど、user_rf_pre_init()では出てないので違うと思う。
思うが、確認したい。。。
起動時が74880bpsなんて変な速度でさえなければ。。。

うちのPC環境では74880bpsを受け取れないので、ロジアナで見た。
uart_init()をコメントアウトして実行だ。
ブログエディタのプラグインがまだ使えないので、ログが見づらいが許しておくれ。


ets Jan  8 2013,rst cause:2, boot mode:(3,6)
load 0x40100000, len 1856, room 16
tail 0
chksum 0x63
load 0x3ffe8000, len 776, room 8
tail 0
chksum 0x02
load 0x3ffe8310, len 552, room 8
tail 0
chksum 0x79
csum 0x79

2nd boot version : 1.5
SPI Speed      : 40MHz
SPI Mode       : QIO
SPI Flash Size & Map: 32Mbit(1024KB+1024KB)

jump to run user1 @ 1000
       VsXX OY F   

SDK ver: 1.5.2(80914727) compiled @ Jan 29 2016 17:26:12
phy ver: 484, pp ver: 9.6

user_init

ets Jan  8 2013,rst cause:2, boot mode:(3,7)
load 0x40100000, len 1856, room 16
tail 0
chksum 0x63
load 0x3ffe8000, len 776, room 8
tail 0
chksum 0x02
load 0x3ffe8310, len 552, room 8
tail 0
chksum 0x79
csum 0x79

2nd boot version : 1.5
SPI Speed      : 40MHz
SPI Mode       : QIO
SPI Flash Size & Map: 32Mbit(1024KB+1024KB)

jump to run user1 @ 1000
       VsXX OY F VY1 P  S !     

SDK ver: 1.5.2(80914727) compiled @ Jan 29 2016 17:26:12  
phy ver: 484, pp ver: 9.6

user_init

赤文字は、こちらがログ出力させている文字列。
あれ・・・don’t useも出てないが、user_rf_pre_init()も出てない。

また、最近なのかどうかわからないが、リセットが2回走ってから起動しているのが気になる。
boot modeの出力が2回あるが、最初は(3, 6)、次は(3, 7)。
Causeとboot modeはこういうことらしいので、リセットピンでリセットして、起動デバイスはFLASHということだろう。
http://www.esp8266.com/viewtopic.php?p=2096#p2112
最後の6とか7とかが、わからないままだ。

よくわからないので、user_rf_pre_init()を空実装にすると、boot mode(3, 7)だけだ。
うまく説明できないが、user_rf_pre_init()に実装を置くのは良くない感触だ。
また調べるかもしれないが、今回はここまでにしておこう。

あ、user_rf_pre_init()を空実装にして、user_init()でuart_init()を呼ぶようにしたら”don’t use rtc” が出るようになった。
くっ・・・気になるが、今回はここまでだ。

 

リンクサイズ

Makefileに、-lsslだの-lsmartconfigだの入っているが、使ってないので、バイナリに影響が出てるのかどうかを確認する。
こっちはビルドするだけだ。
中身はあまりチェックせず、sizeコマンドで大きさだけ見てみる。

IoT_Demoと同じ構成でビルド。


size .output/eagle/debug/image/eagle.app.v6.out
   text	   data	    bss	    dec	    hex	filename
 215206	    884	  25184	 241274	  3ae7a	.output/eagle/debug/image/eagle.app.v6.out


以下をコメントアウトしてビルド。

#    -lupgrade\
#    -lssl    \
#    -lpwm    \
#    -lsmartconfig \


size .output/eagle/debug/image/eagle.app.v6.out
   text	   data	    bss	    dec	    hex	filename
 215206	    884	  25184	 241274	  3ae7a	.output/eagle/debug/image/eagle.app.v6.out

同じやね。

2016/02/03

[esp8266]user_rf_pre_init()は処理するところじゃないな

user_rf_pre_init()は、user_init()より前に呼ばれている。
じゃあ、UARTの速度変更とか、リセット原因の出力のようなあまり本体に関わらない処理をそこに置いておくと、user_init()が呼ばれたときにはさっぱりした状態で始められそうだ。

そう思って、ずっとそう実装していた。
まず最初にわかったのは、UARTの速度変更をしても、user_init()が呼ばれたときにはまた元に戻っているということだ。
まあ、そういうものかと思って、あまり気にしなかった。

リセット原因は、いつやってもREASON_DEFAULT_RSTしか取れなかったので「使えねぇなあ」と、これはこれであまり気にしていなかった。
どうみてもWDTでリセットがかかっているシーンだったけど、そういうものなんだ、と気にしてなかったのだ。

 

が、なんとなくuser_rf_pre_init()に書いていた処理を、全部user_init()に移動させると・・・リセット原因がちゃんと取得できてるじゃないか!
リセットボタンを押したときのしか見てないけど、REASON_EXT_SYS_RSTが返ってきている。

いやあ、今年一番の驚きでしたよ。
みんなも、気をつけようね。


もう1つ気付いたのは、FLASHを焼くとき、ESP8266のTXはUART1でも焼けそうだということ。
まあ、これはうちにあるあれこれつなげた基板でしか動かしてないから、他でもそうなのか知らんけどね。