頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


macOSでバインドを使いテーブルを表示する

macOSでテーブルを表示させようとした。
NSTableViewDelegate、NSTableViewDataSourceを使わずにバインドを使う。
NSArrayControllerで検索するといろいろと参考ページが見つかると思う。

この方法は以前Objective-Cでやったことがあったのだが、今回はSwiftでやろうとしたらえらくはまってしまった。はまりすぎて、俺の理解がおかしいのか?とObjective-Cに戻ってまで確認したりもした。

YamaguchiTatsuya/NSTableViewWithBindings: Simple sample code for macOS, to show table view with bindings
↑とりあえず最小限のサンプルコードをGitHubで公開してみた。


NSArrayControllerをドラッグ&ドロップする

↑Interface builderでViewControllerにArrayControllerを追加(矢印のようにドラッグ&ドロップ)。

NSArrayController追加後の画面

↑ここに見えるので、これを選択して
1. outletを接続
2. Content ArrayをViewControllerのpropsArrayに設定

すると、ViewController内の以下のコードのように
        let tp1 = TableProps(name: "apple")
let tp2 = TableProps(name: "banana")
let tp3 = TableProps(name: "chocolate")

assert(arrayController != nil, "arrayController is nil")

arrayController?.addObject(tp1)
arrayController?.addObject(tp2)
arrayController?.addObject(tp3)

for tp in propsArray {
print(tp.name)
}

↑arrayControllerにデータを突っ込んだ直後にpropsArrayの中身を確認すると、ちゃんと表示されている!バインディングすげー!って感心しました。


テーブルで表示するには他にもテーブル周りでバインドを設定する必要がありますがサンプルコードでご確認ください。


なお、結局Objective-Cで動いたのにSwiftで動かず、
this class is not key value coding-compliant for the key name.
といったエラーばかり出てたのは、TablePropsクラスで@objc dynamic というのが必要だったためのようでした。

//var name: String = “” 実行時エラー
@objc dynamic var name: String = “”


Version
Swift 5.1.3
スポンサーサイト






独自ファイル形式のDocument Based Applicationのサンプルコード

macOSのDocument Based Applicationの公式サンプルコードの謎
↑この続き。

AppleのサンプルコードやXcodeのデフォルトのプロジェクトではファイルを.txtファイルとして保存・読み込みする。
実際にmacOSのdocument based applicationを作成する場合にStringオブジェクトだけ扱う、なんてことはなく、様々な型のデータを扱うことになる。
そういう場合のコードを作成し、サンプルコードをGitHubで公開してみた。

YamaguchiTatsuya/DocumentBasedAppWithOwnExtension: macOS sample code for document-based application for own extension

↑こちらで適当なところから git clone https… とかで見ることができるはず。

textの場合と異なるのはContextクラスをNSSecureCodingプロトコルに準拠するようにした、というくらいか。


macOSのDocument Based Applicationの公式サンプルコードの謎

macOSアプリの話です。iOSではありません。

XcodeでmacOSアプリのプロジェクト作成時の画面で、”Create Document-Based Application”のところにチェックするとそれ用のテンプレで新しいプロジェクトが作成される。
これをベースに自分が作りたいようにごにょごにょしていくものの、クラス間の参照関係だとかがイマイチよくわからない。実際作ってはみたものの、何だか動きがおかしい、、、
ということがあったので、再度調べてみたら、公式のサンプルコードがあることに気付いた。

Developing a Document-Based App | Apple Developer Documentation

↑これを動かしてみたんだが、、、確かに動く。でも、コードがなんか不思議だ。

ViewController内に下のようなコードがある。
    weak var document: Document? {
if let docRepresentedObject = representedObject as? Document {
return docRepresentedObject
}
return nil
}
Documentクラスのオブジェクトを得ているように見える。
ViewControllerのrepresentedObjectから参照を得ているけどそもそもDocumentクラス内でViewControllerのrepresentedObjectにはContentクラスのオブジェクトを入れてる。
それじゃあこのdocumentには値は入らないんじゃないのと思って調べるとやはりdocumentは常にnil、、、
document?.objectDidBeginEditing(self)
とかやってるけど意味ないのでは、、、?
何か見落としているのだろうか?んー、謎だ。


機械学習で画像認識ができていなかった

KerasのImageDataGeneratorで画像データの水増し
↑この続き。
結局4chで画像データを水増しして学習をやり直すことにした。

Kerasで再度学習し直し、macOSアプリのMetal Performance Shadersで同じ入力なら同じ計算結果になることを確認した。

次に動画ファイルで”Excellent!”の文字がありそうな付近で予測結果がどのようになるか確認する。

↓その結果がこちら。動画から1/30秒ごとに中心付近の画像を得てMPSに渡して予測した。

予測結果1

↑画像下の数字が”Excellent!”の文字がある確率(Softmax関数で「ある」の場合の出力値なので)。
この値を見ると、うっすら表示している場合は値が低く、はっきり見えるのは1.0となっている。
6コマ目が豪快に間違えているが、まあなんとか使えるかな、、、

と思っていたのだが、他の動画で確認してみると、、、

予測結果2

予測結果3

↑どちらも全く"Excellent!"が出ていないのに1に近い値を出してる。なんか違うところで判定してそう。
これは使えない。

冷静に考えれば、二択とは言え学習用の画像データは1,302枚だもの、、、少ない。元はCreateML(転移学習)用で準備してたからな。うーん、考え直さねば。


KerasのImageDataGeneratorで画像データの水増し

3チャンネル画像だとKerasとMPSの計算が合わない
↑この続き。
Kerasで学習のやり直しをすることに。せっかくなので画像データの水増しを試してみた。
TensorFlowでも画像データを増やせる関数などがあったがKerasにもImageDataGeneratorというものがあるようで取り入れてみた。

画像の前処理 - Keras Documentation
↑公式はこちら。

修正部分はこんな感じ↓
from keras.preprocessing.image import ImageDataGenerator

datagen = ImageDataGenerator(
                             rotation_range = 3 , 
                             width_shift_range = 0.1,
                             height_shift_range = 0.1,
                             zoom_range = 0.02,
                             channel_shift_range = 10.0, 
                             )#—(1)

datagen.fit(x_train)#—(2)


#history = model.fit(x_train, y_train, batch_size=batch_size, … #—(3)
history = model.fit_generator(
                              datagen.flow(x_train, y_train, batch_size=batch_size),…#—(4)

↑(1)ImageDataGeneratorで目的に合致するもので使えそうなのを選んで設定。
どのように画像が変化するのかは参考ページなどに。
(2)は内容によっては不要かも。
ImageDataGeneratorを使う前は(3)のfit関数で訓練を実行していたのだけど、(4)の形式に変更。

調子に乗って盛り込みすぎると学習が進まなくなってしまったので、ほどほどがよさそう、、、ほどほどってなんやねん!?将来はそういうのもKerasが良きに計らってくれたらいいのにな。


参考ページ
Kerasによるデータ拡張 - 人工知能に関する断創録
Kerasでデータ拡張(Data Augmentation)後の画像を表示する - Qiita







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