※こちらは2020.04.29時点での記事です。Githubのレポジトリなど、最新のものでは修正されている可能性があります。確認の上ご利用ください。
更新情報
- 2020.04.30
- Github(AI-Feynman)更新 ... ライブラリの依存関係最適化によるrequirements.txt変更、プログラムコード自体も大きく変化(GPU前提のコードからCPUでも動くように、詳細はCommitsとIssues#1~#4を参照のこと)
- massoさん(Twitter: @__masso__)から、インストールしたパッケージをもとにrequirements.txtを出力する方法をご教授いただいたので記事に反映(20200430追記requirementstxtの出力)
優秀参考記事 ←Dockerfileの中身に非常に参考にしました
- 更新情報
- そもそも何がやりたかった?
- 履歴なぐりメモ
- その他のよく使うdockerコマンド
- 終わりに
そもそも何がやりたかった?
Githubからcloneしてきたファイルを実行するための、それ専用のPython環境を作成したかった。さらに、その環境はWindows OSでもなくMac OSでもない、Ubuntu上に作成したかったのです。
今回対象としているのは、コチラのやつ。
以前論文内容を日本語に訳して記事にした、Feynmanの物理学に関するAI。
執筆時点(2020年4月29日 日本時間12時頃)で、cloneするとフォルダ構成は以下のとおり(この時点での最終commitは2020年4月26日)。なお、cloneは作成した/git-repos/
ディレクトリ上に行う。
/git-repos |- /AI-Feynman |- Code | |- ai_feynman_terminal_example.py | |- ... | |- example_data | |- example1.txt | |- ... | |- LICENSE |- README.md |- requirements.txt
履歴なぐりメモ
作成から実行まで、やったことを全部メモに残す。 なかなかうまくいかなかったけれど、どうにか成功したので、、
githubのrepositoryのclone
~/git-repos% git clone https://github.com/SJ001/AI-Feynman.git Cloning into 'AI-Feynman'... remote: Enumerating objects: 19, done. remote: Counting objects: 100% (19/19), done. remote: Compressing objects: 100% (19/19), done. remote: Total 193 (delta 6), reused 0 (delta 0), pack-reused 174 Receiving objects: 100% (193/193), 31.23 MiB | 1.96 MiB/s, done. Resolving deltas: 100% (87/87), done.
cloneした後、requirements.txtを一部書き換える。
python >= 3.6 torch >= 1.4.0 matplotlib sympy = 1.4 pandas scipy sortedcontainers
↓
torch >= 1.4.0 matplotlib sympy == 1.4 pandas scipy sortedcontainers
んで、カレントディレクトリをcloneしてきたディレクトリ内部に移動する。
~/git-repos% cd AI-Feynman
Dockerfile作成・編集
Dockerfile
を/git-repos/AI-Feynmanに作成し、VSCodeで編集する。
terminal上でcode
と入力しVSCodeを開く設定はここを参考に、ドゾ
~/git-repos/AI-Feynman% touch Dockerfile ~/git-repos/AI-Feynman% code Dockerfile
Dockerfileの中には、以下のように書き込む。
FROM ubuntu:18.04 RUN apt-get -y update \ && apt-get -y upgrade \ && apt-get install -y locales curl python3-distutils \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \ && python3 get-pip.py \ && pip install -U pip \ && mkdir /code \ && rm -rf /var/lib/apt/lists/* \ && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 ENV LANG en_US.utf8 WORKDIR /code ADD requirements.txt /code RUN pip install -r requirements.txt # requirements.txtからパッケージのインストール
この時点でのディレクトリ構成は、以下の通り。
/git-repos |- /AI-Feynman |- Code | |- ai_feynman_terminal_example.py | |- ... | |- example_data | |- example1.txt | |- ... | |- LICENSE |- README.md |- requirements.txt |- Dockerfile
Dockerfileのビルド
下記コマンドでビルドする。
~/git-repos/AI-Feynman% docker build -t ai-feynman .
すると、以下のようにドバドバッと出力が返ってくる。ここでは、
- Ubuntu image fileのダウンロード
- requirements.txtに記載されている各種ライブラリのpip install
が実行されている。
imageの確認
さて、これでビルドが完了した。作成されたイメージを見てみよう。
~/git-repos/AI-Feynman% docker images (git)-[master] REPOSITORY TAG IMAGE ID CREATED SIZE ai-feynman latest 83a20b651a69 38 minutes ago 2.68GB ubuntu 18.04 c3c304cb4f22 5 days ago 64.2MB python 3.6 b63ef4ef530f 5 days ago 914MB
うむ、くるしゅうない。
もしnoneになっていたりしたら、Dockerファイルを見直しましょう(Dockerファイルの記述方法に関しては、他の記事に譲ります)。
containerの作成
imageファイルが無事作成できていることを確認したら、それを使用してcontainerを作成する。
~/git-repos/AI-Feynman% docker run -it -v /~full path to/git-repos/AI-Feynman:/code --name test ai-feynman:latest /bin/bash
ここで、もしも
docker: Error response from daemon: Mounts denied: The path /git-repos/AI-Feynman is not shared from OS X and is not known to Docker. You can configure shared paths from Docker -> Preferences... -> File Sharing. See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.
といったエラーが出力された場合、dockerのファイルシェアリングに関して設定をする必要がある。その設定方法は、こちらを参考にされたい。
上のターミナルでのコマンドについて、Dockerfile内でWORKDIR
に設定した/code
と、PC上の操作したいディレクトリ/ ~full path to~ /git-repos/AI-Feynman
を繋ぐために、-v
で設定している。また、--name test ai-feynman
では、ai-feynmanというimageを使用してtestというcontainerを作成しており、最後の/bin/bash
ではcontainer作成後、そのままbashシェルを起動した状態にする(コンテナから出ない、コンテナ内で作業ができる状態)。
コンテナに入った状態で、ls -a
と打つとコンテナ内(WORKDIRに設定した/code
内)の全ファイル一覧を取得できる。さらに、python3.6.9が入っていることも確認できた。
root@244227505b95:/code# ls -a . .. Code Dockerfile example_data .git LICENSE README.md requirements.txt root@244227505b95:/code# python3 --version Python 3.6.9
コンテナの扱い(出入り)について
コンテナは、docker ps -a
とコマンドを入力することでその状態を確認することができる。
~/git-repos/AI-Feynman % docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2948d035556b ai-feynman:latest "/bin/bash" 22 seconds ago Exited (127) 5 seconds ago test1 244227505b95 ai-feynman:latest "/bin/bash" 10 minutes ago Up 10 minutes test
ここに見られるように、STATUSという項目があり、
- STATUS = Up ... コンテナ起動中
- STATUS = Exited ... コンテナ停止中
である。これらの操作に関して、メモがてら残す。
containerを作成したいとき
先ほどと同様に
docker run -it -v ~~:~~ --name xxxx IMAGE [command]
と入力すると、IMAGEを元にしたxxxxという名前のコンテナを作成し、そのコンテナに入った状態(ログイン状態)になる。さらに、[command]を入力することで、そのまま何かしらの処理を実行することができる。
コンテナから一時的に出たい時(コンテナは止めない;STATUS=Up)
コンテナを起動させた状態で、ログイン状態を抜けるには、特別コマンドを使用しない。
[control] + P -> [control] + Q
で抜けることができる。この時、STATUS=Upのままである。
なお、この動作を「デタッチ dettach」という。
STATUS=Upのコンテナに入る
STATUS=Upを維持した状態でログイン状態から抜けることをdettachと呼んだが、ここではその逆;attachする。以下のコマンド。
docker attach <CONTAINER ID or NAME>
ログイン状態で、コンテナを停止させて抜ける;STATUS=Exit
以下のコマンド。ログイン状態が解除されるだけでなく、コンテナが停止するため、処理も停止することに注意。
exit
ログアウト状態で、コンテナを起動させる;STATUS=Exited->Up
docker start <CONTAINER ID or NAME>
ログアウト状態で、コンテナを停止させる;STATUS=Up->Exited
docker stop <CONTAINER ID or NAME>
起動しているコンテナにログインする
予め、start
でコンテナを起動しておくか、dettachすることで起動した状態であることが条件。以下のコマンド。
docker exec -it <CONTAINER ID or NAME> /bin/bash
サンプルプログラムの実行
README.md
内で、GitHubからcloneしたこのレポジトリを使用するためには以下のコマンドをターミナル上で入力することで可能であるとのこと。
python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt
scikit learnがない
やってみたところ、errorが。
root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt Traceback (most recent call last): File "ai_feynman_terminal_example.py", line 2, in <module> from S_run_aifeynman import run_aifeynman File "/code/Code/S_run_aifeynman.py", line 6, in <module> from RPN_to_pytorch import RPN_to_pytorch File "/code/Code/RPN_to_pytorch.py", line 12, in <module> from sklearn.metrics import roc_curve, auc ModuleNotFoundError: No module named 'sklearn'
、、、、requirementsに書いてなかったやんけコンテナ内で、scikit learnをインストールする。
root@244227505b95:/code/Code# pip install sklearn Collecting sklearn Downloading sklearn-0.0.tar.gz (1.1 kB) Collecting scikit-learn Downloading scikit_learn-0.22.2.post1-cp36-cp36m-manylinux1_x86_64.whl (7.1 MB) |████████████████████████████████| 7.1 MB 2.0 MB/s Requirement already satisfied: scipy>=0.17.0 in /usr/local/lib/python3.6/dist-packages (from scikit-learn->sklearn) (1.4.1) Collecting joblib>=0.11 Downloading joblib-0.14.1-py2.py3-none-any.whl (294 kB) |████████████████████████████████| 294 kB 1.6 MB/s Requirement already satisfied: numpy>=1.11.0 in /usr/local/lib/python3.6/dist-packages (from scikit-learn->sklearn) (1.18.3) Building wheels for collected packages: sklearn Building wheel for sklearn (setup.py) ... done Created wheel for sklearn: filename=sklearn-0.0-py2.py3-none-any.whl size=1315 sha256=0626703174a4bb8db6dca7865c9c86f20ff744c1c0fa3c42076ebf653d82959a Stored in directory: /root/.cache/pip/wheels/23/9d/42/5ec745cbbb17517000a53cecc49d6a865450d1f5cb16dc8a9c Successfully built sklearn Installing collected packages: joblib, scikit-learn, sklearn Successfully installed joblib-0.14.1 scikit-learn-0.22.2.post1 sklearn-0.0
seabornがない
さて、気を取り直して。
root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt Traceback (most recent call last): File "ai_feynman_terminal_example.py", line 2, in <module> from S_run_aifeynman import run_aifeynman File "/code/Code/S_run_aifeynman.py", line 6, in <module> from RPN_to_pytorch import RPN_to_pytorch File "/code/Code/RPN_to_pytorch.py", line 15, in <module> import seaborn as sns ModuleNotFoundError: No module named 'seaborn'
、、、、、、、、、、、、、(複雑な感情)seabornをインストールするよ。
root@244227505b95:/code/Code# pip install seaborn Collecting seaborn Downloading seaborn-0.10.1-py3-none-any.whl (215 kB) |████████████████████████████████| 215 kB 487 kB/s Requirement already satisfied: pandas>=0.22.0 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.0.3) Requirement already satisfied: numpy>=1.13.3 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.18.3) Requirement already satisfied: scipy>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from seaborn) (1.4.1) Requirement already satisfied: matplotlib>=2.1.2 in /usr/local/lib/python3.6/dist-packages (from seaborn) (3.2.1) Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas>=0.22.0->seaborn) (2020.1) Requirement already satisfied: python-dateutil>=2.6.1 in /usr/local/lib/python3.6/dist-packages (from pandas>=0.22.0->seaborn) (2.8.1) Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=2.1.2->seaborn) (1.2.0) Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=2.1.2->seaborn) (2.4.7) Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib>=2.1.2->seaborn) (0.10.0) Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.6/dist-packages (from python-dateutil>=2.6.1->pandas>=0.22.0->seaborn) (1.14.0) Installing collected packages: seaborn Successfully installed seaborn-0.10.1
torch visionがない
さて。めげない。
root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt Traceback (most recent call last): File "ai_feynman_terminal_example.py", line 2, in <module> from S_run_aifeynman import run_aifeynman File "/code/Code/S_run_aifeynman.py", line 8, in <module> from S_NN_train import NN_train File "/code/Code/S_NN_train.py", line 6, in <module> from torchvision import datasets, transforms ModuleNotFoundError: No module named 'torchvision'
、、、、めげぬ。
root@244227505b95:/code/Code# pip install torchvision Collecting torchvision Downloading torchvision-0.6.0-cp36-cp36m-manylinux1_x86_64.whl (6.6 MB) |████████████████████████████████| 6.6 MB 1.3 MB/s Requirement already satisfied: torch==1.5.0 in /usr/local/lib/python3.6/dist-packages (from torchvision) (1.5.0) Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from torchvision) (1.18.3) Collecting pillow>=4.1.1 Downloading Pillow-7.1.2-cp36-cp36m-manylinux1_x86_64.whl (2.1 MB) |████████████████████████████████| 2.1 MB 1.2 MB/s Requirement already satisfied: future in /usr/local/lib/python3.6/dist-packages (from torch==1.5.0->torchvision) (0.18.2) Installing collected packages: pillow, torchvision Successfully installed pillow-7.1.2 torchvision-0.6.0
最終的に
※2020年4月29日日本時間12時頃の情報です。現在とは動作が異なることがあるでしょう。本稿はDocker環境構築がメインディッシュであるため、ここを最新版に反映させてはおりませんのでご容赦ください。
root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt Checking for brute force + Traceback (most recent call last): File "ai_feynman_terminal_example.py", line 18, in <module> NN_epochs=opts.NN_epochs, vars_name=opts.vars_name, test_percentage=opts.test_percentage) File "/code/Code/S_run_aifeynman.py", line 164, in run_aifeynman PA = run_AI_all(pathdir,filename+"_train",BF_try_time,BF_ops_file_type, polyfit_deg, NN_epochs) File "/code/Code/S_run_aifeynman.py", line 39, in run_AI_all PA = run_bf_polyfit(pathdir,pathdir,filename,BF_try_time,BF_ops_file_type, PA, polyfit_deg) File "/code/Code/S_run_bf_polyfit.py", line 27, in run_bf_polyfit brute_force(pathdir_transformed,filename,BF_try_time,BF_ops_file_type,"+") File "/code/Code/S_brute_force.py", line 27, in brute_force subprocess.call(["./brute_force_oneFile_v3.scr", file_type, "%s" %try_time, pathdir+filename]) File "/usr/lib/python3.6/subprocess.py", line 287, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib/python3.6/subprocess.py", line 729, in __init__ restore_signals, start_new_session) File "/usr/lib/python3.6/subprocess.py", line 1364, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) PermissionError: [Errno 13] Permission denied: './brute_force_oneFile_v3.scr'
はい、これはもうプログラム上の問題でございます。
ちなみに、このエラーはS_brute_force.py
に以下のように追記することで回避可能なエラーであることを知っていますボクは。自分で見つけたの、エライ(ちゃんとGithubでも報告します)
def brute_force(pathdir,filename,BF_try_time,BF_ops_file_type,sep_type="*"): try_time = BF_try_time try_time_prefactor = BF_try_time file_type = BF_ops_file_type try: os.remove("results.dat") except: pass if sep_type=="*": - subprocess.call(["./brute_force_oneFile_v2.scr", file_type, "%s" %try_time, pathdir+filename]) + subprocess.call(["./brute_force_oneFile_v2.scr", file_type, "%s" %try_time, pathdir+filename], shell=True) if sep_type=="+": - subprocess.call(["./brute_force_oneFile_v3.scr", file_type, "%s" %try_time, pathdir+filename]) + subprocess.call(["./brute_force_oneFile_v3.scr", file_type, "%s" %try_time, pathdir+filename], shell=True) return 1
でも、まだdenyされる。前のversionではこれで突破できたのだけれど、、他の部分もコード変わっているのかな、、
root@244227505b95:/code/Code# python3 ai_feynman_terminal_example.py --pathdir=../example_data/ --filename=example1.txt Checking for brute force + 14ops.txt: 1: 14ops.txt: ./brute_force_oneFile_v3.scr: Permission denied Checking for brute force * 14ops.txt: 1: 14ops.txt: ./brute_force_oneFile_v2.scr: Permission denied Checking polyfit
(2020.04.30追記)requirements.txtの出力
massoさん(Twitter: @masso)から、container内で新たにライブラリを追加したのち、その一覧をrequirements.txtとして出力する方法をご教授いただいたのでそれをメモ。
pip freeze
で、インストールされているライブラリの一覧を取得することができる。
root@244227505b95:/code# pip freeze cycler==0.10.0 future==0.18.2 joblib==0.14.1 kiwisolver==1.2.0 matplotlib==3.2.1 mpmath==1.1.0 numpy==1.18.3 pandas==1.0.3 Pillow==7.1.2 pyparsing==2.4.7 python-dateutil==2.8.1 pytz==2020.1 scikit-learn==0.22.2.post1 scipy==1.4.1 seaborn==0.10.1 six==1.14.0 sklearn==0.0 sortedcontainers==2.1.0 sympy==1.4 torch==1.5.0 torchvision==0.6.0
そして、これをrequirements.txtとして出力するためには以下のコードを走らせるだけで良い。
root@244227505b95:/code# pip freeze > requirements.txt
実際に出力されたrequirements.txtがこちらである。
cycler==0.10.0 future==0.18.2 joblib==0.14.1 kiwisolver==1.2.0 matplotlib==3.2.1 mpmath==1.1.0 numpy==1.18.3 pandas==1.0.3 Pillow==7.1.2 pyparsing==2.4.7 python-dateutil==2.8.1 pytz==2020.1 scikit-learn==0.22.2.post1 scipy==1.4.1 seaborn==0.10.1 six==1.14.0 sklearn==0.0 sortedcontainers==2.1.0 sympy==1.4 torch==1.5.0 torchvision==0.6.0
これで、今回作成したcontainerの環境を再現することが可能となる。
その他のよく使うdockerコマンド
imageファイルを削除したい
docker rmi <IMAGE ID or NAME>
containerを削除したい
docker rm <CONTAINER ID or NAME>
使用していないimage/containerを一括削除したい
docker system prune -a
未使用のものは全部消える。個別にしたいときは、
docker container prune -f docker volume prune -f docker network prune -f docker image prune -f
終わりに
Dockerを使用したいときに、ボクの思っている使い方(やり方)を説明してくれているブログや記事がなかったため、ずっとうまく構築できていなかった。ようやく実行できる環境を構築できてハッピーなので、備忘録にした。
OSの問題だと思っていたけれど、WindowsでもMacでもUbuntuでもできないならやっぱりコードの問題。issue報告しつつ、AI-Feynmanが使える日が来ることを祈ろう。
[C]の頃から好きだった、久しぶりに聞いたので余韻がすごい。
ってことで、今回はこちらの曲を。
(せーのっ)
\\\ 言 え ///