Caffe (with CUDA 8, cuDNN 5.1) を Windows 10 Pro 64bit で build して matcaffe のデモを走らせる(2017-11時点)

環境

Windows 10 Professional, 64 bit. Fall Creators Update 適用済み。GPUGeForce GTX 1060.

Matlab は現時点で最新の R2017b と、諸事情により必要なかなり古い R2014a の両方でデモコードの実行に成功した。なので、これらの間のバージョンならどれでも通るのではないだろうか。

やりたいこと

画像関係の Deep Learning したい。まさに自分がしたい内容について matcaffe のコードが公開されているので、まずは matcaffe を動かしたい。

ウェブ上にもちろん情報はあるんだけど、それでもハマったので、自分用にメモ。とくに matcaffe 固有の問題はウェブ上に記述が少ない。日本語はほぼない。

手順の流れ

基本はここ → GitHub - BVLC/caffe at windows だが、ハマりポイントがあり、また matlab 関係はいろいろ足りていないのでけっこうググる必要があった。

今回入れるのは Visual Studio 2015, CUDA 8.0, Python 3.5: Caffe Release とする。

以下の記述で、実行場所の指定がなかったり ./ とあったり、caffe/foobar などとある場合は、cd caffe 後のディレクトリ(直下に build, cmake, data, docker, ... が見えている位置)を意味することとする。

  1. (必須)Visual Studio 2015 のインストール
  2. (必要かどうか不明確)システム > システムの詳細設定 > 環境変数 > システム環境変数 に VCTargetsPath として C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140 を新規でセット。
  3. (必須)CMake 3.4以上のインストール
  4. GPU使うなら必須)CUDA 8 と cuDNN 5.1 のインストール
  5. (必須?)Anaconda3 4.2.0 のインストール ← 4.4.0 は python 3.6 がデフォなので厳密を期した。Miniconda でもいいと思う。
  6. conda で必要なツールのインストール ← 記憶がやや曖昧…
  7. git のインストール(必要ではないかも)
  8. 適当なディレクトリを作って、コマンドプロンプトpowershell から git clone https://github.com/BVLC/caffe.git して、cd caffe して、git checkout windows する。
  9. (必須)展開されたディレクトリのうちの scripts フォルダに build_win.cmd というのがある(なかったら上の git clone に失敗してるかも)。これをテキストエディタで開いて編集。
  10. (必須かどうかは場合による?)展開されたディレクトリのうちのルートディレクトリに CMakeLists.txt があるのでこれを編集。
  11. (matcaffe の場合おそらく必須)caffe/matlab/CMakeLists.txt を編集(後述)
  12. scripts ディレクトリよりもひとつ上の階層において、コマンドプロンプトなどから、cmake と python --version がちゃんと通ることを確認(パスの確認)。後者で、2.7 とか出た場合、cygwin あたりの python が優先されてるっぽいので、cygwin から python をアンインストールしておく(必要かどうかは知らないけど、どうせ cygwinpython 使わんでしょ?)
  13. 同じ場所で、scripts\build_win.cmd を実行する。失敗した場合は、build ディレクトリを削除したほうが良い(キャッシュみたいのが生成されるので)。あと、C:\Users[ユーザー名].caffe\dependencies という隠しフォルダ(ディレクトリ)も自動生成されていて、こっちも消したほうがいい場合があるかもしれない。
  14. ビルドが通ったら、mnist のテストをする。
  15. matlab から実行できることをテストするために、classification_demo.m を実行する。

以下、それぞれについてもう少し詳しい手順を記す。

Visual Studio 2015 のインストール

Visual Studio のページに行くと最新の 2017 に飛ばされるので、下の方から 以前の Visual Studio ソフトウェアのダウンロード | Visual Studio へ飛ぶ。しかしここで 2015 の右の「ダウンロード」をクリックすると MS アカウントにログインしろと言われる。さらに、しばらくログインしていなかった場合はそれでも「お前にはダウンロードする資格はない」とか言われてリダイレクトされる。どうすればいいかというと、MSアカウント(というか Visual Studio アカウント?)の自分のプロフィール画面の左下にある Visual Studio Dev Essentials というのに無料 subscribe すればよい。うーん、わかりづらい。

ビルドに必要なのは VC++(のコンパイラ cl.exe)だけらしい。自分は、怖いので、絶対に関係ないであろうモバイル関係以外はほとんど全部入れた気がするけど、正直、容量の無駄なので、あとで消したい。

CUDA 8 と cuDNN 5.1 のインストール

互換性の問題があるらしいので、CUDA は 8, cuDNN は 5.1 とする。CUDA は正しくは CUDA Toolkit というやつ(最初これすら知らなくて右往左往した)。具体的にはここから→ CUDA Toolkit Download | NVIDIA Developer 。一方、cuDNN はググればダウンロードページに行くと思うけど、その先は Developer program みたいの会員登録(無料)しないとダウンロードできなかったと思う。先に CUDA をインストールして、cuDNN の方は、C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0 以下の同名ディレクトリに中身を移動しちゃうだけでよい。

Anaconda3 4.2.0 のインストール & 必要なツールのインストール(condaで)

Anaconda installer archive ← ここから昔のバージョンを落とせる。 4.4.0 は python 3.6 がデフォだが、caffe はあちこちで「3.5 にしてね」ってあるので、厳密を期した。でもたぶん、4.4.0 を入れておいて、conda install python=3.5 でいいんじゃないですかね…。

この後、

conda install --yes cmake ninja six scikit-image

だったかをしたはずだが、記憶がすでに曖昧だ…。たしか、protobuf==3.1.0 はしようとしてもエラーができてできなかった気がする。

build_win.cmd の変更

