docker上でnvidia-smiするとFailed to initialize NVMLが出る

ホストPCでnvidia-smiが正常動作する場合

以下を実行する。

sudo sed -i 's/^#no-cgroups = false/no-cgroups = false/;' /etc/nvidia-container-runtime/config.toml
sudo systemctl restart docker

参考: Nvida Container Toolkit: Failed to initialize NVML: Unknown Error - #3 by SimonBirrell - Linux - NVIDIA Developer Forums

ホストPCでもnvidia-smiでFailed to initialize NVMLが出る場合

以下を実行する。

sudo systemctl stop gdm
sudo systemctl isolate multi-user.target
sudo systemctl stop systemd-logind
sudo killall gdm-x-session

sudo rmmod nvidia_drm
sudo rmmod nvidia_modeset
sudo rmmod nvidia_uvm
sudo rmmod nvidia

sudo systemctl restart docker

nvidia GPU関係のインストール

動作環境

GPUドライバ

インストール

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
ubuntu-drivers devices # ドライバ候補表示
sudo apt install nvidia-driver-*** # 好きなドライバを選択

確認: nvidia-smiのコマンドでGPU状態が表示される

CUDA

公式サイトから好きなバージョンを選択し、自分のPC環境を選んでいく

Installation Instructions通りにコマンドを実行する

# CUDA Toolkit 11.7 Update 1, Linux Ubuntu 22.04 x86_64, deb(local) の場合
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-ubuntu2204.pin
sudo mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.7.1/local_installers/cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.deb
sudo cp /var/cuda-repo-ubuntu2204-11-7-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda

以下を~/.bashrcに書き加えてパスを追加

export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/lib/cuda/lib64:$LD_LIBRARY_PATH"

確認: nvcc -Vまたは/usr/local/cuda/bin/nvcc -VでCUDAの情報が表示される

備考

  • CUDAが対応していないGPUドライバが入っていると自動で削除され、対応しているドライバがインストールされることがある
    • 不要になったドライバはそのままでもいいが以下のように削除できる
      • ドライバ一覧表示: sudo dpkg -l | grep nvidia*
      • ドライバ削除: sudo apt purge [不要ドライバ]

cuDNN

公式サイトから好きなバージョンを選択し、ダウンロード

インストール

# tarファイル形式のcudnnをダウンロードした場合
tar -xvf [対象のcudnnファイル名].tar.xz
sudo cp [対象のcudnnファイル名]/include/cudnn.h /usr/local/cuda/include 
sudo cp -P [対象のcudnnファイル名]/lib/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*

nvidia-docker

リポジトリの追加

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update

インストール

sudo apt-get install nvidia-docker2

再起動

確認: 以下コマンドでエラーなく表示されればOK

nvidia-container-cli -k -d /dev/tty info

備考

tensorflow

インストール

pip install tensorflow-gpu

確認: 以下コマンドでPhysicalDeviceとしてGPUが認識される

python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"

備考

  • 公式の要件(CUDA 11.2, cuDNN 8.1.0)でなくても動いた
    • 動作確認条件: tensorflow-gpu==2.11.0, CUDA 11.7, cuDNN 8.6.0
  • import時に出るCould not load dynamic library 'libnvinfer.so.7'..., Could not load dynamic library 'libnvinfer_plugin.so.7'..., TF-TRT Warning: Cannot dlopen some TensorRT libraries...について
    • tensorflowのグラフを最適化してくれるTensorRTがないというだけで無視しても動作はする
    • あるとパフォーマンスが上がる(インストール方法)
  • import時に出るsuccessful NUMA node read from SysFS had negative value (-1)...について
    • Ubuntuの仕様でGPUのNUMA nodeが-1となっているので0と認識しましたよというだけなので問題はない
    • NUMA node: マルチデバイスのメモリアクセスを効率化するNUMAの枠組みで割り振られたノード番号
    • 参考

pytorch

インストール

pip install torch torchvision torchaudio

確認: 以下コマンドでTrueと返ってくる

python -c "import torch; print(torch.cuda.is_available())"

pythonのvenvを活用する

venvを使ってpythonの仮想環境を活用する方法をまとめる。

venvについて

venvはpythonの仮想環境を構築するモジュールの一つ。 pythonが公式で出している。

