DebianとAnacondaとDeepLabCut

Linux

はじめに

DebianでAnacondaを使ってDeepLabCutの環境構築を行ったときのメモです。
deeplabcut-dockerで仮想環境「sudo deeplabcut-docker gui -v ./home/mackenzie/DEEPLABCUT」を試しましたが、GPUを認識しませんでした。

export DOCKER="sudo docker"

sudo deeplabcut-docker bash -v ./home/mackenzie/DEEPLABCUT

sudo deeplabcut-docker gui -v ./home/mackenzie/DEEPLABCUT

環境

- Debian 12 bookworm
    - nvidia-driver 525.147.05-4~deb12u1
    - nvidia-cuda-dev 11.8.89~11.8.0-5~deb12u1
    - nvidia-cuda-toolkit 11.8.89~11.8.0-5~deb12u1
    - nvidia-cudnn 8.5.0.96~cuda11.7

- Anaconda3 2024.02-1
    - deepLabcut 2.3.9
    - tensorflow 2.10.0
    - tensorboard 2.10.1
    - tensorboard-data-server 0.6.1
    - tensorboard-plugin-wit 1.8.1
    - tensorflow 2.10.0
    - tensorflow-estimator 2.10.0
    - tensorflow-io-gcs-filesystem 0.36.0
    - tensorpack 0.11

GPU関連ライブラリのインストール

ホストであるDebianにインストールします。
「/etc/apt/sources.list」の各行に「non-free」を追加します。

deb http://deb.debian.org/debian/ bookworm main non-free-firmware contrib non-free

システムにインストールします。

sudo apt update

sudo apt -y install nvidia-driver firmware-misc-nonfree linux-headers-$LINUX_HEADERS dkms

sudo apt -y install nvidia-cuda-toolkit nvidia-cuda-dev

sudo apt install nvidia-cudnn

TensorFlowとCUDAなどの関係は下記を参照します。

ソースからのビルド  |  TensorFlow

Anacondaのインストール

Installing on Linux — Anaconda documentation
How To Install DeepLabCut — DeepLabCut

必要なパッケージをインストールします。

sudo apt install libgl1-mesa-glx libegl1-mesa libxrandr2 libxrandr2 libxss1 libxcursor1 libxcomposite1 libasound2 libxi6 libxtst6

下記URLにアクセスして「Skip registration」をクリックします。
「64-Bit (x86) Installer」を右クリックして、URLをコピーします。

Distribution | Anaconda
Anaconda's open-source Distribution is the easiest way to perform Python/R data science and machine ...

または以下から「linux-x86_64」の最新版を右クリックしてURLを得ます。

Index of /

コピーしたURLからAnacondaをダウンロードしてインストールします。
Anacondaを再インストールする場合は「~/anaconda3」を削除します。
最後の質問は、yesを選択します。

wget wget https://repo.anaconda.com/archive/Anaconda3-2024.02-1-Linux-x86_64.sh

bash Anaconda3-2024.02-1-Linux-x86_64.sh

You can undo this by running `conda init --reverse $SHELL`? [yes|no]
[no] >>> yes

~/.bashrcの末尾にAnacondaの環境設定が追記されているので読み込みます。
同時にbase環境が有効になります。

source ~/.bashrc

ログイン時にbase環境を起動しないようにします。

conda config --set auto_activate_base false

base環境などから抜ける場合は、以下を実行します。

conda deactivate

Anacondaのアンインストール

最初から環境構築をやり直す場合です。
仮想環境のDEEPLABCUTを削除する場合はbase環境に戻ってから削除します。

conda deactivate

conda remove -n DEEPLABCUT --all

Anacondaを削除する場合は以下の通りです。
~/.bashrcにAnacondaの設定がある場合は、削除します。

rm -rf ~/anaconda3

rm -rf ~/.condarc ~/.conda ~/.continuum

DeepLabCutのインストール

下記URLにアクセスして「Raw」をクリックしてURLをコピーし、DeepLabCutの定義ファイル「DEEPLABCUT.yaml」をダウンロードします。

DeepLabCut/conda-environments/DEEPLABCUT.yaml at main · DeepLabCut/DeepLabCut
Official implementation of DeepLabCut: Markerless pose estimation of user-defined features with deep...
wget https://raw.githubusercontent.com/DeepLabCut/DeepLabCut/main/conda-environments/DEEPLABCUT.yaml

