※こちらは2020.04.29時点での記事です。Githubのレポジトリなど、最新のものでは修正されている可能性があります。確認の上ご利用ください。
更新情報
優秀参考記事 ←Dockerfileの中身に非常に参考にしました
そもそも何がやりたかった?
Githubからcloneしてきたファイルを実行するための、それ専用のPython環境を作成したかった。さらに、その環境はWindows OSでもなくMac OSでもない、Ubuntu上に作成したかったのです。
今回対象としているのは、コチラのやつ。
以前論文内容を日本語に訳して記事にした、Feynmanの物理学に関するAI。
k-ptl.hatenablog.com
執筆時点(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
さて。めげない。
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が使える日が来ることを祈ろう。
昨夜はYouTubeで[Alexandros]のVipParty2018が放送された。
[C]の頃から好きだった、久しぶりに聞いたので余韻がすごい。
ってことで、今回はこちらの曲を。
(せーのっ)
\\\ 言 え ///