2019/11/30


以前、mruby から TensorFlow Lite を扱う為の mrbgems、「mruby-tflite」を書きました。

Big Sky :: MRuby の TensorFlow Lite バインディングを書いた。

以前 TensorFlow Lite の Go バインディングを書いたのだけど Big Sky :: TensorFlow Lite の Go binding を書いた。 Google launche...

https://mattn.kaoriya.net/software/lang/c/20190417102631.htm

KaoriYa さんに Coral EdgeTPU をプレゼントして頂いたので、mruby-tflite を Coral EdgeTPU 対応する為の mrbgems を書きました。

GitHub - mattn/mruby-tflite-edgetpu
https://github.com/mattn/mruby-tflite-edgetpu

元の mruby-tflite とはソースを分離してあります。build_config.rb に以下の様に追加して頂くだけで EdgeTPU を扱える様になります。

conf.gem :github => 'mattn/mruby-tflite'
conf.gem :github => 'mattn/mruby-tflite-edgetpu'
conf.gem :github => 'kjunichi/mruby-webcam'
conf.gem :github => 'qtkmz/mruby-gd'

mruby-tflite と mruby-tflite-edgetpu を連携するには以下の様にインタプリタに対してオプション設定する必要があります。

#! ./bin/mruby

# オプションを生成
options = TfLite::InterpreterOptions.new

# Coral EdgeTPU のデバイス一覧から 0 番目を delegate として割り付け
options.add_delegate TfLite::EdgeTPU.new(TfLite::EdgeTPU.devices[0])

model = TfLite::Model.from_file 'mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite'
interpreter = TfLite::Interpreter.new(model, options)
interpreter.allocate_tensors
input = interpreter.input_tensor(0)
output2 = interpreter.output_tensor(1)
output3 = interpreter.output_tensor(2)
wanted_width = input.dim(1)
wanted_height = input.dim(2)
wanted_channel = input.dim(3)
data = Array.new(wanted_height * wanted_width * wanted_channel, 0)
labels = {}
File.read('coco_labels.txt').lines.each do |x|
  kv = x.split('  ')
  labels[kv[0].to_i] = kv[1].strip
end

cam = Webcam.new(ARGV[0]||0)
cam.set_size(wanted_width, wanted_height)
cam.each(true) {|img|
  decoded = GD::Image.new_from_jpeg_data(img)
  (0...wanted_width).each do |x|
    (0...wanted_height).each do |y|
      pixel = decoded.get_pixel(x, y)
      offset = (y * wanted_width + x) * wanted_channel
      data[offset..offset+2] = [decoded.red(pixel), decoded.green(pixel), decoded.blue(pixel)]
    end
  end
  decoded.destroy
  input.data = data
  interpreter.invoke
  result = []
  output3.data.each_with_index do |v, i|
    next if v < 0.6
    result.push([v, output2.data[i]])
  end
  result.sort{|a, b| b[0] <=> a[0] }.take(5).each_with_index do |v, i|
    s = v[0]
    i = v[1]
    puts "#{labels[i]} #{i} #{s}"
  end 
  puts "---"
}

現状、mruby には OpenCV の様に加工した MAT を表示できる mrbgems が存在しない為、kjunichi さんが作っておられる mruby-webcam で画像を取り込み、qtkmz さんの mruby-gd で画像を解析し、そこに何が映っているのかを端末に出力しているだけですが、今後 OpenCV の様な mrbgems が登場すれば mruby でもリアルタイムで画像を解析し、認識したオブジェクトに枠や名称を描画する事も出来る様になるかもしれません。

mruby-tflite-edgetpu
詳解ディープラーニング 第2版 ~TensorFlow/Keras・PyTorchによる時系列データ処理~ (Compass Booksシリーズ) 詳解ディープラーニング 第2版 ~TensorFlow/Keras・PyTorchによる時系列データ処理~ (Compass Booksシリーズ)
巣籠 悠輔
マイナビ出版 / ¥ 3,740 (2019-11-27)
 
