頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


macOSアプリでSave Asができない

最近、macOSアプリ(リリース目的ではなく自分専用だけど)を作ろうかなと勉強してる。

ざっと調べるとドキュメント・ベース・アプリケーションなるものがあって、それでエディターっぽいのを作るのがHello Worldみたいなもんらしい。知らんけど。

プロジェクトでDoc Base Appにチェック

↑プロジェクトの新規作成時に Create Document-Based Application にチェックすれば必要なクラスのサブクラスとか用意してくれる。

storyboardのviewに Text View を貼り付けてやる。
Documentクラス(NSDocumentのサブクラス、Xcodeが作ってくれてる)にすでにある以下のメソッドに必要な処理を書けば、ファイルの読み込み、保存ができる。

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError;
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError;


ところが、どういうわけか Save as ができない。

storyboardではSave As

↑storyboard上だとSave Asになってるのに、

実行時はDuplicate

↑実行時にはDuplicateになってる。



なんぞや?と調べた結果、アプリのTarget設定のCapabilitiesってところにApp SandboxってのがあってここのFile accessがデフォでRead Onlyになってる。

Read Onlyを変更する

ここをRead/Writeに変えたら期待通りDuplicateじゃなくSave Asになり、処理もできるようになった。そういうことだったのね、、、



macOS Sierra 10.12.6(ええ、まだSierraですねん)
Xcode 9.0.1
スポンサーサイト






Depth APIで部屋の奥の方を消してみた

iOS 11で公開された深度に絡むAPI、いわゆるDepth APIで遊んでみた。

Capturing Depth in iPhone Photography - WWDC 2017 - Videos - Apple Developer
↑これね。

サンプルコードのAVCamPhotoFilterのシェーダー部分をいじって、遠い部分を黒く塗りつぶすようにして部屋を撮影したのがこちら。

↑デバイスはiPhone 7 Plus。
なかなかしんどいですねえ、、、相当負荷が高い処理なんだろうな。

Supported Depth Resolutions for Streaming

↑上記のWWDCの動画内でこのようにリアルタイム(ストリーミング)だと320x180@24 fpsのデータが得られるとか(画像クリックで拡大)。案外小さいデータなんだな、とか思ってたんだが、、、それだけ処理が大変ってことか。

Depth APIとARKit使えば近くの人物などはそのまま表示し、周りの背景を描画したものに差し替えるような動画ができるんじゃね?とか思ってたけどこの様子じゃそれどころじゃなさそう。


機械学習におけるデータの範囲(2)

機械学習におけるデータの範囲
↑の続き。データの範囲はどうしても0から1じゃないとダメなのか問題。オチもよくわからないってことなんだがやったこと書いとく。

簡単化するためMNISTで同じようなことをやって確認してみた。ちなみに畳み込みのある方のMNIST。
これも自分でtfrecord形式のデータを作成してて、読み込む時は画像データ(輝度)の値を
tf.uint8
で得ている。8ビットの符号なし整数だから0から255。
image = tf.cast(image, tf.float32)
image /= 255.0
という感じでfloatにキャストしといてから255で割って、0から1.0になるようにしてる。当然これはちゃんと学習が進む。

輝度の確認

↑元画像はこんなので明るい部分はをチェックすると0.99近い。
なのでさっきのを
image /= 128.0 # 255.0
って書き換えたら0から2.0くらいになる。
試しにこれでやってみると、、、ちゃんと学習が進んだ!
image /= 85.0
これだと0から3.0くらいなんだが、、、学習が進むことも落ちることもあった。
データファイルの順番、バッチ作成時にランダムになるようにしてるから毎回同じってわけでは決してないので、たまたまいけることもあればたまたまダメなこともあるってことで、そこはええねん。

落ちる時のエラーメッセージにはこんなのが。
Nan in summary histogram for: conv2/weights_0

これってTensorBoardで必要なデータを出力する時の話?と思ってその辺りを消して実行すると、落ちずに処理は進むんだけど、cross entropyがずっとNanのままだった。
損失関数が発散するような場合には学習率を変えればうまくいったことがあったが、今回は全然効果なし。

