log/2021
自分がやったこと技術のログ。今後何かあるたびに追記予定です
Rustの画像処理ライブラリ調査メモ
image (image-rs)
- Rustのデファクトっぽいやつ
- これ使ってハズレることはなさそう
- 画像自体の取り扱いがメインで、グラフィックスプログラミングっぽいものは↓のimageprocでやる方針の模様
imageproc
- Canny edgeとかHOGとかハフ変換とかそれ系(伝われ)が入ってる
- 機械学習系を別にするとOpenCVのお世話にならずにすむラインナップかもしれない
- というか実装APIを見ているとOpenCVの項目をかなり参考にしてそうな雰囲気を感じる
photon (photon_rs)
- WebAssembly出力でブラウザで使えるのが売りっぽい
- 公式サイトにブラウザ上で動かしてるデモがいっぱいある
- 処理内容は視覚効果メインっぽい
- エッジ化、色相変換、ノイズ、セピア化など
- 対応フォーマットはimage-rsよりは少なめ?
- imageと違ってBGR対応などはない一方で、HSVを扱えたりするのは要点押さえてて好印象
Photon-rs使ってみた
やったこと
ディレクトリ内の画像全部を正方形画像に resize & cropするだけ
ハマったところ
- native::open_image のファイルパス指定引数がcrate.io版だと無駄に 'static lifetime になっていて異様に使いづらい
- GitHubの方では9ヶ月前に修正済み(だけどなぜかcrate.ioに反映されていない)ので、GitHubから取ってくるようにして解決
現状
- ものすごく素直に書いて、約1400件の画像で40sくらいだったり約8200件の画像で4分以上かかったり
- ちょっと遅くない?という感じなので並列化はしてみるつもり
並列化してみた
rayonのpararell iterator利用に変えただけ
- i5-6500(3.2GHz / x4 cores)
- 1400件が12s, 8200件が75sほどに
- i5-9600K(3.7Gz / x6 cores)
- 1400件が6s, 8200件が35sほど
- 追記:Ryzen 5 5600X (3.7-4.6GHz / x6 cores)
- 1400件が3.8s, 8200件が24sほど
- 元はi5-6500を使っていたマシンの換装。3倍速くなった
- メモリもDDR4-2133からDDR4-3200に同時に換装しているので、CPU同士の比較としてアンフェアになってはいます
並列化した分だけ速くなってる感じ。普段使いしてるi5-6500の性能が割と悲しいことになっているけど、それなりに許せる範囲の速さにはなった(メイン機もいい加減買い替え時なのか…)→ 買い替えました、ベンチ結果を追加
Rust書いてみたメモ
最近よく触っているのがPythonとTSなので、この2つが主な比較対象になっています
- 環境はVSCode
- 途中までRust拡張、その後rust-analyzeに移行
- RLSよりrust-analyzeの方がもろもろ高性能高機能でした
- RLSはちょくちょく止まるし処理も遅めで生産性下がってた
- どちらも#[test]ディレクティブつけると「|>run test」などのボタンが表示されて文明的
- 途中までRust拡張、その後rust-analyzeに移行
- 所有権まわりの理解をしないと何も書けないことが分かり、この際ということでお勉強して「所有権完全に理解した」。
- 簡単なプログラムなら所有権大して意識しなくても書けるかなと思っていたけれど、むしろ所有権理解しないと一切何も書けないくらい最初から要求されるやつでした
- たまたま所有権が絡んだライブラリのバグ踏んだというせいもありますが…
- オライリー「プログラミングRust」の4章〜5章あたりだけ読めば多分大丈夫
- 5章は「参照」という名前だけど、実質所有権の話をしているので4章とセット
- 簡単なプログラムなら所有権大して意識しなくても書けるかなと思っていたけれど、むしろ所有権理解しないと一切何も書けないくらい最初から要求されるやつでした
- crates.ioがAPIリファレンス兼ねる状態になっているのはすごくやりやすい
- 割とみんなちゃんとドキュメント書いている印象だけど、これは文化の問題?
- npmだとAPIリファレンス系はnpmjs.com内では基本的に見れなくて、いちいち外部サイトに行く必要があった。この点crates.io内での完結度が高いのはすごく良い
- テストが言語組み込みなのは良い。すごく良い
- JS/TSみたいに「あーテストなーjest入れてテストスクリプト準備してー」みたいなところで手と頭を使わなくて済むのは最高のDXだった
- ソースコード中にインラインで適当に書いていけるのもとっつきやすくていい
- モジュールまわりは正直なんじゃこりゃと思うところが多かった
- あくまで初めて触った人の印象として
- main.rs/lib.rs がハードコード状態なのはなんだかなと
- use moduleまわりの説明は公式ドキュメントも書籍も微妙に雰囲気読んでという感じで、変にハマりがちになりそう
- 発展的な例は頑張って説明してるけど、基本的な部分の説明が抜けてる印象
- 総じてPythonよりはマシ、node系とは同じくらい首をかしげることがあるという感じ
- エラー処理が今どき言語として当たり前の水準なのも実は感謝した方がいいのかもしれない
- 初見でフリーズした構文:lifetime parameterとクロージャの引数
- rayonでの並列化がめちゃくちゃお手軽でびっくりした
pixi.js 触ったメモ(TBD)
- Arch Linux / Firefox のデフォルトだとWebGL動かなかった問題
Firefox
Go to about:config, search for webgl.disabled, ensure that its value is false.
Go to about:config, search for webgl.force-enabled, set it to true.
Go to about:config, search for layers.acceleration.force-enabled, set it to true.
restart your firefox.
React PIXI
- Reactアプリケーションとして作ったのもあり、React PIXIを採用
- 薄いラッパーだけど、React上でpixiを扱えて乗せれて良かった
- Hooksやコンポーネントがそのまま使える
- 困ったらpixi.js本体のドキュメントを見るスタイル。薄いラッパーなのでそこまで困らない
pngのバイトストリームを読み込むAPIがない…?
- ファイル選択ダイアログ経由でPNGファイルからテクスチャを作ろうとするとpixi.jsで完結しない
- JS自体にPNGデコーダーAPIはない
-
pngjsを導入したブラウザ環境での挙動が怪しかったのでUPNG-jsにした- まさかこんなことで外部ライブラリが必要になるとは
Canvasを画像として保存
- pixi.js 自体があまり面倒を見てくれない感じだったので、生DOMからCanvas HTMLElement引っ張ってきてtoBlobなどをした
- StageのpreserveDrawingBufferオプションを入れておかないと更新内容が反映されないので必要
Firebase / GitHub Actions
- React製ブラウザアプリ(バックエンドはなし)のデプロイ先に Firebase Hosting を選択した
- firebase init をして、ウィザードにしたがっているとGitHub Actions向けの設定ファイルまで生成してくれて赤ちゃんになる
- あまりに面倒見が良くて技術記事的に書くことがないレベル
TypeScript パッケージ関連メモ
JSでのデータ可視化
- MLやるならpyplotやgraphviz的なことやりないよねって
- 思ったよりこれだというライブラリがなく、ライブラリ選定で半日溶けた
- Reactネイティブなvisxがよさそうな感じ
フロントエンドのデータ可視化ライブラリ調べた
- D3.js: ド定番だけど生DOM触る設計が今だと微妙
- とは言えラッパーや後発では出来ない自由度があったりする
- C3.js: D3.js ラッパー。D3のうち一部機能でいいならこれもアリかも
- plotly.js: D3ベースで多分今一番メインストリームな感じ。元商用
- PythonやRと互換性があるのはえらい
- 3Dグラフなど競合と比べて一番機能豊富、だと思う
- Chart.js, Chartist.js : 棒グラフとか描画するだけならこれでいいと思う
- Victory, Rechart: Reactベース。やれることはChart.jsと同様ぽい
- 番外 HighChart: 商用。個人で使うのは厳しそうだけど評判はよさげ
- visx: ReactベースでD3並の自由度。要件的に今回はこれを採用してみる
JRA公式ページからオッズの取得
JRA公式ページ自体の実装について
断定系で書いている部分も、基本的には推測に基づいたものです
- jQueryによるSPA(と言っていいのか)的な何かになっている
- Routerのような気の利いたものは入れてないようで、UX的には別ページのような状態でも全て同一のURL https://www.jra.go.jp/JRADB/accessO.html になる
- /JRADB/accessI.html というエンドポイントからレース情報を取得してそうなのだけど、開発ツールを見る限り空の配列しか返って来ていない。
- 平日だから?週末に要検証
APIコールの実装
- 呼び出し先レース情報・オッズ種類のIDが存在している
- 下記のhidden inputに関して、cnameを上述オッズのIDで書き換える(jQueryによるDOM操作)
- formをsubmitすることでリクエストを発火、レスポンスでオッズ表示ページのHTMLが返ってくる
<form id="commForm01" method="POST" enctype="application/x-www-form-urlencoded" style="margin-top:0em; margin-bottom:0em">
<input type="hidden" id="cname" name="cname">
</form>
オッズの取得
リクエストは普通にPOSTするだけでも取得できる。例
curl -X POST -d "cname=pw156ou1009202102110120210501Z%2F3C" https://www.jra.go.jp/JRADB/accessO.html
- オッズのIDは pw156ou1009202102110120210501Z/3C のようにスラッシュ(/)を含む形式になっているが、リクエスト時にはURLエンコードしてあげないといけない
- 返ってくるデータは普通のHTMLページそのものなので、あとは普通のHTMLスクレイパーでやれるはず
- HTMLパーサーは何を使うか…BeautifulSoupは定番だと思うけどPython触りたくない
TBD
特定のレース単位で、オッズIDのリストを取得する方法
雑感
「競馬 オッズ 取得」などで適当に検索するとnetkeibaのスクレイピング記事ばかり出てくるんだけど、二次ソースへのスクレイピングばかりヒットするのはどうなんでしょうか
読書メモ:Category Theory for Programmers
- 読書中、WIP
- ページ数は多いけれど、1ページあたりの文字数は少なめなので分量はほどほど
- 今のところまさにタイトル通りの本という感じ
- 抽象性の高い圏論の概念を冗長性の高い記述で伝えてくれる
- これとは別に普通の圏論の本も横に置きながら読むといい気がした
- 例えばモノイドの説明に3ページくらい使っているけれど、普通の圏論の教科書だと3行で説明されていたりする
- マックレーンでは「よってモノイドは単位元を持つ半郡そのものである(p.12)」で済まされたりするようなところ
- 本書を読んでから教科書を見ると頭におさまりやすいと思いました
- 例えばモノイドの説明に3ページくらい使っているけれど、普通の圏論の教科書だと3行で説明されていたりする
追記
日本語化プロジェクトが進んでいた(しかもzenn上で書籍化)
fp-ts
TBD あとでかく
- 関数型で一応実戦利用可能なレベルなのは良い
- JS/TSのライブラリはPromiseやnull返す形で作られているので、それを自分で加工する手間はどうしても発生する
- ここはライブラリ自体が悪いわけではないけれど、エコシステムの問題として
- メモ:
- カリー化は Apply あたりのサンプルコード参照
- Monadはヘルパーのchainでつなぐ
- Promiseのラッパーまわりはあまり使いやすい感じがしない・・・
TypeScript でスクレイピング
脱Pythonに向けて
- 基本的なquerySelectorはjsdomでやれそう
- HTTPリクエストはaxios使ってるけど、スクレイピング向けのものはあるかもしれない
いまかいてる
Next.js + WebAssembly
Rustで書いた資産をNextから使いたいというユースケース
-
https://medium.com/lagierandlagier/nextjs-webassembly-and-web-workers-a5f7c19d4fd0
- 主にここでだいたいやりたことの解説になっていた
- 記事主のサンプルはWorkerを使う構成になっているけれど、Workerなしでもやれる
- 補助的にこちらのエントリも参照した https://zenn.dev/softoika/articles/3fb7278157ba081acea4
- Next公式にあるサンプルはwasm直読みの例しか置いておらず、実践的には微妙
PyTorch + code-server入Docker環境構築メモ
環境
Arch Linux
手順
PyTorchのビルド済みイメージの上に、code-serverのインストールスクリプトを追加
FROM pytorch/pytorch:1.9.0-cuda11.1-cudnn8-devel
RUN apt-get update && apt-get install -y curl
RUN curl -fsSL https://code-server.dev/install.sh | sh
RUN useradd -ms /bin/bash tackman
USER tackman
WORKDIR /home/tackman
RUN code-server \
--install-extension ms-python.python \
--install-extension ms-ceintl.vscode-language-pack-ja
トラブルシュート
立ち上がった後にターミナルでnvidia-smiなどをしようとすると
Failed to initialize NVML: Unknown Error
のエラー
解決法
- privilegedオプションつきで起動でいけた
- docker-compose.yml内に privileged: true を追加
version: '3.9'
services:
code:
build:
context: .
ports:
- 127.0.0.1:8081:8080
volumes:
- ./:/home/tackman/app
entrypoint: "code-server --auth none --bind-addr=0.0.0.0:8080 /home/tackman/app"
privileged: true
deploy:
resources:
reservations:
devices:
- capabilities: [gpu]
参考リンク
- https://qiita.com/suzuki_sh/items/6bc15446965df20b6c5a
- https://bbs.archlinux.org/viewtopic.php?id=266915
- https://docs.docker.com/compose/gpu-support/
- https://docs.docker.com/config/containers/resource_constraints/#gpu
- https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
- https://docs.docker.com/compose/compose-file/compose-file-v3/
GCPで学習終了通知
- Discordに投稿するスクリプトを書いて、終了時にDiscord個人窓にいボットが投稿するようにしてる
- sudo poweroffでインスタンスが終了できるので、学習終了時にそのままインスタンス落とす
- GPUインスタンスは富豪的に使うには流石にちょっとお高い
Dockerコンテナ内からホストの終了
- GPUインスタンスはお高いので、タスク終了したら自動的に落ちるようにしたい
- 前述のようにホスト側ではpoweroffでかんたんに落とせるが、コンテナ内からやろうとすると色々面倒(妥当)
# docker-comppose up -d でコンテナは立ち上がっている想定
ホスト側から
docker-compose exec ContainerName bash && sudo poweroff
コンテナ内で
python train.py && discord_notification_command && exit
コンテナにbashで入って、そこから抜けたらシャットダウンするという若干乱暴なソリューション
JSの時刻ライブラリ
- いつの間にかmoment.jsがお亡くなりになっていたので
- フットプリントが一桁KBのday.jsをとりあえず使うことにした https://www.npmjs.com/package/dayjs
- 競合よりおおむね一桁小さいサイズ
参考
#Oculus Air Link + Clip Studioのでの作業チャレンジログ
Air Link自体について
- 非ゲームアプリケーションを触っている範囲では遅延等をほぼ感じない、かがくのちからってすげー
HMD+板タブでクリスタ
結論としては辛い
環境概要
- 4Kディスプレイにクリスタを全画面表示の状態で、Air Linkを使って操作
- 立ち作業用スタンディングデスクに板タブと左手デバイスがわりのハーフキーボード(キーボードの左半分だけのやつ)
- デスクトップが平面になる程度にVR空間内で近づけた状態で作業
なお私は右利きでペンを右手に持って作業しているので、左利きの方は適宜読み替えてください
使用感
良い/NPな点
- 解像度はだいたいこんなものかという感じ
- ドローイングにはあまり支障はない気はする、細かい部分の描き込みや仕上げは無理そう
- 大画面で作業ができる
- ある意味イーゼルを使った作業感
- 人間が動いて物理的に目を近づけることで細部を見に行ける
悪い
- Oculusコントローラーと板タブでポインティングデバイスとして干渉する
- 少なくとも左手にはコントローラーを持っていないともろもろ調整ができないけれど、常時カーソルが移動している判定になる
- 一応板タブの上にペンを浮かせている状態にすれば板タブ入力が優先されはするが・・・
- 板タブが強制ハイセンシ化する
- ディスプレイ利用時と比べて大幅に狭い範囲での作業になるので、体感センシが倍になる
- 板タブ側の入力範囲調整でなんとかなる可能性はある
- ディスプレイ利用時と比べて大幅に狭い範囲での作業になるので、体感センシが倍になる
- クリスタ内でカーソル(・とか+みたいになってるやつ)の現在位置が非常に分かりづらい
- これは私の視力の問題はある気はする
まとめ
可能性は感じるものの、(自身の習熟曲線を加味しても)現時点ではちょっと実用に耐えなさそう。Oculusネイティブなドローイングツールを先に試してみた方がよさそう