当方ではimportlib_metadatが足りなかったので、DEEPLABCUT.yamlに「- importlib_metadata」を追加しました。

name: DEEPLABCUT
channels:
  - conda-forge
  - defaults
dependencies:
  - python=3.9
  - pip
  - importlib_metadata   <-- 追加
  - ipython
  - jupyter
  - nb_conda
  - notebook<7.0.0
  - ffmpeg
  - pip:
    - "deeplabcut[gui,tf]"

DeepLabCutをインストールおよびアップデートします。

conda activate

conda env create -f DEEPLABCUT.yaml

conda env update -f DEEPLABCUT.yaml

アップデートしないとdeeplabcut.label_frames関数でPySide6関連のエラーが出ます。(2024.04.30)

AttributeError: 'PySide6.QtGui.QAction' object has no attribute 'menu'

DeepLabCutの実行

ログインしてDeepLabCutの仮想環境を有効にします。

conda activate

conda activate DEEPLABCUT

DeepLabCutをGUIで起動する場合は以下です。

python -m deeplabcut

DeepLabCutをコマンドで起動する場合は以下です。

ipython

In [1]: import deeplabcut

In [2]: from tensorflow.python.client import device_lib
In [3]: device_lib.list_local_devices()

DeepLabCutの解析手順

手順とパラメータの詳細は下記を参考にします。

DeepLabCut User Guide (for single animal projects) — DeepLabCut

この手順で生成されるファイルの構成です。

プロジェクト名-氏名-実行日時
  - config.yaml
  - dlc-models
  - labeled-data
  - training-datasets
  - videos
  - evaluation-results
        - iteration-0
            - プロジェクト名xxx
                - map

解析するビデオの保存ディレクトリ
 - 【解析するビデオ名】DLC_【net_type】【プロジェクト名】【日付】shuffle【iteration回数】.csv
 - 【解析するビデオ名】DLC_【net_type】【プロジェクト名】【日付】shuffle【iteration回数】.h5
 - 【解析するビデオ名】DLC_【net_type】【プロジェクト名】【日付】shuffle【iteration回数】_meta.pickle
 - plot-poses
    - hist.png
    - plot-likelihood.png
    - plot.png
    - trajectory.png
 - 【解析するビデオ名】DLC_【net_type】【プロジェクト名】【日付】shuffle【iteration回数】_labeled.mp4

コマンドで実行した場合です。
iPythonを起動して、DeepLabCutをインポートします。

ipython

import deeplabcut

変数をリセットします。

%reset -f

プロジェクトを作成します。

config_path=deeplabcut.create_new_project('testname', 'as', ['/home/as/DeepLabCut/sample.mp4'], working_directory='/home/as/DeepLabCut/sample', copy_videos=False)

config_path=deeplabcut.create_new_project('プロジェクト名', '氏名', ['学習データ作成用の動画ファイル'], working_directory='作業ディレクトリ' , copy_videos=False)

作業ディレクトリの下に「プロジェクト名-氏名-実行日時」のディレクトリが作成され、ファイル構成は以下となります。

- config.yaml
- dlc-models
- labeled-data
- training-datasets
- videos

既存のプロジェクトを読み込む場合は、

config_path='プロジェクト名-氏名-実行日時/config.yaml'

設定ファイル「プロジェクト名-氏名-実行日時/config.yaml」を編集します。
「bodyparts:」にターゲットの数だけ、任意の変数を記述します。
デフォルトのresnet_50を使わない場合、「default_net_type:」に 「resnet_101」などを記述します。

vi プロジェクト名-氏名-実行日時/config.yaml

例えば、

bodyparts:
- m1
- m2
- m3
- m4

default_net_type: resnet_101

numframes2pick: 20

batch_size: 8

学習データをする作成のため、指定した動画から複数のフレームを抽出します。
「プロジェクト名-氏名-実行日時/labeled-data/動画ファイルから拡張子を除いた名前」のディレクトリの下に保存されます。
デフォルトは20枚です。
変更する場合は、「プロジェクト名-氏名-実行日時/config.yaml」にある「numframes2pick」の数値を修正します。

deeplabcut.extract_frames(config_path, 'automatic', 'kmeans')