ちなみに
(1)image /= 255.0(0から1.0)の場合
(2)image /= 85.0(0から3.0)で処理ができた場合
それぞれでTensorBoardのDistibutionを比較するとweight,biasの分布はさほど変わらずだけど、初期の勾配が大きくなっている。

TensorBoardによる係数の分布1

↑こちらは(1)の方。

TensorBoardによる係数の分布2

↑こちらは(2)の方。

けどこの程度で問題になるんかな?
数学的には別に0から1じゃなくてもいけるんだけど、コンピュータの処理上でどこかでオーバーフローでもやってるんだろうか?


カメラで得た画像にVision frameworkを使う

Vision.frameworkをObjective-Cでやってみた
↑この続き。

どうなんだろうな?と思って確認すると、顔画像が90度回転してたり上下逆さまだと認識しないっぽい。

横向きだと検出しない

これで何が困るかというとiPhoneのカメラから得られる画像を回転を意識せずにUIImageViewで表示すると横向きになる(デバイスの姿勢はportrait)のでカメラから得たデータを回転させる必要がある。Vision frameworkの顔認識処理に渡すのはCGImageなのでここから回転させないと具合悪い。
いろいろと調べて試してみた結果、
Ios rotate, filter video stream in ios - Stack Overflow
↑ここにあるコードを使うと意図通り回転させることができた。


↑これでカメラで得た画像に対して顔検出処理ができるとこまでOK。


↑iPhone 7 Plusのフロントカメラでリアルタイムでやってみたが、、、
顔検出処理に200msecほど必要だと測定してたから追従性はこんなもんだろうとは思っていたが、、、問題は期待ほど精度が高くないこと。顔の向きや光の具合でとんでもない判定が出ることが多い。それから動画にはないけどいわゆる変顔みたいな表情も苦手の様子。
リアルタイムではなくてもいいので正確に表情を検出したかったんだけど、これじゃ使えない感じ。ただ、こういう機械学習モノはどんどん精度が上がっていくだろうし、瞳が取得できない不具合も修正はされていくだろうから時々チェックするようにせねば。


機械学習におけるデータの範囲

最近またTensorFlowをいじってる。やったことメモ。

機械学習(TensorFlow)で位置計測っぽいことをやってみた
↑以前こういうのをやったんだけど、これを使って思い出しがてら気になってたデータの範囲について二つ確認。
1つは正解のラベルについて、もう一つは画像のデータについて。

(1)正解のラベル
この時は正解が無次元化された円の座標と半径で学習してる。座標は-1から1で半径は0超から0.5。この正解を得ようというネットワーク(CNN)だったんだが、この正解が無次元化されてなくてもいけんの?というのを確認しようとした。
座標が0から64.0の値を取る場合だと学習がうまく進まなかったので最後の出力層部分のコードをよくよく見ると、

y_conv=tf.nn.tanh(tf.matmul(h_fc2, W_fc3) + b_fc3

となってた。tan(θ)ってことは、-π/2 , π/2で発散するから-π/2 〜π/2の範囲を超えてるからか?ってことでtanhをreluに変えたらいけた。


(2)画像のデータ
画像のデータは0から1.0の値を取るとしてるんだけど、これが0〜255.0のfloatでもいいんじゃないの?といろいろと試してみたんだけど、結果から言うとなぜかできんかった。0〜2.0でもダメ。

tf.image.random_brightness(image, max_delta=0.4)
tf.image.random_contrast(image, lower=0.6, upper=1.4)

といった画像数水増し処理を特に考えず(作った時はどこかでサンプルを見つけたんだろうね)入れてたけど、これよく見ると場合によっては1.0を超えると思うんだ(すでにimageはtf.float32にキャストしてる)。もしかして今まではたまたま学習が進んだけど、実は悪さしてんじゃね?ってことで

tf.clip_by_value(image , 0.0 , 1.0 )

と言うclampと同じ処理を入れてみた。すると、どうよ。学習の進み具合がよくなってるやん!
不思議や。NNの処理をいくら見ても0〜1の範囲を超えるとまずそうな部分は俺には見つけられんのだが。いつか気付いたら追記するわ。









Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.