なにごとも 継続

博士課程での研究や思ったこと、作業記録、などなど自由に書いていくつもりです

F2FをgitとDockerを使って実行しよう

F2FをgitとDockerを使って実行する。

Face2faceはFakeVideoとも呼ばれる、画像フレームの生成することで自然に元動画を加工する技術の一つ。

pix2pixを元にした実装がGithub上にあるので、それを走らせてみたいと思う。
コードはこちら


(追記)
結論から言うと、docker環境でのデモ実行はできませんでした
dockerfileの理解をしてから再挑戦しますが、これは自分のメモとして残しておきます。


まずmkdir demoでデモ用のディレクトリを作った。
そのディレクトリ上でgitでcloneする。

git clone https://github.com/datitran/face2face-demo.git

あとは、ここからどうやってdockerイメージを作るのか、前の記事を確認しつつ進める。

とりあえずdocker quickstart terminalを起動した。

Docker image

Dockerの流れは、次の通り。 1. Docker imageを用意する
  1-1. docker imageをpullする
  1-2. Dockerfile内でFROM イメージ:タグ名のベースイメージから、新しい処理を書く
2. docker build -t {イメージ名} {場所}でDockerfileからイメージを作成する
3. docker runでイメージを元にしたコンテナを作り、コンテナ内に入る

Dockerfileからbuildして、イメージを作り、それを元にして実行環境であるコンテナを作っていく。
Dockerfile は、自分で書き足していくという点はいろいろなサイトで指摘されている。
ふむ?

Dockerfileについての公式レフ
コンテナについての公式レフ Docker超入門⑤はDockerfileについて詳しい。
Docker超入門⑥にフローのまとめがされている。

なるほどそうか。
* Dockerは環境構築を指定して管理しつつ、細かい変更はgitで管理する。
* 機能が増えてくると、Dockerfileに記述を足して、そこを自動化していく。
ということか。
Dockerfileは127行までなので、適宜整理して最適化していくらしい。
つまりそれを元に新しいイメージを作るDockerfileを作ればいい。

 docker-compose

Docker-composeは、複数のコンテナ間を関係づけるもの。
docker-composeに関する公式レフ

docker builddocker runでイメージの作成やコンテナの起動は、とくにrunでオプションや環境引数の指定の面で複雑になる。
そこでdocker-composeで複数のコンテナを含めたイメージのbuildとrunを行うと、実行の際に各コンテナを意識しないで操作できる。
Docker composeの参考は次のサイトがある。

docker-composeの動作は、docker-co,pose.ymlファイルの記述で管理する。
ymlファイルの書き方は、次のものが参考になった。
基本的な書き方:docker-compose.ymlの書き方について解説してみた
複数のコンテナに関係した操作:Docker compose ことはじめハンズオン

F2Fを実行するDockerfileをつくる

F2Fのデモを参考にして、Dockerfiledocker-compose.ymlを作っていく。

# anaconda install
FROM continuumio/anaconda3:latest
...

ここで、アナコンダのイメージからコンテナを作るときにactivateしないといけないらしいので、RUN conda activateを行う。

Anaconda の公式 Docker イメージがアクティベーションしないと使えなくなった件

# コンダイメージの継承
FROM continuumio/anaconda3:2019.03
ENV PYTHONUNBUFFERED 1

# 仮想環境の構築
RUN conda env create -f environment.yml
RUN conda activate face2face-demo

RUN mkdir /face2face-reduced-model

CMD ["mv", "freeze_model.py" "face2face-reduced-model"]

としてdocker build -t face2face-demo .を打つ。
-tは名前を付けるオプション
.はカレントディレクトリを指す。
ENV PYTHONUNBUFFERED 1python環境変数の一つ。

RUNとCMDの違い

RUNは新たなイメージを作るためにcontainerを動かすもの。
CMDはイメージを元にしてcontainerを作り、動かすもの。

DockerのRUNとCMDの違い

しかし、
environment.ymlが存在しないとエラーが出る。

ENV PYTHONUNBUFFERED 1
===
RUN mkdir /face2face-demo
WORKDIR /face2face-demo
COPY envirenment.yml /face2face-demo/

# 仮想環境の構築
RUN conda env create -f environment.yml
RUN conda activate face2face-demo
RUN mkdir /face2face-reduced-model
COPY . /face2face-demo/
===
CMD ["mv", "freeze_model.py" "face2face-reduced-model"]

