今回はNeural Network Consoleで「output_result.csv」に出力された評価結果を、EXCELに取り込んで、画像を一覧するマクロ(VBA)を作ってみます。
元々手作業でやってたものが元です
Neural Network Consoleで「output_result.csv」に出力された評価結果を、EXCELに取り込んで分類に失敗したファイルを識別する方法を前回やりました。
そうすると。
識別できるのはいいけど、ひとつひとつ画像を開いたりするのが面倒だ。
との・・ご意見をいただきました(笑)
なので、とりあえず前回の要領でEXCELファイルができている前提で、ボタンを押したら確認する一覧表ができますよ・・程度の簡単なマクロ(VBA)をつくってみようかな・・というわけです。
EXCELのマクロ(VBA)を使ったことがある方を前提に説明します
今回は前回の続きでMNIST画像(28×28サイズ)を想定したものになってます。
やるのは、こんな感じでもやれますという考え方の例と、サンプルソースの紹介です。
前回の記事が、EXCELを使うので、今回もVBAを使います。、
もしEXCELでVBAプログラム(マクロ)を使ったことがない方は、以下の記事とかで基本的な部分を確認ください。
さて。
始めます。
動作仕様です
元になるのは、こちらの記事の手順で作成したEXCELシートです。
このフォーマットのA列からD列・・つまり、画像ファイル名と正解ラベル・評価結果・OK/NG判定結果の4列をコピーして使います。
受取側のEXCELの動作仕様です
まず、xlsm で保存したEXCELに2つのシートを作ります。
名前は「output」と「result」にしてます。
outputシートは元ネタです。
こんな感じのレイアウトにします。
A列1・2行目にまたがったボタンは「開発」リボンにあるフォームのボタンです。
ここに、上記のEXCELからA列~D列のデータ部分をコピーしたものを貼り付けて使います。
貼り付けたイメージはこちらです。
そして「result」シートには、なんとなく結果のヘダーを作っておきます。
ポイントはA列の行の幅と高さを画像にあわせておくとカッコいいということ。
MNISTの28×28サイズのまま画像を表示しても小さくて見づらいので、5倍くらいに拡大して表示するようにします。
なので、幅「17.4」高さ「108」くらいに調整してます。
そして「output」シートの「resultシート作成」ボタンを押すと、マクロが動いて、outputシートの各行の画像ファイルのパスから画像を表示して、ついでに正解ラベルと評価結果をコピーします。
動かした結果の例がこちらです。
いい感じです。
つまり、NG分だけフィルタして貼り付ければ、簡単にアンマッチ画像チェックのリストが作れます・・という。
いちいち、手で拾わなくてもいいよ・・という。
ただ、それだけの話ですが。
そして、消すのもスマートにできないといけないから、「resultシートクリア」ボタンも用意してます。
こういうツールです。
VBAのソースと補足説明です
最初にソース全体をのせます。
' resultシート作成ボタンに対応する ' Sub make_image_list() Dim input_sheet, result_sheet As String Dim out_row, in_row, max_row As Integer input_sheet = "output" result_sheet = "result" out_row = 2 max_row = Sheets(input_sheet).Cells(Rows.Count, 1).End(xlUp).row Sheets(result_sheet).Select Application.ScreenUpdating = False For in_row = 4 To max_row Sheets(result_sheet).Cells(out_row, 1).Select Call add_picture(Sheets(input_sheet).Cells(in_row, 1).Text, 5) Sheets(result_sheet).Cells(out_row, 2) = Sheets(input_sheet).Cells(in_row, 2).Text Sheets(result_sheet).Cells(out_row, 3) = Sheets(input_sheet).Cells(in_row, 3).Text out_row = out_row + 1 Next in_row Application.ScreenUpdating = True End Sub ' resultシートクリアボタンに対応する ' Sub clear_all() Dim img_shape As Shape Dim result_sheet As String Dim row, max_row As Integer result_sheet = "result" For Each img_shape In Sheets(result_sheet).Shapes If img_shape.Type = msoPicture Then img_shape.Delete Next img_shape max_row = Sheets(result_sheet).Cells(Rows.Count, 2).End(xlUp).row For row = 2 To max_row Sheets(result_sheet).Cells(row, 2).ClearContents Sheets(result_sheet).Cells(row, 3).ClearContents Next row End Sub ' 画像ファイル名とパス(file_name)と拡大率(zoom)を受け取り画像を拡大表示する ' Sub add_picture(file_name As String, zoom As Integer) Dim img_file_name As String Dim img_shape As Shape img_file_name = file_name Set img_shape = ActiveSheet.Shapes.AddPicture( _ Filename:=img_file_name, _ LinkToFile:=False, _ SaveWithDocument:=True, _ Left:=Selection.Left, _ Top:=Selection.Top, _ Width:=0, _ Height:=0) With img_shape .ScaleHeight zoom, msoTrue .ScaleWidth zoom, msoTrue End With End Sub
補足説明にはいる前に、ちょっとお断りを。
上記のマクロ名や変数は「make_image_list()」のように、小文字でアンダーバー(_)つなぎにしてます。
VBAだと「makeImageList()」のような記法の方が一般的なので、気持ち悪いなと思われる場合は、使う時には適当にお好きな名前に変更してください。
さて。
resultシートに画像を表示する 「make_image_list()」からです。
このマクロを「resultシート作成」ボタンに関連づけます。
まあ、やってることと言えば
max_row = Sheets(input_sheet).Cells(Rows.Count, 1).End(xlUp).row
で、A列(Cellsの第二引数は1がA列、2がB列・・です)のデータが存在する最終行を取得して、4行目からmax_row行まで、ループで1行ずつ処理しているだけです。
そして、「Sheets(result_sheet).Select」でresultシートをアクティブにして、パフォーマンスを稼ぐために「Application.ScreenUpdating = False」で画面再描画を抑制しています。
画像を表示するのは
Call add_picture(Sheets(input_sheet).Cells(in_row, 1).Text, 5)
で、画像ファイルのフルパスとファイル名を「output」シートのA列から取得して、zoomに「5」を指定することで5倍にしています。
add_picture()マクロは、EXCELで画像ファイルからセルに貼り付ける時の、定番の書き方そのものなので、特に補足はしません。
たぶん。
同様のソースや解説は、ググればいっぱいでてきますので。
今度は。
クリアするほう「clear_all()」です。
このマクロは「resultシートクリア」ボタンに関連づけます。
画像ファイルをクリアする部分。
For Each img_shape In Sheets(result_sheet).Shapes
If img_shape.Type = msoPicture Then img_shape.Delete
Next img_shape
テキスト部分をクリアする部分
max_row = Sheets(result_sheet).Cells(Rows.Count, 2).End(xlUp).row
For row = 2 To max_row
Sheets(result_sheet).Cells(row, 2).ClearContents
Sheets(result_sheet).Cells(row, 3).ClearContents
Next row
にわけてます。
ちょっと効率悪いですけど、1セルずつ「数式と値だけを消す」ClearContentsを使ってます。
Deleteとかしてしまうと、書式も消えて面倒なので。
そのくらいですかね。
ポイントは。
あとは、これをベースにして、ちょこちょこ書き換えてもらえば、時々のデータにあわせてできると思います。
最後にちょっと言い訳です
あえて・・ですけど。
エラー処理とか、汎用的にする配慮とかは一切してません。
こういうブログでサンプルにするのに、あまり、行数を増やしたくなかったということもありますが、あくまで、自分で作って自分で使う。
そういう想定のツールだというのもあります。
正直。
学習とかに使うデータセットは都度違います。
シンプルな土台だけ用意しといて、細かい調整をソースコードの修正で行う方が、実は下手に重たい汎用的なツールを使うより、速くて確実だと・・自分では言ってるのですけどね。
単なる、横着の言い訳かもしれません(笑)
そのへんはご容赦ください。
今回はこんなところで。
ではでは。