既にインストールされたpythonに依存した仮想環境を構築し、仮想環境ごとに独立のpythonモジュールの環境を作成できる。

仮想環境の作成

ここではpython3.10がすでにインストールされているとする。
まずvenvモジュールをインストールする。

sudo apt install python3.10-venv

venvは仮想環境ごとにフォルダを作成して管理される。
そのフォルダは任意の場所に作成可能なので指定して仮想環境を作成する。

python3.10 -m venv [仮想環境フォルダのパス]

仮想環境に入るには以下のようにする。

source [仮想環境フォルダのパス]/bin/activate

この後はpythonpipが仮想環境のものとして使える。

仮想環境から出るには以下のようにする。

deactivate

VSCode連携

venvはVSCodeと連携してVSCode上のインタプリタやTerminalにvenvのpythonを選択できる。

まず以下のようにして仮想環境があるパスを設定する。

  • VSCode画面でFile -> Preferences -> Settings
  • Python: Venv Pathの項目で[仮想環境フォルダがある一階層上のパス]を入力

そして以下のようにしてVSCodeと連携するpythonを選択する。

  • ctrl + shift + p -> Python: Select Interpreter -> ワーススペースレベルで選択
  • 該当の仮想環境がPythonバージョン('[仮想環境フォルダ名]':venv)と表示されるので選択

この後はインタプリタに仮想環境のpythonが使われ、Terminalも仮想環境に入った状態で立ち上がる。

引き継ぎ

venvは既にインストールされたpythonに依存しているので別のPCに移植する際は一から作成する必要がある。 ただ、pipは以下のようにしてrequirements.txtに書き出せるのでこれを別PCに移す形で移植する。

移植元PC

  • 仮想環境に入る
  • pip freeze > requirements.txt

移植先PC

  • 移植元と同じpythonで仮想環境を作成する
  • pip install -r requirements.txt

venvのシェル名を変更する

以下のようにvenvで作成した時と別の名前でシェル名を変更する。

$ source venv/bin/activate
(hogehoge) $ 

これはvenv/bin/activateのPYTHONHOMEにかかわる箇所を変更する(48-62行目くらい)。

画面の割れたスマホをAnyDeskで運用する

スマホを落として画面がバキバキになってしまった...
画面以外はちゃんと動くのでなんとか活用したい。
そこで遠隔操作アプリを使って別のスマホから操作して運用方法を試してみた。

必要なもの

  • 破損スマホ:画面がバキバキになってしまったスマホ
  • 操作スマホ:破損スマホを操作するための別のスマホ
  • モニター:一時的に破損スマホの画面を映す用
  • USBキーボード:一時的に破損スマホを操作する用
  • Type-C変換アダプター:破損スマホのType-CからUSBキーボードやモニター(HDMIとか)に繋ぐ用
  • 適当なPC:スマホの設定をちょっといじる用
  • AnyDesk:遠隔操作アプリ