このように変えても駄目だった。
ymlファイルの構成法を調べても、web等の話が多くてよくわからない。
Docker Compose - docker-compose.yml リファレンスでは、docker-composeで使えるリファレンスをまとめている。
慣れてくれば参考になるだろう。

Dockerfile

基本を整理しておく。
* FROM ubuntu:latest ベースになるDocker image
* RUN touch test ubuntu:latest の上に $ touch test を実行したimage layerを作成

Docker超入門⑤

いい本があればいいのだけれど。
同じような用途で使っている人がいないか調べてみた。

Dockerを使って機械学習の環境を作ろうとした話

Dockerileでenvironment.ymlを読み込むのをやめて、docker-composeでやることにする。

# コンダイメージの継承
FROM continuumio/anaconda3:2019.03

ENV PYTHONUNBUFFERED 1

RUN mkdir /face2face-demo

# 作業ディレクトリの変更
WORKDIR /face2face-demo
version: "3"
services:
  app:
    container_name: "f2f-demo-env"
    build:
      context: .
      dockerfile: ./Dockerfile
    image: face2face-demo
    volumes: 
        - /face2face-demo
    tty: true 

environment.ymlの中身を調べるために参考にしたサイト
condaの仮想環境を出力したものになっているらしい。
直接必要なもの以外も出力されているのでややこしい。しかし、それならばやはり、dockerfile内でやった方がよいだろう。

ADDはコピーだとわかった。

Docker: Compose の導入と環境構築

# コンダイメージの継承
FROM continuumio/anaconda3:2019.03

ENV PYTHONUNBUFFERED 1

RUN mkdir /face2face-demo

# 作業ディレクトリの変更
WORKDIR /face2face-demo

# カレントディレクトリにある資産をコンテナ上の`作業ディレクトリ`にコピーする
ADD . /face2face-demo

# 仮想環境の構築
RUN conda env create -f environment.yml
RUN conda activate face2face-demo

# モデルを置く場所を作成
RUN mkdir /face2face-reduced-model
COPY . /face2face-demo

CMD ["mv", "freeze_model.py" "face2face-reduced-model"]

ここで、docker-compose upをやってみる。

 Docker imageの消去

その前にdockerのimageが増えてきたので整理したい。
Dockerイメージとコンテナの削除方法によると、コンテナから消して、次にイメージを消すようだ。

まず動作コンテナの確認:docker container ls
停止しているコンテナの確認:docker container ls -a
IDを指定して削除:docker rm {ID1} {ID2}
これで複数消せる。

イメージの確認:docker image ls
削除:docker rmi {ID} {ID2}
中間ファイルも消されるので、docker image ls -aで中間ファイルの消去も確認できる。

 docer-compose

docker-compose upをかけたら、エラーが出た。 conda initがrunされていないと怒られた。
あとconda.compat~の警告が出ていて、調べたところバグらしい。
QAを見つけた。

結論から言うと、下のようにRUN conda activate~を置き換える。

...
# Make RUN commands use the new environment:
SHELL ["conda", "run", "-n", "face2face-demo", "/bin/bash", "-c"]
...

Activating a Conda environment in your Dockerfile に書いてあった。
condaで仮想環境を作る際の有名なはまりポイントらしい。

-dでバックグラウンドの実行
--buildオプションで起動時にイメージも作成する。

run up startの差は、公式レフに書いてあった。
runは一時的なもので使うようだ。

またエラー。condaでRUNをしようとしているようだ。なぜbashではなく、condaの命令が連続していると捉えられているのかわからない。
これはちょっと1から作るのはきついな。
BindsNetはDocker imageがあった思うのでそっちをやろう。
それによくよく考えたら、Webカメラとコンテナの通信ができないのでは?
コンテナからホストに映像を出力する方法もわからない。
初めの一歩には高すぎた。それらを勉強してからやろう。

dockerを介さず、PC内で普通に環境を作ることにした。
python run_webcam.py --source 1 --show 0 --landmark-model shape_predictor_68_face_landmarks.dat --tf-model face2face-reduced-model/frozen_model.pb   で動かした。
GPUを持っていないのでかなりカクついている。
顔の角度や表情の変化の許容値が、かなりシビアだった。

キャプチャは撮ったのだけれども、編集とgif変換をどうやるのか不明なので、出来たら載せます。
ソフトを入れるより、OpenCVで自分でやる方が勉強にもなる気がするので。