中学生にもわかるTensorFlow入門　その２　行列の演算

#今回の概要
[前回](http://qiita.com/EtsuroHONDA/items/02635dc3026e29f3cb41)はテンソルとは何かを説明しましたが、今回は、行列の演算についてごく基礎的なことを説明させていただこうと思います。理系の大学を目指す受験生や大学生なら十二分に理解しているような内容です

ここでどうして行列の演算かというと、歴史的に見て、まず行列を利用して方程式を解くといういわゆる線形代数の基本的なものから学問が発達し、それを元にさらに一般化させたテンソルという概念によって多重線形代数というものに発達していったという歴史があるからです

実際TensorFlowや[Chainer](http://chainer.org/ )などのニューラルネットワークを比較的容易に記述できるようになった（Python言語の）ライブラリはこうした行列演算が基礎になっていますから、そこで必要となるであろう最低限の知識である行列の和と積についてまず説明します。次に図形の変形などの際に利用されるであろう、行列の積の演算を利用し、図形の変形や回転、あるいは平行移動などを行う一次変換について簡単に説明します

#行列の和と積

まず行列の和。これは条件として足されるものと足すものが同じmxnの行列であることが前提です。しかしやっていることは簡単で対応する各行列の要素をそれぞれ加算しただけです

```math
\begin{pmatrix} { a }_{ 11 } & { a }_{ 12 } \\ { a }_{ 21 } & { a }_{ 22 } \end{pmatrix}+\begin{pmatrix} b_{ 11 } & { b }_{ 12 } \\ { b }_{ 21 } & { b }_{ 22 } \end{pmatrix}=\begin{pmatrix} { a }_{ 11 }+b_{ 11 } & { a }_{ 12 }+b_{ 12 } \\ { a }_{ 21 }+b_{ 21 } & { a }_{ 22 }+b_{ 22 } \end{pmatrix}
```

次に乗算ですが、まずスカラー倍することを考えます。その場合各行列の要素がスカラー倍されるということになります

```math
c\cdot \begin{pmatrix} { a }_{ 11 } & { a }_{ 12 } \\ { a }_{ 21 } & { a }_{ 22 } \end{pmatrix}=\begin{pmatrix} { c\cdot a }_{ 11 } & c\cdot { a }_{ 12 } \\ c\cdot { a }_{ 21 } & c\cdot { a }_{ 22 } \end{pmatrix}

```


次に行列同士の乗法ですが、掛けられる側が$l×m$、掛ける方が$m×n$というように掛けられる側の行数と掛ける側の列数が揃っていることが条件です。ここで、行列の$i$行$j$番目の成分$c_{ij}$は

```math
{ c }_{ ij }=\sum _{ k=1 }^{ m }{ { a }_{ ik }\cdot  } { b }_{ kj }
```
で表されます。例えば２×２の大きさの同士の行列の掛け算は次のようになります

```math
\begin{pmatrix} { a }_{ 11 } & { a }_{ 12 } \\ { a }_{ 21 } & { a }_{ 22 } \end{pmatrix}\begin{pmatrix} b_{ 11 } & { b }_{ 12 } \\ { b }_{ 21 } & { b }_{ 22 } \end{pmatrix}=\begin{pmatrix} { a }_{ 11 }\cdot b_{ 11 }+{ a }_{ 12 }\cdot b_{ 21 } & { a }_{ 11 }\cdot b_{ 12 }+{ a }_{ 12 }\cdot b_{ 22 } \\ { a }_{ 21 }\cdot b_{ 11 }+{ a }_{ 22 }\cdot b_{ 21 } & { a }_{ 21 }\cdot b_{ 12 }+{ a }_{ 22 }\cdot b_{ 22 } \end{pmatrix}
```

では$2×1$の行列と$1×2$の大きさの行列はどうなるでしょう

```math
\begin{pmatrix} { a }_{ 11 } \\ { a }_{ 21 } \end{pmatrix}\begin{pmatrix} b_{ 11 } & { b }_{ 12 } \end{pmatrix}=\begin{pmatrix} { a }_{ 11 }\cdot b_{ 11 } & { a }_{ 11 }\cdot b_{ 12 } \\ { a }_{ 21 }\cdot b_{ 11 } & { a }_{ 21 }\cdot b_{ 12 } \end{pmatrix}
```


以上、簡単に行列の加法、乗法について見てきました。ほかに、行列の計算をする上で必要な次のことが言えます
（参考：https://ja.m.wikipedia.org/wiki/行列 ）

**行列の積は可換でない**
　一般に、mxm同士の行列であっても

```math
  B \cdot A \neq A \cdot B
```

**行列の積は結合法則が成立する**
　乗法が定義される限りにおいて

```math
  (A\cdot B)\cdot C = A\cdot (B\cdot C)
```
が成立する

**分配法則が成立する**
　各項における加法と乗法が定義される限りにおいて

```math
  (A + B)\cdot C = A\cdot C + B\cdot C
```
および

```math
  A\cdot (B + C) = A\cdot B + A\cdot C
```
が成立する

#一次変換

上記の基本的な行列の演算さえ知っておけば「MNIST for ML Beginners」で説明されているプログラムの内容はほぼ理解できるのですが、図形変形させたり回転させたり平行移動させたりするときの処理に行列の演算を行うことがあります。そのような演算のことを総じて一次変換というのですが、今回は一次変換の具体的な処理についてお話します

一次変換は図形の位置を表す座標行列に処理したい行列を乗ずることによって成立します。

####変形

　例えば、二次元上の点$(1,1)$を点$(x',y')=(a+c,b+d)$と移動させるようなことを考えるとそのような一次変換の一般的な式は次のようにあらわされます

```math
\begin{pmatrix} x' \\ y' \end{pmatrix}=\begin{pmatrix} ax+cy \\ bx+dy \end{pmatrix}=\begin{pmatrix} a & c \\ b & d \end{pmatrix}\begin{pmatrix} x \\ y \end{pmatrix}
```
となります。これは一般に正方形を平行四辺形に変形させることに相当します

![正方形を並列へ](https://qiita-image-store.s3.amazonaws.com/0/123035/b224956e-e8d1-6cac-01c6-beed5a80ebbd.png)
（上図はhttps://ja.wikipedia.org/wiki/行列 より引用）

####回転

　さて中心が原点で半径が半径が１の円（これを単位円と言います）について考えます。平面を規定する正規直交基底(1,0)、(0,1)を角θだけ回転移動させることを考えます。そうしたとき単位円上の点（0,1)を単位円上の点(cosθ,sinθ)上に回転移動させると考えると、点(1,0)は(-sinθ,cosθ)上に移ることとなります。このような一次変換を行う行列は、

```math
式\begin{pmatrix} \cos { \theta  }  & -\sin { \theta  }  \\ \sin { \theta  }  & \cos { \theta  }  \end{pmatrix}
```

となります


####平行移動

　平行移動は少々ひねりが必要で一次変換の行列は一般に次のように表されます。(ウキペディア：https://ja.m.wikipedia.org/wiki/平行移動 より引用)

>例えば三次元の場合において、ベクトル w = (wx, wy, wz) は四成分の斉次座標 w = (wx, wy, wz, 1)で表せる[2]。
>
>各点を斉次座標で書いた斉次ベクトル p を、定ベクトル v だけ平行移動させるには、平行移動行列
>
>```math
T_{\mathbf{v}} = 
\begin{pmatrix}
1 & 0 & 0 & v_x \\
0 & 1 & 0 & v_y \\
0 & 0 & 1 & v_z \\
0 & 0 & 0 & 1 
\end{pmatrix}
```
>を掛ければよい
>

つまり、

>```math
 T_{\mathbf{v}} \mathbf{p} =
\begin{pmatrix}
1 & 0 & 0 & v_x \\
0 & 1 & 0 & v_y\\
0 & 0 & 1 & v_z\\
0 & 0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
p_x \\ p_y \\ p_z \\ 1
\end{pmatrix}
=
\begin{pmatrix}
p_x + v_x \\ p_y + v_y \\ p_z + v_z \\ 1
\end{pmatrix}
= \mathbf{p} + \mathbf{v}
```

となるということです

[次回](http://qiita.com/EtsuroHONDA/items/19d192a15613fae1ec10 )は、いよいよニューラルネットワークの一種であるパーセプトロンについての説明を行います