ゆるふわめも

東京か京都にいます。

dockerでのコンテナ作成、削除関係のコマンド一覧

実験で使用するため。Mac OS X、Docker version 1.13.0環境での内容。 HPOlibがなかなか動かせないので一度Dockerfileを作っておきたくてその時の作業メモ。

イメージ

イメージ一覧

docker image ls

イメージ取得

docker pull IMAGE_NAME

ubuntu 14.04の環境で実験を行いたい場合は

docker pull ubuntu:14.04

イメージ削除

docker rmi IMAGE_ID

既存のコンテナからイメージを作成

docker commit CONTAINER_ID

コンテナ

公式のリファレンスなどを参照したほうがいい。

コンテナ一覧

docker ps -a

コンテナ起動

docker run -d -p 8888:80 --name CONTAINER_NAME IMAGE_NAME

-p 8888:80によってlocalhost:8888とコンテナのポート80をつなぎます。

コンテナに指定した名前をつけて起動して、コンテナに入る

docker run -it --name="CONTAINER_NAME" IMAGE_NAME:TAG_NAME /bin/bash

ubuntu:14.04の場合を例にすると、

docker run -it --name="demo2" ubuntu:14.04 /bin/bash

ホスト側のディレクトリをコンテナ内にマウント

コンテナ内でMac上のディレクトリへのアクセスをできるようにして、そこでファイルをやり取りしたい場合に利用。dockerコマンドを実行しているディレクトリ$(pwd)以下のDIRNAMEディレクトリとコンテナ内のABS_PATH_TO_DIRディレクトリをつなげます。

docker run -it --name="CONTAINER_NAME" -v $(pwd)/DIRNAME:ABS_PATH_TO_DIR IMAGE_NAME:TAG_NAME /bin/bash

具体的には

docker run -it --name="demo2" -v $(pwd)/mount:/mount2 ubuntu:14.04 /bin/bash

など。

コンテナ削除

削除前に停止する必要があります。

docker stop CONTAINER_ID;docker rm CONTAINER_ID

Dockerfile関係

以下のようなDockerflieを作成して、ビルドします。こうすることでDockerfileさえあれば同じ環境をいつでも作る事ができます。Dockerfileの中身を適当に記述して…

FROM ubuntu:14.04
MAINTAINER misos <sample@hoge.com>

RUN locale-gen en_US.UTF-8
ENV LC_ALL en_US.UTF-8

RUN \
    apt-get update  \
    apt-get -y install \
    software-properties-common \
    vim \
    wget \
    unzip \
    curl \
    git-core \
    python-dev \
    python-pip \
    python-numpy \
    python-nose \
    python-scipy \
    python-pandas \
    python-protobuf \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

上記ファイルを DOCKERFILE_DIRディレクトリ以下に保存、そして

docker build DOCKERFILE_DIR

を実行。DOCKERFILE_DIRはDockerfileのあるディレクトリ。

普段はRUN apt-get update ...の後に RUN pip2 install ...などが続く。

参考文献など

画風変換をtensorflowで実装し、最適化の項を変化させた時の出力画像の変化を見る

学会に参加してるのですが、昼休みが長すぎたので実験しました。CPUでも待ち時間で計算できたことに少し驚き。 最適化の箇所を 2/17 に追記する予定。

Neural Style Transfer

の二番煎じですが、tensorflowで実装。 使用した画像はpixabeyの商用可能画像です。

を含めたくさんの実装が公開されてます。

VGGネット

訓練済みモデルのダウンロード

neural style transferでは訓練済みの画像分類モデルVGG-19を用いるので、それを定義する。 モデルの重みは Matconvnetのこちらから取得できる。

モデルの定義

画像に直接加える前処理(中間画像を引く、など)は preprocess内に全て記述する。 訓練をする際にある損失関数を計算する箇所は後ほど登場。

class vgg:
    # init
    def __init__(self):
        self.name = "default"
        self.vgg_path = "vgg19.mat"
        self.mean_pixel = None # [R, G, B]
        self.SKIP_PREPROCESS = False
        print("[vgg]init")
        
    # network
    def build(self):
        # layer name
        self.layers = (
            'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1',
            'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',
            'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'conv3_3',
            'relu3_3', 'conv3_4', 'relu3_4', 'pool3',
            'conv4_1', 'relu4_1', 'conv4_2', 'relu4_2', 'conv4_3',
            'relu4_3', 'conv4_4', 'relu4_4', 'pool4',
            'conv5_1', 'relu5_1', 'conv5_2', 'relu5_2', 'conv5_3',
            'relu5_3', 'conv5_4', 'relu5_4'
        )
        
        # load weight
        data = scipy.io.loadmat(self.vgg_path)
        mean = data['normalization'][0][0][0]
        self.mean_pixel = np.mean(mean, axis=(0, 1))
        self.weights = data['layers'][0]
        
        print("[vgg]build")
        
    def conv_layer(self, input, weights, bias):
        conv = tf.nn.conv2d(input,\
                            tf.constant(weights),\
                            strides=(1, 1, 1, 1),\
                            padding='SAME')
        return tf.nn.bias_add(conv, bias)

    def pool_layer(self, input):
        return tf.nn.max_pool(input,\
                              ksize=(1, 2, 2, 1),\
                              strides=(1, 2, 2, 1),\
                              padding='SAME')
    
    # eval
    ## 画像をモデルに入力
    def process_img(self, input_image):
        net = {}
        current = input_image
        for i, name in enumerate(self.layers):
            kind = name[:4]
            if kind == 'conv':
                kernels, bias = self.weights[i][0][0][0][0]
                kernels = np.transpose(kernels, (1, 0, 2, 3))
                bias = bias.reshape(-1)
                current = self.conv_layer(current, kernels, bias)
            elif kind == 'relu':
                current = tf.nn.relu(current)
            elif kind == 'pool':
                current = self.pool_layer(current)
            net[name] = current
        assert len(net) == len(self.layers)
        return net

    # preprocess
    ## 中間画像を足す or 引く
    def _add_mean(self, image, sign=-1):
        return image + sign*self.mean_pixel
    
    def preprocess(self, image):
        if not self.SKIP_PREPROCESS:
            image = self._add_mean(image, sign=-1)
        return image
        
    def unprocess(self, image):
        image = self._add_mean(image, sign=1)
        return image
    

