About

Ubuntu 16.04 に NVIDIA-Docker を導入する方法を紹介します。

検証環境

2017年3月30日時点の情報です。

  • Ubuntu 16.04
  • GeForce GTX 1080
  • NVIDIA ドライバ 375

NVIDIA ドライバをまだインストールしていない場合は こちらの記事 を参考に先に導入してください。

Docker Engine のインストール

[公式サイト] Get Docker for Ubuntuを参考にします。

$ sudo apt-get update
$ sudo apt-get -y install apt-transport-https ca-certificates curl
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce

インストールできたか確認します。

$ docker --version
Docker version 17.03.1-ce, build c6d412e

NVIDIA Docker のインストール

[GitHub] nvidia-dockerを参考にします。

NVIDIA Docker をインストールします。

$ wget https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
$ sudo dpkg -i nvidia-docker*.deb

ユーザーを docker グループに追加

デフォルトでは、sudo をつけないと nvidia-docker コマンドが実行できません。

$ nvidia-docker ps
nvidia-docker | 2017/01/14 20:07:56 Error: Cannot connect to the Docker daemon. Is the docker daemon running on this host?

ユーザーを docker グループに追加します。

$ sudo usermod -aG docker $USER

再起動すると、sudo なしで nvidia-docker コマンドが叩けるようになっていると思います。

ndarray の属性

ndarray の次元数,形状,型などは属性で取得できる.

ndarray の形状 (shape)

ndarray の形状は shape 属性で取得できる.
タプルで (軸1の要素数, 軸2の要素数, …, 軸nの要素数) となっている.

>>> x = np.array([[1, 2, 3],
                  [4, 5, 6]])
>>> x.shape
(2, 3)
>>> x.shape[1] #軸1の要素数は?
3

ndarray の型 (dtype)

ndarray の型は dtype 属性で取得できる.

>>> x = np.array([[1, 2, 3],
                  [4, 5, 6]])
>>> x.dtype
dtype('int32')

ndarray の次元数 (ndim)

ndarray の次元数は ndim 属性で取得できる.

>>> x = np.array([[1, 2, 3],
                  [4, 5, 6]])
>>> x.ndim
2

ndarray の要素数 (size)

ndarray の要素数は size 属性で取得できる.

>>> x = np.array([[1, 2, 3],
                  [4, 5, 6]])
>>> x.size
6

ndarray のメモリ配置に関する情報 (itemsize, strides, nbytes)


ndarray の要素1つのバイト数は itemsize 属性で取得できる.
今回,配列の型は int32 なので,メモリ上で1つの要素は4バイトで表現される.

>>> x = np.array([[1, 2, 3],
                  [4, 5, 6]])
>>> x.dtype
dtype('int32')
>>> x.itemsize
4  # (byte)

ndarray の配列全体のバイト数は bytes 属性で取得できる.

>>> x.nbytes
24  # (byte)

ndarray で各軸を移動するために必要なバイト数は strides 属性で取得できる.

>>> x.strides
(12, 4)

About

Python の数値計算ライブラリ numpy の多次元配列 ndarray の作成方法についてまとめた.
numpy,ndarray

以下のコードを実行するには,まず numpy を import する.

import numpy as np

numpy.array(object, dtype=None)

numpy.array を使うと,値と型を指定して多次元配列を作成できる.

>>> x = np.array([[0,1,2],
                  [3,4,5],
                  [6,7,8]],
                  np.int32)

empty() で作成する.

numpy.empty を使うと,形状を指定して値を初期化しない多次元配列を作成できる.

>>> x = np.empty((2,2))
>>> x # デタラメな値が入っている.
array([[  4.24399158e-314,   8.48798317e-314],
       [  1.27319747e-313,   1.69759663e-313]])

zeros() で作成する.

numpy.zeros を使うと,形状を指定して値を0で初期化した多次元配列を作成できる.

>>> x = np.zeros((2,2))
>>> x
array([[ 0.,  0.],
       [ 0.,  0.]])

ones() で作成する.

numpy.ones を使うと,形状を指定して値を1で初期化した多次元配列を作成できる.

>>> x = np.ones((2,2))
>>> x
array([[ 1.,  1.],
       [ 1.,  1.]])

empty_like(), zeros_like(), ones_like() で作成する.