if DEFINED APPVEYOR ( の else の方だけでいい、という記述も見かけたけど、よくわからんし大した量じゃないので両方変えた。

変えた場所は

  • WITH NINJA=1 → =0 に(2箇所)
  • PYTHON_VERSION=2 → =3 に(2箇所)
  • BUILD_MATLAB=0 → =1(2箇所)
  • CONDA_ROOT のパスを自分のパスへ変更。ダブルクオーテーションは付けない。自分の場合は、C:\Users\maz\Anaconda3 だった(2箇所)
  • cmake -Gなんちゃら、のところに、-DCUDNN_ROOT=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0 ^ を追加。不要な気がするが念のため。

CMakeLists.txt への追記

既に入っている cygwingcc とコンフリクト(?)するのを避けるために、「Visual Studio の方の C コンパイラを使ってね」と伝える必要があるらしい。Ninja 切れば不要だったのかもしれないが、まぁ…

17行目あたり(projectの前でないといけないらしい)に、以下を追記した:

## Specify the C compiler for avoiding errors
set(CMAKE_C_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe")
set(CMAKE_CXX_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe")

注意事項としては、なんか知らんけど、パスの区切りはバックスラッシュ(円マーク)だと怒られる。スラッシュにする必要がある。あとは、もし Visual Studio 2015 以外を使いたいなら、14.0 のところをもちろん自分の数字に変えるべし。

matlab/CMakeLists.txt の編集

このままビルドすると、 matlab で実行しようとしたときに mex が見つからないよ、みたいに怒られる。正確には、

Undefined function 'caffe_' for input arguments of type 'char'

だったと思う。このエラーを回避するために、MEX File Missing during Installation · Issue #5219 · BVLC/caffe · GitHub にあるとおり2行追加する(61行目あたり)。

set_target_properties(matlab PROPERTIES 
                                 RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/matlab/+caffe/private)

set_target_properties(matlab PROPERTIES 
                                 RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/matlab/+caffe/private
                                 RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/matlab/+caffe/private
                                 RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/matlab/+caffe/private
)

とする。

実は最初にビルドしたときはこれを知らなかったので、後で上記の修正をしてから再度ビルドしたら大丈夫になった。

mnist のテスト(シェルから)

WindowsでCaffeをビルドしてGPUで実行する - TadaoYamaokaの日記 にあることに近いのだが、いくつか注意や相違があるのでメモ。

  • 記事にある通り、シェルスクリプトを使うので、ここまで使ってきコマンドプロンプトではなく、ここからは Unix 系のシェルを使う。記事には MSYS とあるが、僕は前に入れていた Cygwin で問題なく動いた。
  • 使うシェルスクリプトファイル(.sh ファイル)たちの改行コード (EOL) が Win の CR+LF になっているので、うまくいかない可能性がある。たとえば、Notepad++ で開いて、menu > edit > EOL conversion > Unix (LF) とすればよい。

念のため、やることもまとめておく。

  • data/mnist/get_mnist.sh を編集:
    • 改行コードを LF に変える。
  • examples/mnist/create_mnist.sh を編集:
    • 改行コードを LF に変える。
    • BUILD=build/examples/mnist → BUILD=build/examples/mnist/Release へ変更(環境によっては違う場所可能性あり)。
    • convert_mnist_data.bin → convert_mnist_data.exe へ変更(2か所)
  • examples/mnist/train_lenet.sh を編集:
    • 改行コードを LF に変える。
    • ./build/tools/caffe → ./build/tools/Release/caffe へ変更(環境によっては違う場所可能性あり)。

以上が終わったら、Cygwin などから、

./data/mnist/get_mnist.sh
./examples/mnist/create_mnist.sh
./examples/mnist/train_lenet.sh

の順に実行する。GPU の場合、GPU-Z やタスクマネージャ(Windows Fall Creators Update適用済の場合)を見るとちゃんと作動していることがわかる。

classification_demo.m のテスト(matlab上で)

matlab はインストール済みとする。

手順は以下の通り

Net.m ファイルの編集

caffe/matlab/+caffe/Net.m の編集について。これは結構ググったのだが、結論としては、https://github.com/BVLC/caffe/pull/5588#issuecomment-303673915 を参考に、72-74行目にある

if ~isempty(self.hNet_self)

コメントアウトして、

if self.isvalid

を記述する。

これで問題なくデモが走るようになった。結果は 1000x1 の配列で、中身チェックしてないけど、エラー出てないからたぶんいいんじゃないか…(疲れた)。

実は変更内容はわかっても変更箇所がわからなかったので、上の github スレッドからリンクしていた(同じ meixiaofeng さんによる) https://github.com/meixiaofeng/caffe/pull/1/files を見て変更箇所を特定した。しかし、これだと変更前のソースになぜか if がないことになっている…。バージョンが微妙に違うのかもしれない(?)。まぁなんにせよ if self.isvalid で走ってるから、いいか。

ほかにハマったところ

ウェブ上の情報がまちまち

現時点 (2017-11-08) での最新バージョンでの入れ方は、「scripts\build_win.cmd を直接テキストエディタでいじって、その後に実行せよ」というもの。しかし古い自家ビルドとかだと、Winであっても、「違う設定ファイルをいじって、Caffe.sln というのを Visual Studio でビルドしろ」とかあって混乱した(やってみたが python 2 のせいっぽい、文字列をダブルクオーテーションで囲ったところの syntax error が連発して死んだ)。結局、現時点では、公式の build_win.cmd でいけるようだ。現時点では。

環境変数の名前を typo した

VCTargetsPath を VcTergetsPath と2重に typo していた。と思ったけど Windows の variables は NOT case-sensitive なので Vc はまだよかった。Tergets がひどい。つらい。

Cmakeが依存ファイルのダウンロード中にWindows download Prebuilt Dependencies.cmakeエラーで止まる

これは proxy が原因だった。Cmake の(あるいはファイルダウンローダの?)設定方法がよくわからなかったし、ググるのに疲れていたので、VPNで回避した。VPNで回避できたということは、確実にproxyのせいともいえる。

気づいたキッカケは、エラーメッセージでググって、これ→ python - Cmake error at Windows download Prebuilt Dependencies.cmake:54 file Download hash mismatch - Stack Overflow を見て、通信関係の問題と言ってるので、「じゃあまた proxy だろどうせ…」→ 当たりだった。

シンポジウム「捕食・被食と殻の役割」のメモ

前置き

日本甲殻類学会・日本貝類学会共催シンポジウム「捕食・被食と殻の役割」 日本甲殻類学会・日本貝類学会共催シンポジウム「捕食・被食と殻の役割」 :: 日本甲殻類学会

に行ったので、メモ。

シャコパンチ

これを聴きたくて(というか加賀谷さんに会いたくて)行った。

  • シャコパンチは「水中で」最速の運動→では水の外で最速な運動はなんだろう?
    • しかし「最速」の定義と「運動」の定義が必要ではある。
    • おそらくここで問題にしているのは「胴体座標系での、体の一部分の」「瞬間的な有次元の加速度(あるいは速度かも)」。
    • たとえば「慣性座標系での」「有次元の速度」だと、おそらくは急降下中のハヤブサとかになってしまう。
  • 個体差が大きい…
  • 腕は(?あるいは受ける側の腹部だったかも)microcrack に強い特殊な構造
  • 撮影は30,000--50,000 fps (!). さすがにめちゃくちゃ速い…!シャッタースピードなども知りたいな→論文読もうか
  • エネルギはどうやって評価するのか?→力積をとってるぽい?→論文読もう
  • シャコは自分のパンチが見えるのだろうか?
    • パンチは速すぎるので、途中では見えていないっぽい?
    • では着弾観測はどうやるのか?視覚・触覚いずれか?両方?
    • パンチが遅いスピアラでも、一度モーションを始めると途中での制御は不可能らしい(スピアラも弾性エネルギ開放でパンチしてるってことかな)
  • 逃げる(動く)相手は叩けるの?
  • 1発目を逃した時に次弾装填 (loading) して再発射するのは可能?
    • 貝のように動かない相手ならできそうだが…
  • 一度途中まで弾性エネルギをためた後で、「やっぱりもうちょっとロードしよう」という追加でのロードはできるのか?しているのか?
    • バネを使わずにふつうに筋肉だけで動かすことはできるという話だった
  • パンチをする腕、上反角方向の回転は可能
  • 叩く前に(殻が相手の場合?)たくさん触っている
    • 何をチェックしている?材質?
    • 「本物の殻でないもの」を叩かせているが、その影響はどのようなものがあるだろうか。より一般的に言うと、叩く相手の硬さに応じてパンチの強さを変えたりしないのか。

シャコパンチ以外の講演

貝の生痕

  • 孔はともかく、カニがバキっとやったやつって、他の外力によって壊れたかどうかの区別を付けられるんだろうか…?
  • ゴカイが貝殻に孔を開けるという話があった。「隔壁があると穿孔がそこで止まる」と言っていたが、なぜなのかがわからなかった。質問もしたのだが、答えが理解できなかった。「掘る側に深さ制限があるのか?」と訊くと「そうだ」と言っていたと思うが、後で考えると、それなら隔壁などなくてもいいだろう。また、隔壁で物理的に止めるということなら、そもそも中空にする理由がわからない。中実でよいのでは?浮力の確保なのか?

タナイス

  • 脚の先端にある鱗みたいな構造、ヤドカリと同じくすべり止めだろうという話だった。ヤドカリにあるのを知らなかった。水棲昆虫のやつとも似てるんだろうか。

幾つかに共通

  • 貝に色を塗ってマーキングするという話があった。被食・捕食というシンポであるのにツッコミがなかったのでおそらく一般的な手法なんだろうけれど、素人からすると、その色を変えたことによる被食率みたいなものの変動がないの?ってのが気になった。
  • やはりある程度小さいものについては CT が強いなと思いました。お金払って計測してもらうのも十分にありかもしれない。
    • 種類によるかもしれないけど、僕が使用経験のある Artec の Space Spider はあまりにも細かな構造を調べるのは無理。おそらく SfM も同様? SfM は画素によるのかな…だとしたら表面については意外と SfM まだポテンシャルあるのだろうか…
  • 水の抵抗みたいな話はほとんど出なかったですね…ですよね…

UPDATE 2017-10-27

加賀谷さんに(2017-10-11付で)リプライのエントリをもらっていた:

katsumushi.hatenadiary.com

とりあえずリンクのみ。

Fluentメモ:periodic boundary condition の offset には符号がある

Periodic だからどっちからどっちでもいいじゃん、と思っていたんだけど、そうではなかったという話。周期境界は、Mesh interface で設定する。このとき、デフォルトだと offset 量は自動計算される。たとえば、2つの境界が y=0 と y=1 にあった場合、offset 量は「y が 1」と自動で計算される。もしinterface 1 に y=0, interface 2 に y=1 の面を選んだら、これで何も問題はない。しかし、逆に interface 1 に y=1, interface 2 に y=0 の面を選んだ場合は、offset 量は正しくは「y が -1」でないといけない。これでちょっとハマった。

メモ:Fluent case & data files --> EnSight format --> read in ParaView

前置き

ハマったところを中心にメモ。

状況としては、既に結果ファイルの cas & dat (時系列データ)があるが ParaView で開きたい、そしてどうやら EnSight 形式じゃないとまともに読めないっぽい、なんとかしたい、という感じ。

環境

  • Windows 10, 64 bit
  • Fluent 18.1
  • ParaView 5.4.0-RC2 64bit

手順

Fluent データの下準備

準備が必要。まず、gzip 圧縮されたデータファイルはなぜか変換してくれないので、全部解凍しておく必要がある。面倒だが仕方がない。次に、ファイル名について、詳しくはマニュアル(https://www.sharcnet.ca/Software/Ansys/16.2.3/en-us/help/flu_ug/flu_ug_file_export_esight.html でも多分大丈夫)を読めばいいのだが、簡単に書いておく。

「メッシュの変形や移動がなく、case ファイルが一つだけの場合」を考える。このとき、case ファイルは[一つ目の data ファイルと同じ名前].cas」にしておく。具体例をあげると、

  • test-001.cas
  • test-001.dat
  • test-002.dat
  • test-003.dat
  • test-004.dat

という感じにリネームしておくとTUI上での作業が楽。

Fluent 上

まず適当な workbench(新規でもいい)を開いて、新たに fluent モジュールを適当なところにおいて、Solution の方をダブルクリックして起動。というか直接 fluent 起動してもいいのかな。おそらくここで、たぶん case ファイルを読み込んだほうがいいが、読み込まなくてもなんとかなった。まぁどうせコマンド入力してる途中で読むんだけど。

TUIウィンドウをクリックしてコマンド入力モードに移る。

ここでまずつまずいたのだが、実はこいつ、pwd で現在のディレクトリ確認できる。すると、なんか変なところにいるはず(いつもの作業フォルダの dp0/FLU みたいなとこね。WBで確認できる場所)。じゃあ pwd ができるんなら cd もできるよね、とやるとできなくて死にたくなる。 Change current working directory with a text command? -- CFD Online Discussion Forums によると正しいコマンドは sync-chdir [path] だという。知るかよ…。とにかくそれで所望のファイルがあるディレクトリへ移動する。

あとは https://www.sharcnet.ca/Software/Ansys/16.2.3/en-us/help/flu_ug/flu_ug_file_export_esight.html などにあるとおりに、コマンドを入力していけばよい。

具体的には、まず

file/transient-export/ensight-gold-from-existing-files

を入力する。すると、色々ときかれるので答えていく。

たとえば以下のようにする:

  • EnSight Case Gold file name test_ensight
  • Case / Data file selection by base name? [yes]
  • Case / Data file base name test
  • Specify Skip Value [0](黙ってEnter)
  • Cell-Centered? [no](黙ってEnter)
  • Write separate file for each time step for each variable? [no](黙ってEnter)
  • Write in binary format? [yes](黙ってEnter)
  • Specify Data File Frequency [1](黙ってEnter)
  • Separate case file for each time step? [yes] no(今は case ファイルが1つしか無いので)
  • Read the case file? [yes](黙ってEnter)
  • Case file name [“test-0-001.cas”] test-001.cas(違うファイル名をサジェストされたので変更)

ここで一度ケースファイルが読まれて、グリッドが読まれる。

  • cell zone id/name(1) [*](黙ってEnter…よくわからんけど行けた)
  • cell zone id/name(2) [()] (黙ってEnter…よくわからんけど行けた)
  • Interior Zone Surfaces(1) [()] (黙ってEnter…よくわからんけど行けた)

  • Select the variables to be exported

  • EnSight Case Gold scalar(1) else q to continue>

これは「どの変数を export するか」ということ。何も書かずに Enter したらリストが出るのでそこから選ぶ。pressure とか x-velocity, y-velocity, z-velocity とかすればいいんじゃないかな。選択が終わったら q と書いて Enter すれば変換が始まる。

ParaView

出てきたファイルのうち、.encas というのが ParaView で読むべきケースファイル、なのだが、このままでは ParaView の reader が認識しないので、拡張子を .cas に変える。実は、いちおう、選択肢の一番下にある All files を表示させ、.encas を開いてから、reader として EnSight を選べば同じことはできるが、単に時間がかかるので、もう変えちゃったほうが早いと思う。

ParaView で開いたら、そのままでは流体領域が全部見えていて(というか外側境界だけ見えているはず)全然使えないので、 Recovering Fluent surfaces in ParaView -- CFD Online Discussion Forums にあるとおり、Extract Block フィルタをかましてやると、Multi-block Dataset という認識になって、壁面とかを選択できるようになる。

ちょっとずつ追記中…

Docker で jupyter notebook から Caffe を試した

前提

Caffe を試したくなったが環境構築に苦労したのでメモ。

なので CPU モードしか試していない。

最初はふつうにビルドしようとしたのだが、依存関係が多すぎたり、python 2 なのか 3 なのか OpenCV も 3 なのかなんなのか、conda がいいのか悪いのか、などなど色々と困って、Makefile.config を何度書き換えても失敗し、しんどくなったので、Docker を試してみた。自分は Docker も機械学習も全くの素人でこれが初めての試み。

手順

まず Docker for Mac をふつうにダウンロードしてきてGUIでインストール。起動。

次に、jupyter と Caffe などの色々なパッケージが入った Docker 用イメージファイルを公開してくれている人がいた ( https://github.com/floydhub/dl-docker ) ので、

$ git clone https://github.com/floydhub/dl-docker

としてダウンロード。

しかしこのあとマニュアルにあるとおりのコマンドで jupyter を起動すると kernel が起動しなかった。対処法は、フォーラムにあるものを微妙に改変して、

$ docker run -it -p 8888:8888 -p 6006:6006 floydhub/dl-docker:cpu sh -c 'jupyter notebook --ip=0.0.0.0 --no-browser'

でいけた(フォーラムのコマンドは floydhub/ がない)。

これで docker 内の仮想マシンみたいなものに入るので、その中の /opt/caffe/example (だったかな?)へ辿っていき、そこにあるサンプルの notebook を開いていつものように実行する。というところまでやった。

チュートリアルの0番と1番は、GPUのところをちょこっとCPUに書き換えたら問題なし。具体的には、

caffe.set_device(0)
caffe.set_mode_gpu()

というところが何箇所か出てくるので、これら2行をコメントアウトし、

caffe.set_mode_cpu()

に変える。

しかしチュートリアルの2番は画像をDLした後あたりでクラッシュする…。これはまだ解決していない。

参考

今回使わせてもらった Docker は、

Installing all the deep learning frameworks to coexist and function correctly is an exercise in dependency hell.

とあるので複数の deep learning フレームワーク環境を共存させるのが大変、というモチベーションだったようだ。

読んだ:A general scaling law reveals why the largest animals are not the fastest

論文の情報

前書き

僕は動物の飛行の力学(主に流体力学)が専門で、最近は遊泳にも手を出し始めた程度で、歩行・走行は専門ではない。

統計については、最近ようやく勉強を始めたところだけれども、全くの素人であり、この論文の統計手法に関する評価をすることはできない*1

それから、筋肉の話がでてくるけど、生理学についても素人なので、以下では正確性を欠く記述をしている可能性がある。

内容まとめ

概要

いろいろな動物について、水平移動の最大ダッシュ速度(≠巡航速度)を縦軸、体重(質量)を横軸にとった散布図を描く。そうすると、だいたい、小さいほど遅くて、大きいほど速い傾向がある*2。この傾向を、うまく表すような、シンプルな曲線(を表す数式)は、従来の理論では、power lawべき乗則?)といって、「大きければ大きいほど速い」ような数式が提案されていたようだ (第1式; Bejan & Marden, 2006, J. Exp. Biol., 未読)。本研究では、よりよいフィッティングとして、「最大の動物よりもちょっと小さいあたりの動物が一番速い」ような、形としては ∩ のようになる曲線(を表す数式)を提案している。実際に、複数のモデルを比較したところ、提案している新しいモデルが一番よいフィットになった。また、歩行・遊泳・飛行という3つの運動(移動)方法の全てについてこのモデルはフィットした。さらに、いまの世の中にいる生物だけでなくて、化石になった生物、たとえば恐竜の速度をも予測できるはずだとしている。実例として、いくつかの恐竜について、形態学をもとにした推測値と、モデルによる推測値がわりとよく合っていることを確認している。

もうちょっと踏み込んだ内容

当然だけど以下は僕の理解。生理学的な部分などで間違いがあるかもしれない。

速度に「小さいほど遅くて、大きいほど速い傾向」があるのはなぜだろうか。この論文では以下のように説明してる。運動には無酸素運動 (anaerobic) と有酸素運動 (aerobic) の2種類があり、それぞれ筋肉の速筋と遅筋に対応している。速筋は素早い運動を可能にするけれど継続時間が短い;遅筋は逆に遅いけれど継続時間が長い。いま注目しているのはダッシュ速度なので、無酸素運動・速筋が関係していそうだ。ポイントは、速筋は継続時間が短いということ。この影響を考慮したのが今回提案するモデル。

要点は Figure 1 にまとめられている*3。これは上段の左右 (a, b) と下段の左右 (c, d) がペアになっている。まず、上段は(従来の)理論的な予測で「無限に加速できるとしたら、速度は体重の順番になる」ということ。ここでもう一つのポイントは、最大速度に到達するのは体重が大きいほど遅いという点。これは一種の2乗3乗則ということでいいのだと思う。力は筋肉の断面積つまり長さの2乗に比例するが、質量(体重)は3乗に比例する。したがって、加速度 = 力/質量 は長さの1乗に反比例する…つまり、大きいほど加速が遅い。まぁ、直感的にも、小型飛行機と大型ジェット機の離陸とか見てればわかるんじゃないかと思う。

ところが実際には、速筋が蓄えられるエネルギ (ATP) には限界があるので、有限の、けっこう短い時間しか加速することはできない。この影響を考慮すると、体重がとても大きな(重い)動物は、加速度が小さいために、速筋のエネルギを使い切った時点ではまだ十分に加速しきれていない、ということになるようだ(下段)。逆に、これはハッキリとは書いていないのだけれど、あまりにも小さい(軽い)動物だと、速筋のエネルギを使い切るよりも前に加速しきってしまうようだ。こうしたことから、結果として「実現できる最大ダッシュ速度」は、体重の順番にはならず、「ちょうど速筋のエネルギを使い切る頃に十分に加速しきる動物」すなわち「一番重いやつよりもちょっと軽いやつ」が最速、ということになる。

このように、提案している新モデルでは筋肉のことを考慮しているけれど、地面から受ける反力とか水流や風の影響は全く考慮していない。個人的にはこのあたりが気になるのだけれども。

手法

  • 文献を調査して、622データ(474種)の最大(ダッシュ)速度と質量の情報を取得。
  • 提案モデルを含む、複数のモデル(数式)をこの速度-質量の関係にフィッティング(Rを使用)。
  • フィット具合は Bayesian information criterion (BIC) で評価。
  • Residual variation analysis → ここは僕の知識不足でよくわからず。内温性・外温性の比較もやっている (figure 3) ようだがいまいちわからなかった。

感想

たまには時系列で感想を綴ってみるのもいいかもしれないと思うのでやってみる。

twitter で存在を知り、AFPBB のニュース記事を読み、論文のアブストと図をチラッと見た時点では「おっすごそうじゃん」という印象だった。「歩行・遊泳・飛行という複数の移動様式における最大速度」がひとつのモデル(数式群)で表現できるという売り込み。どうやら、筋肉の収縮かなにか、生理学的な発想がもとになっているようだ。「あぁ、そっち系なのかな。流体力学はどれくらい考慮されているのだろう?」僕は力学屋なので、このモデルというのが力学をどれほど考慮しているのか、あるいはデータに合うようにフィッティングしただけで力学的メカニズムは考慮していないのか、という点がまず気になる。歩行では地面との接触による地面反力 (ground reaction force, GRF) だけを考慮して流体力学的な考慮はしなくていいのかもしれないが、遊泳では水の抵抗(抗力)を受けるし、飛行では抵抗に加えて重力に対抗するだけの揚力を生み出す必要がある。そしてこれら流体力学的な力というものは、物体のサイズによって影響を受ける。そこでまず、論文本文をダウンロードして、いくつかのキーワード(やその断片)で全文を検索した。具体的には、drag(抗力), lift(揚力), force(力), fluid(流体), aero*4, hydro*5 あたりで検索した。すると force は多少ヒットするが3/5が muscle force であり、aero はヒットした9つ全てが aerobic か anaerobic, hydro は参照文献のタイトルで1ヒットのみ。よって「あぁ、やはり筋肉の生理学は考慮しているようだが、流体力学は考慮していないようだな」という事がわかった。この時点で熱狂は少し落ち着き、「うーん、深く読むのは後でいいかな」となった。僕が興味あるのは、流体力学的な考慮がなされたモデルだからだ。

ところがアブストをよく読むと、このモデルは「474種 (species)」ものデータで支持されているという。これがひっかかった。少なくとも飛行に関して、正確な最大速度というのはそんなに多くは計測されていないという印象が僕にはあった。「このうち飛行ってどれくらいあるんだろう?」という疑問がわいた。そこで、イントロダクションも結果もすっ飛ばして手法 (Methods) を見に行った。ここで最大速度は具体的には文献から “maximum speed”(最大速度)、“escape speed”(逃避速度)、“sprint speed”(スプリント速度…おそらく短距離ダッシュのことだろう)のキーワードで検索したとある。さらに以下の2つの速度を除外している:

  1. 垂直方向の速度。主に鳥の文献に多い。要は急降下で最速になるということだろう。重力加速度により速度を得てしまうが、これは今回のモデルに入っていないため除外するとのこと。
  2. 通常速度のうちの最大値。これは「including also dispersal and migration(分散や渡りを含む)」とあるので、要は、長時間に渡って維持が可能な最大巡航速度のことだろう。

本文をすっ飛ばしていたので、ここで初めて最大速度というものが実際には「水平方向の」「ダッシュ速度」だとわかった。前者はなんとなくそうかなと思っていたが、後者が意外で、僕はここを読むまでは maximum speed とは「最大の巡航速度」のことだと思っていた*6

続けて、"622 data points for 474 species (see Supplementary Table 1 for an overview)“ とある。どうやら本文中にはデータ数の内訳がなく、supplementary material を見ろということのようだ。

…なんか時系列で書くのに疲れてきたので、ここからはまた要点のみの記述にします…

出典について

本文中で使用されたデータセットの出典は supplementary information*7 に明記されている。しかし、

  • データ数の少なさ
  • 出典調査のずさんさ

の2つの問題があると思う。

追記:出典の表をPDFでのみ提供していることも大きな問題だわ…。CSVにすべきだ。

遊泳と飛行のデータ数

走行(歩行)に比べて遊泳と、とくに飛行のデータ数が少ない。具体的には、

  • 走行:458データ(節足動物50・鳥類3・哺乳類261・爬虫類144)
  • 遊泳:109データ(節足動物1・鳥類5・魚類81・哺乳類16・軟体動物5・爬虫類1)
  • 飛行:55データ(節足動物19・鳥類29・哺乳類9)

となっている (Supplementary Table 1)。統計学的にどうなのかはわからないけど、まぁ、当然、多いほうがよりよいフィッティングになるんだろうってことくらいは想像できる。

個別に見ると、たとえば遊泳する節足動物と爬虫類のデータが1ずつしかなくて、これらはモデル生成に使っていない、といったことも disputable かもしれない(ないものはないのでしょうがないが)。

出典調査のずさんさ

孫引きやひ孫引き(?)が多く、出典調査がずさんである(手間を惜しみすぎている)。したがって出典の信頼性に対する配慮が充分なされているかが疑わしい。

オンライン・ウェブページを出典とすること

出典 96 から 103 はオンラインのウェブサイトとウェブページである。基本事項として、ウェブページの情報は永続性に乏しく、ほとんどの場合は自らの研究ではなく他人の情報の転記や引用であり、査読を経てもいない。当然、扱いには注意が必要だ。

たとえば出典101は www.speedofanimals.com というサイトで、おおもとの出典はなんだろうと思うと、一番下の方に “Animal descriptions are from Wikipedia” と書いてある。英語版ウィキペディアは比較的出典がきちんと整備されている印象があるので、値としては間違っていないのかもしれない、と思いたくはなる。ところが、speedofanimals.com のリンク先URLは www.wikipedia.org とだけなっており、個別の動物についてのリンクではない。英語版であるという保証もない。いつ時点という情報もない。Wikipedia は誰でも書き換えられる wiki なので、「いつの時点の版(バージョン)」という「版指定」がないと、出典としての正確性が劣ることになる*8

しかしそもそも、研究者として、ウィキペディアから転記したサイトをさらに孫引きするというのは正直にいって驚愕した。これはつまり、ウィキペディアにある情報を自分たちでチェックすることを怠り、このサイトに丸投げしているということだ。正しい態度は、ウィキペディアへは当然あたり、さらにそのウィキペディア記事が論拠としている原著論文へあたることだろう。こんなのは基本中の基本で、研究室なら学部生がゼミで指摘されるくらいのことではないだろうか。それを、データをフィッティングしている、データに強く依存した論文で、そのデータをきちんと遡っていない、なんていうのは、本当に、ちょっと、どういうことだ…。しかも、Nature 関連ジャーナルに載るような論文で*9

「そうはいっても、そういう疑わしいデータは、450とかあるデータ点のうちの、ごくごくわずかなんでしょ?」と思うだろうから、速度だけについて、いくつあるかを数えてみた*10

  • 走行:27/458 (5.9%). 内訳は、哺乳類23/261*11, 鳥類2/3, 爬虫類2/144.
  • 遊泳:17/109 (15.6%). 内訳は、鳥類3/5, 魚類9/81, 哺乳類4/16, 軟体動物1/5.
  • 飛行:10/55 (18.2%). 内訳は、全て鳥類10/29.

となっていた。特に飛行では20%近い。だから直ちにダメだというわけではないが、もともと少ないデータのうちの2割をきちんと原典まで遡って確認していない、というのは、信頼性を損ねる行為だと思う。

書籍を出典とすること

これ自体は批判されるような行為ではないのだけれど、やはり査読を経ていない(だろう)し、孫引きなので、もっと sharper な引用の仕方をして欲しいところだ。つまり、多くの本というのは自分で独自に計測したデータを載せることはなくて、さらなる出典があるだろうから、そちらの方を引用すべきではないか、ということ。たまにそうやって調べていると伝言ゲームの過程でデータの転記ミスに気づくこともあるし。

なお、飛行では10/55(節足動物2/19, 鳥類8/29)が出典11番の本に依存している (http://press.princeton.edu/titles/162.html)。出典11番のところには2015年発行とあるが、実際には初版1965年の本の復刻であり、データとしてはかなり古い。他の分野は知らないが、動物飛行のデータで1965年というのは、計測方法などの面から不安が残る。さらにこの本のタイトル “An Essay on” というのがまた不安を掻き立てるが、中身は確認していない。鳥類については、ウィキペディアとこの本とで18/29=62%のデータを占めることになるのだが、僕なら怖くて原典を徹底的に確認しないとフィッティングなんてする気になれない。

あとは書籍じゃなくて査読済み論文だけど孫引き、ってのもあって、それはさすがに(原典の年代や手法などを一度確認しておけば)いいかなぁ、と思います。走行の出典44番と80番がかなり多い模様。

twitter でのツッコミ

以下のようなツッコミが見られた(他にあったら追加するかも)。

ハヤブサ

うーむ。まぁニュース記事はしょせんニュースなので、「論文をよく読んでなかったんですねー」で終わるかもしれないけれど、ちょっとそれだけじゃないんだよなぁ…。このハヤブサの出典は AllAbout からの孫引き: www.allaboutbirds.org/guide/Peregrine_Falcon/lifehistory ←このページには出典が5つ挙げられていて、このどれかが原典だろうとは思うが…(そしてその本の中にまた本当に原典が…)。いやいや、待って待って、その前に、AllAbout には 110 km/h という数字はないぞ。引用すると、

reaching speeds up to 112 km/h (69 mph) in direct pursuit of prey

とある。これ自体がまずちょっと問題で、112 km/h = 約69.59 mph (miles per hour) または 69 mph = 約111.05 km/h だから、記述自体が不正確だ。ただ、いずれにしても 110 km/h にはならない。これが 110 km/h になった可能性は2つありそうで、ひとつは論文執筆者がアクセスした時点では 110 km/h と書かれていた可能性*12。もうひとつは、論文執筆者が勝手に1の位を丸めたか、69 * 1.6 = 110.4 -> 110 km/h というような雑な計算をしたか。なんにせよ、「雑だなぁ」という印象を受ける。

カジキ

これは気づいてなくて(遊泳ちゃんと追いかけてなかった)、「え!?桁違いじゃん」と思ったけど、これもまた孫引き問題でした。しかもけっこう根が深い。

  • 出典10番のその “Direct … blue marlin” (Block et al., 1992, J. Exp. Biol.) は black marlin (Istiompax indica) = 130 km/h および blue marlin (Makaira nigricans) = 75 km/h の速度の出典として載っている。この論文はタイトルの通り blue marlin (Makaira nigricans) の計測をしている。そして指摘の通りこの論文における直接計測の最大は 8.1 km/h なのに、どうなっているのか。
  • 本文を「130」で検索すると Table 1 にある Walters (1962)。また、blue marlin の75 km/h は Walford (1937) とある。いずれも Estimate とある。実測値ではないようだ。しかし References を見ても Walters 1962 なんてものはない(たぶん載せ忘れ)。ググるしかない。こっからまた遡ります。
    • なお、この論文の本文で一番関連ありそうなところを抜き出すと、"The fact that they can strike a bait trolled at 800 cm s-1 leaves no doubt that they are capable of short bursts of high-speed swimming, but we saw no such rapid movements in 160 h of speed observations. High-speed swimming and agility must have a place in the repertoire of activities displayed by blue marlin but, during the summer near Hawaii, such behavior is rare. There were only infrequent 10 to 30 s bursts of speeds exceeding 200 cm s-1. Short periods of fast swimming are undoubtedly important for catching certain prey, and hence important in terms of survival, but the characteristic mode of swimming we observed for this species was quite slow.“ というわけで、800 cm s-1 (28.8 km/h) という値*13はあるものの、計測できたのは 200 cm s-1 程度だったということになっていて、どうも Walters らの estimation は怪しいのではという雰囲気…(ちゃんと読んでないので違うかも)。
  • おそらく Walters, 1962, Am. Zool. http://www.jstor.org/stable/3881203 がそれ。しかしこれもおおもとではない。 Nursall, 1962 が cite されている。しかも、"Nursall (this issue) questions the validity of the reported swimming speeds of 80 and 90 km/hr for tuna, 130 km/hr for marlin and swordfish and of 120 km/hr for sailfish“ とある。Block et al., 1992 はこの記述を見ていたはずなのに、Nursall には言及すらしていない…。
  • Nursall, 1962 はこれ https://doi.org/10.1093/icb/2.2.127.)) であり、ここには、barracuda(カマス)の計測値が異常ではないかという記述に続いて、"Also suspect then are unconfirmed figures for salmon (45 Km/hr = 28 mph), tuna (90 Km/hr = 56 mph) and martin and swordfish (130 Km/ hr = 81 mph) reported by Barsukov (1960)“ とある。まだ遡るのか…。
  • ところが References を見ると、Barsukov, V. V. 1960. The speed of movement of fishes. [In Russian]; Priroda 3:103-104 とある。はい出ました、Russian. これはちょっと遡れないですね…。どうやらこれが原典っぽいけども。
  • というわけで、ようやく、この 130 km/h は “unconfirmed figures” である(っぽい)ことがわかりました。

えーっと、何の話だったっけ?あ、つまり 130 km/h が怪しい、と。たぶん 75 km/h も怪しい。そして今回の論文に戻って figure 2d を見ると、シルエットからしてもカジキっぽいやつがちょうどピーク付近にいる。フィッティングカーブの形に効いてるんじゃないの?という気がしてくる。遊泳も…大丈夫なのか…?

その他の感想

全体を通して

どうにも、全体を通しての僕の感想としては、「走行(歩行)だけにしとけばよかった(っぽい)のになぁ」ということになりそう。いや、走行もチェックしてないけども。そうとうに穿った見方をすると、「走行のデータから新モデルでーきたっと。でも『少なくとも哺乳類の少なくとも走行について成立する新モデルです』と言ってもなんかしょぼいし、ちょこちょこっと wikipedia とかオンラインサイトとかで飛行と遊泳のデータもサクッと集めてみるかー」→「おぉ、なんかよさげじゃん。すげぇ発見だよ!Nature(系列)だ!!」みたいな感じじゃないのかなぁ…って気もしてくる。うがちすぎかな。

ただ、流体力学的なものを入れたとしても、定量的に変わるだけで、定性的な曲線の形状自体はこんな感じなのかもしれない、とは思う。つまりフィッティングに使うパラメタが大きく変わるけど、一番の大枠は間違っていないのかもしれない。その「大枠」の提唱こそがすごく評価されることなのだ、そんな細かい出典のことやらなんやらにツッコんでいるからお前は万年ポスドクなのだ、とか言われたら死ぬ。

mechanistic ってなに?

これ連呼されてるんだけど、意味がよくわからなかった。Methods の Model fitting のところを読むと、どうやら「単なる数値へのフィッティングではなくて、生理学というメカニズムを考慮している」ということを言いたいようだ、たぶん(自信なし)。確かに、流体力学は考慮していないとしても、生理学は考慮しているのだから、一歩前進ということでいいのだろう。

恐竜

Table 1 と figure 4 がそれ。Figure 4 でグレーの円がモデル生成(フィッティング)に用いた現生動物のデータで、緑の塗りつぶし三角が別の人が計算した恐竜の速度と質量の関係(Table 5 でいう Morphological models の列の値)。出典は supplementary table 5 とその references にある3つの文献。これら恐竜の値は、今回新たに提案したモデル生成には使っていない、つまり独立に計算された値。その割にはずいぶんよく合ってるでしょ、ドヤ、ということ。一方、従来手法の power law を使うと、Table 1 の Power law の列にあるように、体重が小さいうちは Morphological models と合うけれど、体重の大きな種では全然合わない(過大に評価する)。なぜ figure 4 に power law の線を入れなかったのかはわからない。入れたほうがわかりやすいのに。両対数なので、要は右肩上がりの直線になるってことだろう。

*1:個々のデータ点の数値が公開されているので、統計の自習素材として使ってみるのはいいかもしれないなぁ…というのはちょっと思った。ただ、表がcsvとかではなくてPDFなのだよな…嫌がらせかよ… → あとで出典チェックする時にウンザリした…。

*2:速度を体長で正規化、とかは今は考えない。

*3:たぶんこの論文は open access (OA) じゃないと思うので、読めないって人も多いかもしれないけど、僕は非OA論文の図をネットにバシバシUPすることにはまだ抵抗があるので、図は載せません(おそらく多くの場合 fair use とみなされるのだろうという気はするが)。bioRxivにプレプリントがあるのでそちらをどうぞ→ https://doi.org/10.1101/095018 . パッと見で図はだいたい同じように見える。

*4:aerodynamics(空気力学), aerodynamic force などにヒットする。

*5:hydrodynamics(水力学), hydrodynamic force などにヒットする。

*6:僕だったら maximum dash speed とかなにか、定義を読まなくても maximum cruising speed とは明確に区別される用語を使ったかもしれない。

*7:紙の雑誌ではなくオンライン版のみに提供される付録という意味での Electronic Supplementary Material の頭文字から ESM とか呼ばれることもある。

*8:ある人が2071年に、2017年出版の論文の出典を確認しようとして、「ウィキペディアから」とだけ書かれていたらどう思うだろうか?「え、いつの情報だよこれ…」となるだろう。

*9:「査読者なにやってんの」というのはあるかもしれないが、基本的には supplementary material までは査読義務はないはずなので、責めるのは難しい(よくない)かもしれない。

*10:質量は速度に比べると計測が容易で、疑いの余地が相対的に小さいので、とりあえず置いておく。

*11:ただしこのサイトのデータのみに依存した種は5, 6程度で、それ以外は他の出典もある。

*12:AllAbout は wikiではないが、当然、記述は変わりうる。

*13:しかしこれも personal communication なのだが…。

How to compile and load Fluent UDF on Linux

Corrections to the UDF manual (version 18.1)

Due to the following typographical errors, you cannot make the UDF. So you need to fix these:

  • Page 341-341: the path “path/ansys_inc/v181/fluent/fluent18.1.0/src/” is inccorect. In reality, it should be “path/ansys_inc/v181/fluent/fluent18.1.0/src/udf/
  • Page 342: In procedure 5, the file of interest is NOT the makefile.udf2 but makefile.udf . -
  • AND rename the copied makefile.udf to makefile . The manual says Makefile but this doesn’t work.
  • Most importantly, it appears you need to copy the makefile into the each of the subdirectory under the architecture directory, e.g., /libudf/lnamd64/3ddp_host/ and /libudf/lnamd64/3ddp_node/ . This information is absent in the manual at all, which is really annoying. Could be environment dependent? but still…

Then, you should finally be able to do the

$ make "FLUENT_ARCH=lnamd64"

and finish compiling.

Prepare the case and data files

This step is important and should be done carefully. The general idea is to do minimum thing. Particularly, do not play with TUI before saving the case file, which could potentially harmful and might result in unexpected behaviour during the computation in the Linux server. In my case, I encountered a situation where the computation halts at the first dat file saving, which seemed to have been the result of changing the suffix or prefix for the auto-saved files (via TUI). When I discard the Fluent module in the Workbench and made a clean Fluent module, this problem disappeared. So be careful.

Unload the UDF

Don’t forget to “Unload” the UDF when you were checking e.g. the body motion in Windows' Fluent. For that, right-clicking the “User Defined Functions” (under the Tree view) and select “Manage…” then you will see the list of loaded UDFs.

Delete the Dynamic Mesh Zones

This may not be the mandatory (I haven’t checked yet) but probably preferable.

record (log) the actions for journal file

I recently found a very useful feature in Fluent, i.e. record (log) the journal actions. From the menu “File > Write > Start journal…” you can record the actions in a journal file.

Unfortunately, Fluent is not smart enough to convert the GUI actions to the TUI commands in the recorded journal file, i.e. they are simply “Click this button” “Click this tab” or such… So you must find the appropriate TUI commands by yourself… (sigh)

How to load the compiled files using a journal file?

Surprisingly, this fatal information is absent in the manual. The following command should work.

/define/user-defined/compiled-functions load "<NAME OF libudf DIRECTORY>"

How to enable Dynamic Mesh & Create Zone for rigid body motion using a journal file?

Note the following applies only for the dynamic mesh & rigid body motion.

For the simple dynamic mesh,

/define/dynamic-mesh/dynamic-mesh? yes no no no no

and for creating the dynamic zone for a simple rigid-body motion

/define/dynamic-mesh/zones/create <ZONE_NUMBER> rigid-body "<UDF_PROFILE>" no 0. 0. 0. 0. 0. 0. 0.

where you must specify the <ZONE_NUMBER> and <UDF_PROFILE>.

You can check the zone number in the Fluent’s Tree pane > Cell Zone Conditions.

And the udf profile is the one shown in the “Motion UDF/Profile” drop down list in the “Dynamic Mesh Zones” dialogue via GUI. (after loading the compiled UDF). It is something like “move_body::libudf” .