破損スマホにAnyDeskをインストール

  • 破損スマホをType-C変換アダプターを介してUSBキーボードとモニターに接続
  • 破損スマホを起動して頑張ってロック画面を突破する
    • 画面は繋げば映ったがPIN入力画面が隠れてしまっていたので大変だった
    • ロック画面からENTER→PIN入力→ENTERでなんとかなった
    • 突破できたらロック画面の設定は解除しておくともうこれをしなくていい
  • キーボードを駆使してAnyDeskをインストール
    • Androidにはデフォルトでキーボードショートカットが登録されているのでそれを駆使していく(参考
    • ショートカット確認:Win+/
    • PlayStoreに行き着く方法
      • Win+Tabマルチタスク画面へ
      • Tabを押すと画面の各項目を選択できるようになるのでその後矢印キーで検索を選択してEnter
      • Win+Spaceで言語を英語に変換してからPLAY STOREと打ち込んでEnter(もう一度Win+Spaceすれば日本語に戻れる)
      • 検索候補にPlayStoreがあるので矢印キーで選択してEnter
    • AnyDeskのインストール
      • PlayStoreの画面の各項目をTabで移動し、検索窓を選択してEnter
      • ANY DESKと打ち込んでEnter
      • 検索結果をTabで移動して、AnyDeskを選択してEnter
      • 後はTabEnterを使ってインストールを続行していく
  • AnyDeskの起動:PlayStoreを起動したのと同じようにしてAnyDeskを起動

操作スマホで破損スマホに接続

  • 破損スマホはAnyDeskの初期画面を開いておく
  • 操作スマホにもAnyDeskをインストール&起動
  • 操作スマホのAnyDeskにリモートアドレスを入力する画面があるので破損スマホ側のアドレスを入力して接続
  • 破損スマホの方で繋いでいいかの確認ポップアップが出るのでTabで許可を選んでいってEnterしていくと接続できる

これで操作スマホからタッチで操作できるようになるのでキーボード&モニタ地獄から開放される

常時接続できるように設定

このままだと接続毎に破損スマホの方で繋いでいいかの確認ポップアップが出てキーボード&モニタ操作から逃れられないので回避するよう設定する。

まずは破損スマホ側のAnyDeskの設定を変えて無人のアクセスを許可する。

  • AnyDesk初期画面左上の≡→設定→セキュリティ
  • Permission Profiles→Unattended Access無人アクセスを許可するにチェック
  • 無人アクセスする際のパスワードを設定

これで行けると思ったが、まだ以下の許可画面が出てくる。

これはAndroid10以上のデフォの仕様で毎回聞く用になってるかららしい(参考)。
これを変更するにはADBを使わないといけないので適当なPCにインストールして以下コマンドを実行してみた。

adb shell appops set com.anydesk.anydeskandroid PROJECT_MEDIA allow
adb shell appops set com.anydesk.adcontrol.ad1 PROJECT_MEDIA allow

※2行目はいらない説あるが一応設定

これによってさっきの許可画面なしに接続することができた。

残課題と対策

AnyDeskのデフォルトの設定で破損スマホ側でAnyDeskが起動されているときだけ接続できるようになっている。
(設定→セキュリティ→双方向接続→AnyDeskのウィンドウがみえる場合のみ許可する)
PCのAnyDeskだと「接続を常に許可する」を選択するとAnyDeskのウィンドウが表示されていなくてもバックグラウンドで動いていて接続ができるようになってる。
なので破損スマホでもその設定にしてみたが、そうすると「セッション作成」画面から進まなくなってしまった(AnyDeskの画面を表示しているときは接続できる)。
「バッテリーの最適化」の対象に入っているからかと対象を外しても変わらなかった。

今できそうな対策としては以下。

  • AnyDeskの接続を切るときには破損スマホ側はAnyDeskの画面にして切る
  • 物理ボタンによるショートカットにAnyDeskを登録する(今回採用)

深層学習以前の強化学習をまとめる

強化学習の観点

  • 何を学習するか
    • 状態や行動の価値を学習: Valueベース
    • 戦略を学習: Policyベース


  • 学習に使う環境をモデル化できるか
    • できる: モデルベース
    • できない: モデルフリー


  • 学習に用いる実績情報はなにか


  • 価値を見積もる際に戦略を考慮するか
    • する: On-Policy
    • しない: Off-Policy


主要な手法をこれらの観点で分類するとこんな感じ

Value/Policyベース モデルベース/フリー モンテカルロ/TD法 On/Off-Policy
Value Iteration Value モデルベース なし なし
Policy Iteration Policy モデルベース なし なし
モンテカルロ法 Value モデルフリー モンテカルロ法 Off-Policy
Q-learning Value モデルフリー TD法 Off-Policy
SARSA Value モデルフリー TD法 On-Policy
Actor-Critic法 両方 モデルフリー TD法 On-Policy

何を学習するか

強化学習では環境が以下の変数で表される。

  • $s$: 現在の状態
  • $a$: 現在の状態からとれる行動
  • $T(s'|s,a)$: 状態$s$で行動$a$をとったときの状態$s'$の遷移確率
  • $R(s,a,s')$: 状態$s$で、行動$a$をとり, 次の状態$s'$に遷移したときに得られる報酬

図にするとこんな感じ

強化学習の目的は指定の期間中(無限でもOK)での報酬の総和を最大化するような制御を得ること。

強化学習では価値と戦略によってエージェントの制御がなされる

  • 価値: エージェントの状態や行動の良否を評価する機構
  • 戦略: エージェントの行動の選択する機構

これらを学習することによってより良い制御を得るが、このどちらを学習するかで分類がされる

Valueベース

  • 状態や行動の価値を学習することで制御を得る
  • このとき行動は戦略に$\epsilon$-greedy法などを用いることで間接的に価値から制御される
  • 手法: 後述のValue Iteration, モンテカルロ法, Q-learning, SARSA, Actor-Critic法など

Policyベース

  • 戦略を学習することで制御を得る
  • 戦略に基づいた状態や行動の価値も学習するが、制御は戦略によってなされる
  • 手法: 後述のPolicy Iteration, Actor-Critic法など

環境をモデル化できるか

モデルベース(環境をモデル化できる場合)

  • エージェントを動かさずシミュレートだけで学習が可能
  • どの行動をするとどういう結果が得られるかのモデルが存在する場合(遷移関数や報酬関数が明らかの場合)に使える
  • 例: 迷路とか

モデルベースの手法: Value/Policy Iteration

Bellman方程式を用いれば強化学習の目的である状態や行動の価値が導出できる。

ValueベースのBellman方程式


\displaystyle
V(s) = R(s) + {\gamma} {\max}_a \sum_{s'} T(s'|s,a) V(s')

PolicyベースのBellman方程式


\displaystyle
V_{\pi}(s) = \sum_{a}\pi(a|s)\sum_{s'}T(s'|s,a)(R(s)+{\gamma}V_{\pi}(s'))
  • $s$: 現在の状態
  • $a$: 現在の状態からとれる行動
  • $s'$: 次の状態
  • $V(s)$: 状態$s$の価値関数
  • $R(s)$: 状態$s$で得られる報酬
  • $T(s'|s,a)$: 状態$s$で行動$a$をとったときの状態$s'$の遷移確率
  • $\gamma$: 報酬の割引率
  • $\pi(a|s)$: 状態$s$で行動$a$をとる確率(戦略を表現)
  • $V_{\pi}(s)$: 戦略$\pi$で行動する場合の状態$s$の価値関数

Bellman方程式を使えば一つ先の状態の価値から今の状態の価値が計算できる。 これを利用して一番最後の状態から逆向きに価値を導出していくことで価値関数が求められる(動的計画法を使って効率的に解ける)。

ただし、この方法では以下のように計算コストが膨大になる。

  • 今の状態$s$の価値$V(s)$の導出には先に全ての行動$a$に関して先の状態の価値$V(s')$を計算する必要がある
  • 先の状態$s'$の価値$V(s')$の導出には先に全ての行動$a'$に関してさらに先の状態の価値$V(s'')$を計算する必要がある
  • さらに先の状態$s''$の価値$V(s'')$の導出には・・・

Value Iteration

これに対し、予め全ての状態に対する価値関数$V(s)$に適当な値が入っていればこの計算をしなくて済み、適当な値が入った$V(s)$はBellman方程式により逐次正確な値に更新していけば計算コストを抑えて$V(s)$が学習できる。 この手法をValue Iterationという。

アルゴリズム

  1. 価値関数$V(s)$を適当な値で初期化する
  2. Bellman方程式を用いて全状態$s$に関して$V(s)$を更新
  3. 2.による更新を繰り返し、$V(s)$に変化がなくなったら終了

2.の更新時に真の価値関数の元となる報酬$R(s)$や遷移関数$T(s'|s,a)$が関与するので、段々真の値に近づいていくイメージ(かな?)。
証明は「UCL Course on RL」のLecture3にあるそうな。

Policy Iteration

先述のValue Iterationのようにして学習した価値関数に基づいて、価値を最大化するような戦略になるようにすれば戦略も学習できる。このようにして価値関数と戦略を同時に学習する手法をPolicy Iterationという。

アルゴリズム

  1. 価値関数$V(s)$と戦略$\pi(a|s)$を適当な値で初期化する
  2. 今の$\pi(a|s)$に基づいて価値関数を学習する(PolicyベースのBellman方程式を使ってValue Iterationを行う)
  3. 学習した価値関数に基づいて価値を最大化するよう$\pi(a|s)$を更新する
  4. 2.,3.を繰り返し、$\pi(a|s)$に変化がなくなったら終了

モデルフリー(環境をモデル化できない場合)

  • エージェントを実際に動かして得た経験から学習
  • どの行動をするとどういう結果が得られるかのモデルが不明、もしくはうまくモデル化できない場合(遷移関数や報酬関数がが不明、もしくはうまくモデル化できない場合)
  • 例: ゲーム、囲碁とか(フィールドや相手が何するかによって環境が変わる)

モデルフリーの手法

後述のモンテカルロ法, Q-learning, SARSA, Actor-Critic法など

学習に用いる実績情報はなにか

モデルフリーで得た経験のうち、何の情報を使って学習するかで分類される

報酬のみから学習(モンテカルロ法)

  • 現在からエピソード終了時刻$T-t$までの報酬を学習に使用する
  • 現在の価値関数が上記の報酬に近づくよう両者の誤差を算出して学習する

※価値関数は解く問題に応じて状態価値関数$V(s_t)$でも状態行動価値関数$Q(s_t, a_t)$でも良い


\displaystyle
Error(s_t, a_t) = (r_{t+1}+{\gamma}r_{t+2}+{\gamma}^{2}r_{t+3}+\dots+{\gamma}^{T-t-1}r_{T-t}) - Q(s_t, a_t)


アルゴリズム

※簡単のため価値関数$Q(s, a)$を行列$Q[s][a]$として考える

  1. 戦略($\epsilon$-greedy法など)に従ってエピソード終了まで行動
  2. エピソード$e$中の状態$s_{t}^{e}$と行動$a_{t}^{e}$について報酬を使って価値行列$Q[s_{t}][a_{t}]$をそれぞれ更新(下式) $$ Q[s_{t}^{e}][a_{t}^{e}] = Q[s_{t}^{e}][a_{t}^{e}] + \alpha Error(s_{t}^{e}, a_{t}^{e}) $$ $\alpha \in (0, 1)$は学習係数

  3. 1., 2.を繰り返す

報酬と見積った価値から学習(TD法)

  • 現在から1時刻先の報酬とそのときの状態価値を学習に使用する
  • 現在の価値関数が上記の報酬と状態価値の和に近づくよう両者の誤差を算出して学習する $$ Error(s_t, s_{t+1}) = r_{t+1} + \gamma V(s_{t+1}) - V(s_t) $$

    • 前述のモンテカルロ法の$r_{t+1}$だけを実際の報酬として観測し、残りは次時刻の状態価値$V(s_{t+1})$で近似しているイメージ
    • この誤差のことをTD誤差(Temporal Difference Error)という
  • 上記は1時刻先の場合であるがこれを$n$時刻先で拡張して考えることができる→Multi-step Learning

    • 一般的に$n=2,3$がよく使われるらしい

TD($\lambda$)法

1時刻〜エピソード終了時刻$T$までのTD誤差を組み合わせる方法


\displaystyle
\begin{eqnarray}
1時刻先での価値&:& W_t^1 = r_{t+1} + {\gamma}V(s_{t+1})\\
2時刻先での価値&:& W_t^2 = r_{t+1} + r_{t+2} + {\gamma}^{2}V(s_{t+2})\\
\vdots\\
T-t時刻先での価値&:& W_t^{T-t} = r_{t+1} + r_{t+2} + \dots + {\gamma}^{T-t}V(s_{T-t})
\end{eqnarray}

としてこれらを$\lambda \in [0, 1]$で重み付けする


\displaystyle
TD(\lambda)法での価値: W_t^{\lambda} = (1-\lambda)\sum^{T-t-1}_{n=1}{\lambda}^{n-1}W^{n}_t + {\lambda}^{T-t-1}W^{T-t}_t
  • 将来の時刻ほど影響が少なくなるようになっている
  • $\lambda=0$のときはTD法, $\lambda=1$のときはモンテカルロ法の価値となるようになっている

Q-learning

TD法を用いて状態価値関数(or行列)$Q$を学習するValueベースの方法

アルゴリズム

  1. 戦略($\epsilon$-greedy法など)に従って1時刻先まで行動
  2. 1時刻先の報酬とそのとき最大の価値を価値となる行動をしたときの価値$Q$を使って価値行列$Q[s_{t}][a_{t}]$を更新(下式) $$ Q[s_{t}][a_{t}] = Q[s_{t}][a_{t}] + \alpha \{(r_{t+1} + \gamma {\max}_{a^{'}} Q[s_{t+1}][a^{'}]) - Q[s_{t}][a_{t}]\} $$
  3. 1., 2.をエピソード終了まで繰り返す
  4. 3.を繰り返す

価値を見積もる際に戦略を考慮するか

学習などで価値を見積もる際に戦略を考慮するかどうかで分類される

Off-Policy

  • 価値を見積もる際に戦略を考慮しない
  • 次の行動は常に価値が最大となる行動を選択する(例: 下式) $$ Q[s_{t}][a_{t}] = Q[s_{t}][a_{t}] + \alpha \{(r_{t+1} + \gamma {\max}_{a^{'}} Q[s_{t+1}][a^{'}]) - Q[s_{t}][a_{t}]\} $$
    • そのため楽観的な価値の見積もりになりやすい
  • 手法: 前述のモンテカルロ法, Q-learningなど

On-Policy

  • 価値を見積もる際に戦略を考慮する
  • 次の行動は常に戦略によって選択される(例: 下式) $$ Q[s_{t}][a_{t}] = Q[s_{t}][a_{t}] + \alpha \{(r_{t+1} + Q[s_{t+1}][a_{t+1}]) - Q[s_{t}][a_{t}]\}\\ a_{t+1} = Policy(s_{t+1}) $$ ※Policy: 戦略(ϵ-greedy法など)
    • そのため比較的現実的な価値の見積もりになりやすい

SARSA

Q-learningの学習に使う1時刻先の価値をとる行動を戦略によって選ぶようにした方法

アルゴリズム

  1. 戦略($\epsilon$-greedy法など)に従って1時刻先まで行動
  2. 1時刻先の報酬とそのとき戦略によって選択された行動をしたときの価値$Q$を使って価値行列$Q[s_{t}][a_{t}]$を更新(下式) $$ Q[s_{t}][a_{t}] = Q[s_{t}][a_{t}] + \alpha \{(r_{t+1} + Q[s_{t+1}][a_{t+1}]) - Q[s_{t}][a_{t}]\}\\ a_{t+1} = Policy(s_{t+1}) $$ ※Policy: 戦略(ϵ-greedy法など)
  3. 1., 2.をエピソード終了まで繰り返す
  4. 3.を繰り返す

Actor-Critic法

戦略と価値関数を別々に学習する手法

  • 戦略担当のActorと価値評価をするCriticがそれぞれ価値関数$Q_A$, $V_C$を持っている
  • ValueベースとPolicyベース双方の性質を持つ
    • Criticの価値関数$V_C$の学習は$V_C$のみによって完結する→Valueベース
    • Criticのよる評価価値と実際の報酬によって算出されたTD誤差によって戦略を学習→Policyベース
  • SARSAとの違い: SARSAの学習対象は価値関数のみ→Valueベース
    • 戦略はϵ-greedy法などを用いることで$Q$の学習によって間接的に更新される
  • SARSAに比べて安定した学習ができる
    • おそらく価値評価と戦略の学習が独立しているから
    • 「価値更新→間接的に戦略が変わる→選択される行動が変わるため価値も変わる→これまで学習目標としていた価値がずれる」
      というのが起こりにくいのだと

アルゴリズム

  1. 戦略($sotfmax(Q_A[s][a])$のような価値関数に依存するもの)に従って1時刻先まで行動
  2. 1時刻先の報酬と$V_C$を用いてTD誤差を算出 $$ Error(s_t, s_{t+1}) = (r_{t+1}+{\gamma}V_C[s_{t+1}])-V_C[s_t] $$
  3. $V_C$を更新 $$ V_C[s_t] = V_C[s_t] + {\alpha}Error(s_t, s_{t+1}) $$ ※${\alpha}$: 学習係数
  4. $Q_A$を更新 $$ Q_A[s_t][a_t] = Q_A[s_t][a_t] + {\beta}Error(s_t, s_{t+1}) $$ ※${\beta}$: 学習係数
  5. 1.~4.をエピソード終了まで繰り返す
  6. 5.を繰り返す

特に3.でValueベースのように$V_C$が更新できている点、4.でPolicyベース戦略に従って選択した$a_t$(1.で選択)に関して$Q_A$が更新できている点がポイント

kedroのデータ構成を知る

機械学習パイプライン構築ツールのkedroを触ったときにkedroのデータ構成の意味が気になったので調べてみた。

kedro.readthedocs.io

kedroのデフォルトの設定でプロジェクトを作成するとdata配下がこんな構成になっている。

 data
├── 01_raw
├── 02_intermediate
├── 03_primary
├── 04_feature
├── 05_model_input
├── 06_models
├── 07_model_output
└── 08_reporting

なんとなくわかるけど、それぞれどんな時に使うのを想定しているのかが気になった。

まずは公式のドキュメントを見てみる。
ここに書いてあった。 f:id:ricrowl:20220105134802p:plain

  • Raw: パイプライン処理のスタート地点で、基本変更しないデータ。作業する際唯一の真となるソースとなる。ケースバイケースだけど大体は型付けがされていないデータとなる。(例: csvデータ)
  • Intermediate: オプショナルなデータで、Rawデータから型付けを行ったデータ。(例: 文字列データを想定した型の表現へ変換する)
  • Primary: Raw/Intermediateデータからクレンジング/変換/ラングリングされたドメイン固有データ。特徴量エンジニアリングの入力として使う。
    ドメイン固有データ: 業界の専門用語などが入ったままでデータ分析用に処理されていないデータ
  • Feature: Primaryデータから抽出された特徴量を含む分析用のデータ。データ分析による特徴ごとにグループ化され、共通の次元に保存される。
  • Model input: 全特徴量を共通の次元に持った分析用のデータで、分析中のプロジェクトの場合は分析した日時に対し特徴量の変更履歴を追跡できるようにする。
  • Models: 学習済みモデルのデータ。
  • Model output: Model inputからモデルによって得られた分析用データ。
  • Reporting: Primary/Feature/Model input/Model outputをまとめたレポートデータで、ダッシュボードや構成された何らかの形式にて使用される。これによってデータを再定義せずにデータの混合や追加の定義、パフォーマンス向上、プレゼンテーション層の置き換えを行う必要性をカプセル化してなくす。

また、ここのサイトユースケースも含めて詳しく書いてあったので参考にした。

以上まとめてみると各データの役目とパイプライン処理との関係は以下のようになると理解した。

f:id:ricrowl:20220105150134p:plain

DockerコンテナがあるPCでGPUドライバ再インストール

GPUドライバがバグったのでGPUドライバを再インストールした。
そしたらGPU対応させていたDockerコンテナが起動できなくなったので、その対処を記録する。

環境

  • PC: Ubuntu18.04
  • GPU: RTX2080
  • Docker: version 19.03.5
  • コンテナ: docker run -it --gpus all ... で作ったコンテナ

GPU再インストール

既存のドライバ削除

sudo apt purge nvidia-*
sudo apt purge cuda-* # あれば
sudo apt autoremove

GPUドライバのリポジトリ追加

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update

GPUのドライバ候補表示

ubuntu-drivers devices

下みたいな候補一覧が出てくるのでnvidia-driver-***のどれか好きなの選ぶ

vendor   : NVIDIA Corporation
driver   : nvidia-driver-418-server - distro non-free
driver   : nvidia-driver-460-server - distro non-free
driver   : nvidia-driver-460 - third-party free
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-465 - third-party free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin

ドライバインストール

sudo apt install nvidia-driver-460

インストール後、nvidia-smiでエラーなく結果が教示されたらOK

Docker側の修正

GPU再インストール後にコンテナをstartで起動しようとすると以下のようなエラーが出て起動できなかった

Error response from daemon: could not select device driver "" with capabilities: [[gpu]]

nvidia-container-runtimeというパッケージを入れて再起動すると治るっぽい(参考)

まず、vimかなんかで以下のスクリプト(nvidia-container-runtime-script.shと名付ける)を作成

curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt-get update

nvidia-container-runtime-script.shを実行&nvidia-container-runtimeインストール

sh nvidia-container-runtime-script.sh
sudo apt-get install nvidia-container-runtime

dockerデーモンを再起動(もしくはPC再起動)

sudo systemctl restart docker

これでエラーなくコンテナを起動できるようになるはず