GUIを起動して抽出したフレームにラベル付けします。
数値キーで「2:マーカー追加」、「3:選択」、「4:画像の移動」ができます。
保存は「Ctrl +S」、または「File -> Save Selected Layers」です。

deeplabcut.label_frames(config_path)

ラベルのチェックを行います。
「プロジェクト名-氏名-実行日時/labeled-data/動画ファイルから拡張子を除いた名前_labeled」のディレクトリの下に保存されます。

deeplabcut.check_labels(config_path)

トレーニング用データセットを作成します。

deeplabcut.create_training_dataset(config_path)

トレーニングで使う設定ファイル「プロジェクト名-氏名-実行日時/dlc-models/iteration-0/プロジェクト名日付・・・/train/pose_cfg.yaml」を編集します。
global_scaleは、動画に用いるラベリングした点の大きさ。
batch_sizeはトレーニングに使うバッチサイズ。
pos_dist_threshは、正解の大きさ。

batch_sizeはデフォルトが「1」なのでiterationの回数が多くなり、計算量が増えます。
学習結果やGPUのメモリ容量を確認しながら、8、16、32あたりを指定します。
解析する動画にも依りますが、GPUのメモリが24GBの場合、batch_sizeが8だとメモリが足りなかったので、時間が掛かりますが1で行いました。

global_scale: 0.8

batch_size: 8

pos_dist_thresh: 17

トレーニングを行います。
オプションを指定する場合です。
displayitersは、指定した回数ごとに学習過程を画面に表示する。
saveitersは、指定した回数ごとに学習過程を保存する。
maxitersは、反復して学習する回数。

displayitersは数値を小さくした方が進捗状況が分かり易くて吉。
また、saveitersも小さくした方が、途中で割り込んで停止した場合に学習が無駄になりません。

deeplabcut.train_network(config_path, displayiters=100, saveiters=15000, maxiters=30000)

トレーニング結果を評価します。
「プロジェクト名-氏名-実行日時」ディレクトリの下に生成されたevaluation-resultsに評価した結果のCSVファイルと、学習データに予測点を追加した画像が保存されます。

deeplabcut.evaluate_network(config_path, plotting=True)

スコアマップ、Locrefレイヤー、PAFをプロットします。
Indicesが未指定の場合、全てのトレーニングとテスト画像が対象となります。
Locrefは、スコアマップ部位があるかもしれない方向マップ (location refinement) のこと?
evaluation-resultsディレクトリの下にmapディレクトリが生成されます。
DeepLabCut 2.3.9では「shuffle=shuffle」が使えませんでした。

deeplabcut.extract_save_all_maps(config_path, shuffle=shuffle, Indices=[0, 5])

deeplabcut.extract_save_all_maps(config_path, Indices=[0, 5])

動画を指定して解析します。
video_path変数を個別に指定して、以後の手間を省きます。

video_path=['解析する動画のファイルパス']

deeplabcut.analyze_videos(config_path, video_path, save_as_csv=True)

解析結果をプロットします。
解析した動画と同ディレクトリにplot-posesが作成されます。

解析する動画をプロジェクトのディレクトリにコピーしてvideo_pathで指定すれば、プロット後にファイル構成がスッキリするかもしれない。

deeplabcut.plot_trajectories(config_path, video_path)

ラベル付き動画を作成します。
解析した動画と同ディレクトリに作成されます。

plot_trajectoriesと同様に、解析する動画をプロジェクトのディレクトリにコピーしてvideo_pathで指定すれば、プロット後にファイル構成がスッキリするかもしれない。
videotypeは、「‘avi’, ‘mp4’, ‘mov’, ‘mpeg’, ‘mkv’」が可能です。
keypoints_onlyは、ラベルのポイントだけ描画します。

deeplabcut.create_labeled_video(config_path, video_path, save_frames=True, keypoints_only=True, videotype='.mp4')

再トレーニングする場合は、精度の低い部分の動画フレームを抽出します。
抽出方法はoutlieralgorithmで指定します。
この機能はまだ使っていないので、以下の「(M) Optional Active Learning -> Network Refinement: Extract Outlier Frames」を参照のこと。

DeepLabCut User Guide (for single animal projects) — DeepLabCut
deeplabcut.extract_outlier_frames(config_path, video_path, outlieralgorithm=)

yesと入力する。

Comments