Core MLモデル「squeezeNet.mlmodel」を用いて画像のオブジェクト認識を行い、結果をデスクトップにCSV形式でデータ書き出しを行い、NumbersでオープンするAppleScriptです。
–> Download squeezeNetKit.framework (To ~/Library/Frameworks)
macOS 10.13上ではスクリプトエディタ、Script Debugger上で、macOS 10.14上ではScript Debugger上で動作します(AppleScript Appletでも動作)。
さまざまなCore MLモデルを用いて画像認識を行わせてはみたものの、最もスコアの高いもののラベルだけを返させても、結果がまったく内容にそぐわないケースが多く見られます。
▲機械学習の評価値が1.0に近いものは確度が高く、0.0に近いものは判断に迷った末に消極的に出した値。経験則でいえば、最高スコアの項目が0.7以上のスコアでないといまひとつのようです(0.7以上でもダメな時はダメなわけで、、、)
画像認識については、結果があまりに的外れで「なんじゃこら?」というケースが多いので、確認のためにCSVデータ出力させてNumbers上で確認させてみることにしてみました。そのためにありあわせのサブルーチンを組み合わせて作ったものです。
スコアが高い順に結果を並べて確認してみると、最も高いスコアの値であっても0.0に近い評価値であることがあり、「何も考えずに最高スコアのラベルだけ取ってくるのはものすごく危険」なことがよくわかります。
▲squeezeNet.mlmodelをNetronでビジュアライズしたところ(一部抜粋)
AppleScript名:SqueezeNetでオブジェクト判定して結果をCSV書き出ししてNumbersでオープン.scpt |
– Created by: Takaaki Naganoya – Created on: 2018/11/11 – Copyright © 2018 Piyomaru Software, All Rights Reserved use AppleScript version "2.7" — High Sierra (10.13) or later use framework "Foundation" use framework "AppKit" use framework "squeezeNetKit" use scripting additions property NSUUID : a reference to current application’s NSUUID property NSArray : a reference to current application’s NSArray property NSImage : a reference to current application’s NSImage property NSMutableArray : a reference to current application’s NSMutableArray property NSSortDescriptor : a reference to current application’s NSSortDescriptor set aFile to POSIX path of (choose file of type {"public.image"}) set aImage to NSImage’s alloc()’s initWithContentsOfFile:aFile set resDict to (current application’s imageClassifier’s alloc()’s init()’s ImageClassifierWithImageAndRetDict:aImage) set kArray to (resDict’s allKeys()) set vArray to (resDict’s allValues()) set aLen to kArray’s |count|() set anArray to NSMutableArray’s new() repeat with i from 0 to (aLen – 1) set tmpKey to (kArray’s objectAtIndex:i) as string set tmpVal to (vArray’s objectAtIndex:i) as real (anArray’s addObject:{aKey:tmpKey, aVal:tmpVal}) end repeat –Sort by value set bList to sortRecListByLabel(anArray, "aVal", false) of me –record in list –> 2D list set cList to convRecInListTo2DList(bList) of me –デスクトップにCSVファイルを書き出してNumbersでオープン set aPath to (((path to desktop) as string) & (NSUUID’s UUID()’s UUIDString()) as string) & ".csv" set fRes to saveAsCSV(cList, aPath) of me tell application "Numbers" open (aPath as alias) end tell –リストに入れたレコードを、指定の属性ラベルの値でソート on sortRecListByLabel(aRecList as list, aLabelStr as string, ascendF as boolean) set aArray to NSArray’s arrayWithArray:aRecList set sortDesc to NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF set sortDescArray to NSArray’s arrayWithObjects:sortDesc set sortedArray to aArray’s sortedArrayUsingDescriptors:sortDescArray set bList to (sortedArray) as anything return bList end sortRecListByLabel on convRecInListTo2DList(aList) set anArray to NSMutableArray’s arrayWithArray:aList set fItem to anArray’s objectAtIndex:0 set keyList to fItem’s allKeys() as list set aCount to anArray’s |count|() set allArray to NSMutableArray’s new() repeat with i from 1 to aCount set anItem to (anArray’s objectAtIndex:(i – 1)) set tmpItem to {} repeat with ii in keyList set tmpDat to (anItem’s valueForKeyPath:(contents of ii)) if tmpDat is not equal to missing value then set the end of tmpItem to tmpDat else set the end of tmpItem to "" end if end repeat (allArray’s addObject:tmpItem) end repeat set allList to allArray as list set the beginning of allList to keyList return allList end convRecInListTo2DList –CSV Kit –2D List to CSV file on saveAsCSV(aList, aPath) –set crlfChar to (ASCII character 13) & (ASCII character 10) set crlfChar to (string id 13) & (string id 10) set LF to (string id 10) set wholeText to "" repeat with i in aList set newLine to {} –Sanitize (Double Quote) repeat with ii in i set jj to ii as text set kk to repChar(jj, string id 34, (string id 34) & (string id 34)) of me –Escape Double Quote set the end of newLine to kk end repeat –Change Delimiter set aLineText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to "\",\"" set aLineList to newLine as text set AppleScript’s text item delimiters to curDelim set aLineText to repChar(aLineList, return, "") of me –delete return set aLineText to repChar(aLineText, LF, "") of me –delete lf set wholeText to wholeText & "\"" & aLineText & "\"" & crlfChar –line terminator: CR+LF end repeat if (aPath as string) does not end with ".csv" then set bPath to aPath & ".csv" as Unicode text else set bPath to aPath as Unicode text end if write_to_file(wholeText, bPath, false) of me end saveAsCSV on write_to_file(this_data, target_file, append_data) tell current application try set the target_file to the target_file as text set the open_target_file to open for access file target_file with write permission if append_data is false then set eof of the open_target_file to 0 write this_data to the open_target_file starting at eof close access the open_target_file return true on error error_message try close access file target_file end try return error_message end try end tell end write_to_file on repChar(origText as text, targChar as text, repChar as text) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to targChar set tmpList to text items of origText set AppleScript’s text item delimiters to repChar set retText to tmpList as string set AppleScript’s text item delimiters to curDelim return retText end repChar |