モデルを宣言

model = vgg()
model.build()

中間層での画像特徴量の抽出

ローカルで実験しているので tf.device('/cpu:0') としていますが、GPUデバイスを認識できる環境ならばこの箇所を tf.device('/gpu:k') などと適当に変更する必要があります。

input_img = cv2.imread("sample.jpg")
content_image = raw_content.astype(np.float)
content_shape = (1,) + content_image.shape # (h, w, nch) =>  (1, h, w, nch) 

with tf.Graph().as_default(), tf.Session() as sess, tf.device('/cpu:0'):
    image = tf.placeholder('float', shape=content_shape)
    nets = model.process_img(image)
    img_prep = np.array([model.preprocess(content_image)])
    img_feat = nets['relu2_2'].eval(feed_dict={image: img_prep})

プロット用の関数

plot_data, plot_titleにリスト形式でプロットしたいデータを渡し、pltmethodでプロットする手法を指定。一度に5~10このグラフを出力することが何回もあるので、毎回これを使用する。

# plot image data
def plot_image(plot_data, plot_title, size=(10,10,3,3), pltmethod=plt.imshow):
    plt.figure(figsize=(size[0], size[1]))
    
    for i in range(len(plot_data)):
        plt.subplot(size[2],size[3],i+1)
        pltmethod(plot_data[i])
        
        if len(plot_title) == len(plot_data):
            plt.title(plot_title[i])
    
    plt.tight_layout()
    plt.show()

中間層の画像の可視化

抽出した画像をプロットしてみる。 グレースケールにした方が良かった…?

plot_data = [input_img]+[img_feat[0, :, :, i] for i in range(5)]
plot_title = ["original_img"]+["%d-layer" % (i) for i in range(5)]
plot_image(plot_data, plot_title, size=(10,10,3,3))

f:id:misos:20170208012339p:plain

最適化問題

元論文を参考にしながら「コンテンツロス」+「スタイルロス」の和が最小になるようにモデルを訓練する。

損失関数の計算

はじめに、このモデルの基となった同著者のモデルの損失の計算(の概略)が以下。

paper.hatenadiary.jp

+後ほど詳細追記予定。

出力結果

後ほど追記予定。

f:id:misos:20170208030607p:plainf:id:misos:20170208030628p:plainf:id:misos:20170208030642p:plain

画風変換に関する論文一覧

ほぼ時系列順、専門ではないので見落としたくさんあると思います。

  • Texture Synthesis Using Convolutional Neural Networks
  • A Neural Algorithm of Artistic Style
  • Visualizing and Understanding Deep Texture Representations
  • Compact Bilinear Pooling
  • From A to Z: Supervised Transfer of Style and Content Using Deep Neural Network Generators
  • Texture Networks: Feed-forward Synthesis of Textures and Stylized Images
  • Generative Image Modeling using Style and Structure Adversarial Networks
  • Perceptual Losses for Real-Time Style Transfer and Super-Resolution
  • Precomputed Real-Time Texture Synthesis with Markovian Generative Adversarial Networks
  • Improving the Neural Algorithm of Artistic Style
  • A Powerful Generative Model Using Random Weights for the Deep Image Representation
  • Preserving Color in Neural Artistic Style Transfer

virtualenv及びanacondaで作成した環境を削除・今ある環境の一覧を確認する

env_nameが環境の名前です。

virtualenv

環境の削除

rmvirtualenv env_name

一覧を表示

-lで環境の詳細を表示する。

lsvirtualenv -b
lsvirtualenv -l

環境を作成

virtualenv -p python3 env_name
mkvirtualenv env_name

環境に入る

workon env_name

anaconda

環境の削除

conda remove -n env_name --all

一覧を表示

conda info -e
conda info -env

環境を作成

conda create -n env_name python=3.4 anaconda

環境に入る

source activete env_name

環境から出る

source deactivete env_name 

環境の名前の変更

conda create --n NEW_NAME --clone PREVIOUS_NAME
conda remove --n PREVIOUS_NAME --all

エラー解決:Cannot remove entries from nonexistent file ...easy-install.pth

エラー内容

pip3コマンドでインストールしようとした際に、依存関係のあるライブラリのバージョンを削除する場合があってその際に

Cannot remove entries from nonexistent file anaconda...easy-install.pth

のエラー。

解決

--ignore-installedオプションをつける。

自分の場合はtensor-flowをpython3環境にいれる途中だったため、

sudo pip3 install --upgrade $TF_BINARY_URL --ignore-installed

エラー解決:chainerを利用している時に AttributeError: 'module' object has no attribute 'full_like'

エラー内容

いろいろ長いエラーの後に

AttributeError: 'module' object has no attribute 'full_like'

と言われる。

解決方法

chainerでGPUを利用しない場合、以下の箇所で numpyに切り替わる。

そのnumpyにfull_linkの属性がないためのエラー。

pip install numpy==1.11

numpy.full_linkがあるバーションを指定して解決。