発送可能時間:在庫あり。

Posted at by



2019/11/12


先日、Gopls の v0.2.0 がリリースされました。

v0.2.0
https://github.com/golang/go/issues/33030#issuecomment-549629508

リリースノートに書かれていますが、このバージョンから completeUnimported に対応しています。fmt が import されていなくても fmt.Println が補完できる様になります。ただしデフォルトでは無効になっています。Visual Studio Code であれば以下を settings.json に含める事で使える様になります。

"gopls": {
    "completeUnimported": true
},
vscode

また vim-lsp をお使いであれば以下の様に設定する事で使える様になります。

if executable('gopls')
  augroup LspGo
    au!
    autocmd User lsp_setup call lsp#register_server({
        \ 'name''go-lang',
        \ 'cmd'{server_info->['gopls']},
        \ 'whitelist': ['go'],
        \ 'workspace_config'{'gopls'{
        \     'staticcheck': v:true,
        \     'completeUnimported': v:true,
        \     'caseSensitiveCompletion': v:true,
        \     'usePlaceholders': v:true,
        \     'completionDocumentation': v:true,
        \     'watchFileChanges': v:true,
        \     'hoverKind''SingleLine',
        \   }},
        \ })
    autocmd FileType go setlocal omnifunc=lsp#complete
    autocmd FileType go nmap <buffer> gd <plug>(lsp-definition)
    autocmd FileType go nmap <buffer> ,n <plug>(lsp-next-error)
    autocmd FileType go nmap <buffer> ,p <plug>(lsp-previous-error)
  augroup END
endif

僕はその他にも実験的なオプションを沢山有効にしています。詳しくは gopls の settings.md を参照下さい。

settings.md
https://github.com/golang/tools/blob/master/gopls/doc/settings.md

これらは Visual Studio Code の gopls セクションでも使えますし、同様に vim-lsp の workspace_config でも使えます。

Posted at by



2019/11/04


はじめに

今年も Vim の国際会議 VimConf 2019 に参加してきました。本格的に国際会議という位置づけに移ってからほぼ4年目、その内3年をスタッフとして参加させて頂きました。

昨年、Vim の作者 Bram Moolenaar 氏を呼べたのはもちろん素晴らしい事ですが、今年も vim-lsp の作者である Prabir Shrestha 氏、neovim のメインメンテナである Justin M. Keyes 氏に登壇頂けたのは、企業スポンサー様の皆さま、個人スポンサーの皆さま、そして当日会場を盛り上げて頂いた皆さまのおかげです。ありがとうございました。

参加したいと思いながらもなんとなく尻込みして来れなかった方、非常に残念です。良い話が沢山聞けました。スライドが後から公開されると思いますが、これだけは言っておきます。熱量やそれを見ている会場の皆さんの期待、懇親会で Vim と関係ない話で盛り上がったり、二次会で Ruby on Ralis のコミッタから OSS とは、英語とは、について聞けるチャンスは、参加しないと得られません。

とまぁ Twitter のタイムラインで「#vimconf」を検索して沢山の感想を頂いているのを見るとスタッフとして関わってきて良かったなぁと毎度思います。

スタッフ業

今年は我々スタッフがこれまで作りたかった物がようやく形として出来上がり始めている感じがしました。

ここ数年、我々は VimConf の敷居をグッと上げました。意図的にではなく我々自身、中途半端な物は出せないだろうと無意識に敷居を上げたのだと思います。発表者の選定、ゲストの選定、パンフレット、色々な物に気を使い、悪くなる可能性を排除し、誰もが納得する最良を目指しました。

一部選定に漏れた方、本当に申し訳ないです。皆さんから数百文字(多い人だと数千字)ある様な熱のこもった プロポーザルを送って頂きました。スタッフも深夜まで何回も読み、議論し、情け容赦なしに決めさせて頂いた結果です。ご了承下さい。

