numpy の Broadcasting

numpy の ndarray の基本演算を紹介する.

要素ごとの加算

numpy.add(x, y) または x + y で要素ごとの加算を行える.

>>> a = np.array([[1, 1, 1],
                  [2, 2, 2]])
>>> b = np.array([[1, 1, 1],
                  [2, 2, 2]])
>>> np.add(a, b)
array([[2, 2, 2],
       [4, 4, 4]])

要素ごとの減算

numpy.subtract(x, y) または x – y で要素ごとの減算を行える.

>>> a = np.array([[3, 3, 3],
                  [2, 2, 2]])
>>> b = np.array([[1, 1, 1],
                  [1, 1, 1]])
>>> np.subtract(a, b)
array([[2, 2, 2],
       [1, 1, 1]])

要素ごとの乗算

numpy.multiply(x, y) または x * y で要素ごとの乗算を行える.

>>> a = np.array([[1, 2, 3],
                  [1, 2, 3]])
>>> b = np.array([[3, 3, 3],
                  [2, 2, 2]])
>>> np.multiply(a, b)
array([[3, 6, 9],
       [2, 4, 6]])

要素ごとの除算

Python 2 と Python 3 で除算の挙動が異なるため,注意する必要がある.
Python 2 でも from __future__ import division とした場合は Python 3 の挙動になる.

演算 Python 2 Python 3
numpy.divide(x, y) または x / y (Python 2) 余りを切り捨てる 余りを切り捨てない
numpy.true_divide(x, y) または x / y (Python 3) 余りを切り捨てる 余りを切り捨てる
numpy.floor_divide(x, y) または x // y (Python 3) 余りを切り捨てる 余りを切り捨てる
>>> a = np.array([[2, 4, 6],
                  [8, 10, 12]])
>>> b = np.array([[2, 2, 2],
                  [2, 2, 2]])
>>> np.divide(a, b)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
>>> np.floor_divide(7, 3)
2
>>> np.floor_divide([1., 2., 3., 4.], 2.5)
array([ 0.,  0.,  1.,  1.])

符号反転

numpy.negative(x) または -x で符号を反転する.

>>> np.negative([1., -1.])
array([-1.,  1.])

要素ごとのべき乗

numpy.negative(x) または -x で符号を反転する.

>>> a = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
>>> b = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
>>> np.power(a, b)
array([  1.,   4.,  27.,  64.,  25.,   6.])

numpy の Broadcasting

numpy の Broadcasting という機能を紹介する.
異なる形状の ndarray 同士で演算を行おうとした場合に,演算前に形状を揃える Broadcasting が行われる.
次の2つのルールを適用した結果,演算対象の ndarray の形状が一致させることができれば,Broadcast が可能となる.

ルール1: 次元数 ndim を揃える.

演算対象の中で,一番次元数が大きい ndarray より小さい次元数を持つ ndarray は1で埋めて一番大きい次元数を揃える.

ルール2: 形状 shape を揃える.

演算対象の中で,一番次元ごとの数を見ていき,その数が1の場合のみ最も大きいものに合わせる.
その際,要素はその次元の同じ値で埋める.

ルール1,ルール2 を適用した結果,形状が一致した場合は Broadcasting 可能である.
以下にいくつかできる例を出す.

ルール1,ルール2 を適用しても形状が一致しない場合は Broadcasting はできず,演算を行おうとした場合はエラーになります.

OKなコード例

>>> a = np.array([[1, 2, 1],
                  [1, 2, 1]])
>>> b = np.array([2, 1, 2])
>>> a.shape
(2, 3)
>>> b.shape
(3,)
>>> c = a + b
>>> c
array([[3, 3, 3],
       [3, 3, 3]])
>>> c.shape
(2, 3)
>>> a = np.zeros((1, 3, 1, 5))
>>> b = np.zeros((3, 3, 2, 5))
>>> c = np.zeros((3, 1, 1))
>>> d = a + b + c
>>> d.shape
(3, 3, 2, 5)

NGなコード例

>>> a = np.zeros((2, 3, 5))
>>> b = np.zeros((3))
>>> c = a + b
ValueError: operands could not be broadcast together with shapes (2,3,5) (3,)

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 コマンドが叩けるようになっていると思います。