numpy.zeros_like: 形状を与えられた配列と同じで値を初期化しない多次元配列を作成できる.
numpy.empty_like: 形状を与えられた配列と同じで値を0で初期化した多次元配列を作成できる.
numpy.ones_like: 形状を与えられた配列と同じで値を1で初期化した多次元配列を作成できる.

>>> x = [[1, 2], [3, 4]]
>>> y = np.empty_like(x)
>>> y
array([[0, 0],
       [0, 0]])
>>> y = np.zeros_like(x)
>>> y
array([[0, 0],
       [0, 0]])
>>> y = np.ones_like(x)
>>> y
array([[1, 1],
       [1, 1]])

About

Python の数値計算ライブラリ numpy を使う上で必須であるインデックス操作についてまとめた.

以下のコードを実行するには,まず numpy を import する.

import numpy as np

Shallow Copy と Deep Copy

ndarray の一部をインデックス操作 (indexing)で切り出したものをスライス (slice)という.

スライスは元の配列の参照なので,スライスを変更すると元の配列も変わってしまう.

>>> x = np.array([1,2,3,4,5,6,7,8,9])
>>> y = x[:3]
>>> y
array([1, 2, 3])
>>> y[0] = 100
>>> y
array([100,   2,   3])
>>> x
array([100,   2,   3,   4,   5,   6,   7,   8,   9])

copy()を使えば,参照ではなく新たな ndarray が作成されるので,切り出した配列を変更しても,元の配列が変わってしまうことはない.

>>> x = np.array([1,2,3,4,5,6,7,8,9])
>>> y = x[:3].copy()
>>> y
array([1, 2, 3])
>>> y[0] = 100
>>> y
array([100,   2,   3])
>>> x
array([1, 2, 3, 4, 5, 6, 7, 8, 9])

インデックス操作 (Indexing)

1次元配列

次の1次元配列に対する操作を見ていく.

x = np.array([0,1,2,3,4,5,6,7,8,9])

array[index]

インデックスを1つ指定する.

>>> x[0]
0

array[start:]

start を指定すると,[start, 9] のスライスが作成される.

>>> x[6:]
array([6, 7, 8, 9])

array[:end]

end を指定すると,[0,end) のスライスが作成される.
Python の list 同様,end の要素はスライスに含まれないことに注意する.

>>> x[:4]
array([0, 1, 2, 3])

array[start:end]

start 及び end を指定すると,[start,end) のスライスが作成される.

>>> x[2:6]
array([2, 3, 4, 5])

array[start:end:stride]

stride を指定すると,[start,end) まで stride ずつ値を取り出したスライスが作成される.

>>> x[1:10:2]
array([1, 3, 5, 7, 9])

2次元配列

次の2次元配列に対する操作を見ていく.

x = np.array([[0,1,2],
              [3,4,5],
              [6,7,8]])

この場合,”要素数3の配列”の各要素が”要素数3の配列”になっていると考える.
カンマで区切って軸ごとの start:end:stride を記述する.
array[軸0に対する操作,軸1に対する操作]

軸0に対する操作

軸1に対する操作を省略した場合は軸0に対する操作のみ行われる.

>>> x[1]
array([0, 1, 2])
>>> x[1:3]
array([[3, 4, 5],
       [6, 7, 8]])
>>> x[::2]
array([[0, 1, 2],
       [6, 7, 8]])

軸0及び軸1に対する操作

>>> x[1:,1:]
array([[4, 5],
       [7, 8]])

>>> x[1][1]
4

3次元配列

3次元配列にでも考え方は同様である.

x = np.array([[[0,1],[2,3]],
              [[4,5],[6,7]]])

この場合,”要素数2の配列”の各要素が”要素数2の配列”の各要素が”要素数2の配列”になっていると考える.
カンマで区切って軸ごとの start:end:stride を記述する.
array[軸0に対する操作,軸1に対する操作,軸2に対する操作]


軸0,軸1及び軸2に対する操作

>>> x[1]
array([[4, 5],
       [6, 7]])
>>> x[1][1]
array([6, 7])
>>> x[1][1][0]
6

n次元配列

例は省略するが,n次元配列でも同様である.
array[軸0に対する操作, 軸1に対する操作, …, 軸nに対する操作] とかけばよい.
また \(k \le n\) としたとき, \(k\) 以降の軸の操作は省略できることも同様である.
array[軸0に対する操作, 軸1に対する操作, …, 軸kに対する操作]