そしてスタッフの皆さんも結構な私生活の時間を割いて VimConf 業に力を注いでくれました。司会者、スタッフ、発表者の3役を担当した mopp さん、ドラ係や懇親会の司会、その他裏で皆を取りまとめ「自分から動く事」を常に忘れなかった aomoriringo さん、そしてそれをサポートし続けた guyon さん、kaoriya さん、ujihisa さん、okuramasafumi さん、tihnca さん、aiya さん、本当に皆さん頑張ったと思います。開催を終えた翌日の今朝、スタッフの一部とアイスコーヒーを飲みながら反省会をしていました。若干燃え尽き症候群ぽかったですが、皆「成功してよかったね」と思っていたに違いないです。

ただ規模が大きくなるにつれ、誰かに負担が偏ってしまいがちになるので、それは今後の課題としなければなりません。落ち着いた頃にスタッフで話し合わないといけないですね。

トークの内容

さて内容ですが、とにかく vim-lsp と Go が沢山出てくる VimConf でした。中には Go を使う為に Vim を触りだしたという方もいらっしゃいました。スタッフとしてウロウロしていたので全ての発表は聞けなかったのが残念ですが、個人的に3つ挙げるとすると以下の様になります。

Prabir Shrestha 氏

vim-lsp の作者としてどの様に vim を複数の言語をシームレスに扱えるエディタにするか、その工夫等をお話頂きました。僕も vim-lsp のメンテナとして興味深く聞かせて頂きました。懇親会でも少しお話させて頂きましたが、編集中にも補完候補がシャカシャカと表示され、間違ったコードにマーカーが付く、こんな事が数年前だと実現できなかった Vim を今の操作感に持って行ったのは vim-lsp による貢献が大きいと個人的には思っています。

Justin M. Keys 氏

Vim に限らずソフトウェアという物を fork する場合、それは既に揺るぎない基本設計が出来上がった物であり、それに乗っかる事のメリットは大きいという話をして頂きました。neovim のメンテナとして、vim 色を残しつつ違う vim を作っていく意気込みが聞けて良かったです。

daisuzu 氏

毎年、安定した発表をされていてそれだけでも凄い事だと思いますが、タグジャンプという Vim 特有の機能を分かりやすく会場にいる多くの皆さん沢山届く発表をして頂いたと思います。タグジャンプは Vimmer の基本です。使った事が無かったのであれば、ぜひ習得してみて欲しいです。

その他にも熱のこもった発表が沢山あり「Vimmer っていっぱいいるんだなぁ」と感じさせて頂ける内容ばかりでした。

懇親会でLTをさせて頂き「RESTサーバを5分で作れる、そう Vim ならね」と題して sqlite3 を使って JSON を返す echo を使ったサーバを5分で作るデモをお見せしました。お酒が入っていたので rows.Close() を呼びだすのを忘れていましたが、普段僕がどんな感じにコーディングしているのかをお伝え出来たと思います。

おわりに

我々スタッフは、こういった素晴らしい発表を皆さんが聞き、また次の回にも参加したい、そう思ってくれる事を願ってスタッフ業をやっています。ブログで VimConf の内容を語って頂くのもよし、会社で「VimConf 楽しかったよ」と同僚にお伝え頂くのもよし、懇親会で Vim にまったく関係ない話で盛り上がって頂くのもよし、今回の VimConf をきっかけにどこかに転職/就職が決まるもよし、すべての Vim をトリガにした動きが我々スタッフの望みです。

個人的には僕の GitHub Sponsors をして頂いている数名の方にご挨拶できた事、古くから Vim の活動をされている kana さんと挨拶だけでもできた事、Go のユーザが沢山いるのを知れた事は、とても良かったです。

これも Vim をトリガにした「人と人が繋がれるキッカケ」ですよね。次の回、どういう風になるのかは分かりませんが、また「人と人が繋がれるキッカケ」が提供される VimConf になる事を願っています。

そして Vim に関してどんどん新しい人が入ってきていて、僕もそろそろアウトプットではなくインプットをしないといけないな、そう感じる VimConf でした。

Posted at by