ディープラーニングを実装から学ぶ～ (まとめ３）中では何が？

学習中に中で何が起きているかちょっと覗いてみましょう。データは、引き続きMNISTです。

# 中間層－なし
まずは、中間層なしの場合を見てみましょう。
以下のネットワーク図になります。(バイアスは省略しています。）

![network_[].png](https://qiita-image-store.s3.amazonaws.com/0/212365/25151203-55a4-592e-c48e-8dd3066e27f4.png)

## 実行
前回のプログラムで以下の設定にて実行します。

```python
# 学習回数
epoch = 50
# ノード数
mds = [[]]
# 学習率
lrs = [0.1]
# バッチサイズ
batch_sizes = [100]
```

50エポック後、学習データに対する正解率は、約93%、テストデータに対する正解率は、約92.5%です。

## 重さ
50エポック後の重さを図にしてみましょう。
重さは、全部で$ 784 \times 10 $個あります。$ w_{1 i}^{(1)} $、$ w_{2 i}^{(1)} $の順に$ w_{10 i}^{(1)} $まで表示します。$ i $は、784個、$ 28 \times 28 $にreshapeし表示します。
正を赤、負を青で表します。色が濃いほど大きい値です。

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,6))
for i in range(10):
    plt.subplot(2,5,i+1)
    plt.title(str(i))
    plt.imshow(W[1][:,i].reshape(28,28), "bwr", vmin = -1, vmax = 1)
    plt.colorbar()
plt.show()
```

![imshow_[]_W[50].png](https://qiita-image-store.s3.amazonaws.com/0/212365/5d0c8376-4815-8332-225e-a2d3145a53a2.png)

何か見えてきますか？
0は、真ん中の青が目立ちます。真ん中に文字があれば負の要因となります。
1は、逆に真ん中が赤です。真ん中以外は青が多く負の要因となります。
2は、左側が青で、左側がつながっていないことが要因になります。
3以降も何をもとに数字を判断しているかわかりますね。

各エポックの重みを保存しておき、エポックごとにどのように変化していくか見てみましょう。
0の場合です。

![imshow_[]_W[0-49].png](https://qiita-image-store.s3.amazonaws.com/0/212365/b1a95260-40a7-9516-e7be-217ef9074116.png)

最初は、学習前の重さでランダムの値です。1エポック目から輪郭が見えています。

## u
uの値を表示するため、u,zを取得できるように予測関数を変更します。

```python
def predict2(x, W, b):
    # 層数
    layer = len(W) 
    # 順伝播
    u = {}
    z = {}
    u[1] = affine(x, W[1], b[1])
    for i in range(1, layer):
        z[i] = relu(u[i])
        u[i+1] = affine(z[i], W[i+1], b[i+1])
    y  = softmax(u[layer])
    return y, u, z
```

呼び出し元も変更します。

```python
            y_train, u_train, z_train = predict2(nx_train, W, b)
            y_test, u_test, z_test = predict2(nx_test, W, b)
```

重さとデータを掛けた図を示します。テストデータの5番目まで表示してみます。

```python
import matplotlib.pyplot as plt

for j in range(5):
    print(j)
    plt.figure(figsize=(20,7))
    for i in range(10):
        plt.subplot(2,5,i+1)
        plt.title("u1[{0:d}]={1:.2f}".format(i, u_test[1][j,i]))
        plt.imshow((W[1][:,i]*nx_test[j]).reshape(28,28), "bwr", vmin = -0.5, vmax = 0.5)
        plt.colorbar()
    plt.show()
```

結果を順に見てみましょう。

* 7

![imshow_[]_u1_0.png](https://qiita-image-store.s3.amazonaws.com/0/212365/019d69b2-d0cc-589d-87bf-fd899adbccc1.png)

u1[7]の画像が一番多く赤く反応しています。

* 2

![imshow_[]_u1_1.png](https://qiita-image-store.s3.amazonaws.com/0/212365/18d1c3c8-3496-11b0-5f5c-e6ecbe5c4dab.png)

u1[2]、u1[3]とも上部は同じように反応していますが、下部で差が出ているようです。

* 1

![imshow_[]_u1_2.png](https://qiita-image-store.s3.amazonaws.com/0/212365/cb1c9397-03ba-426d-49f0-144e74d19f5b.png)

u1[1]の中央が大きく反応しています。

* 0

![imshow_[]_u1_3.png](https://qiita-image-store.s3.amazonaws.com/0/212365/58dae369-ee2f-f2d7-2feb-1dd334ecb979.png)

u1[0]が大きく反応しています。

* 4

![imshow_[]_u1_4.png](https://qiita-image-store.s3.amazonaws.com/0/212365/7da8fefd-062b-1ea0-9491-b0a064efb622.png)

u1[4]、u1[9]が反応しています。ただし、4の方が大きく反応しています。

どのように判断しているかよくわかりました。

# 中間層数－１
次は、中間層が1の場合です。

![network_[100].png](https://qiita-image-store.s3.amazonaws.com/0/212365/08f5c4b8-9b75-0d52-3beb-cc706f3053bd.png)

バイアスは、省略しています。

## 実行
パラメータを以下とします。

```python
# 学習回数
epoch = 50
# ノード数
mds = [[100]]
# 学習率
lrs = [0.5]
# バッチサイズ
batch_sizes = [100]
```

50エポック後、学習データに対する正解率は、約100%、テストデータに対する正解率は、約98%です。

## 重さ
50エポック後の重さを図にしてみましょう。
１層目は、$ 784 \times 100 $個、２層目は、$ 100 \times 10 $個です。
１層目の100個を$ 28 \times 28$でreshapeします。
２層目の10個を$ 10 \times 10$でreshapeします。

１階層目です。

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,21))
for i in range(100):
    plt.subplot(10,10,i+1)
    plt.title("W[1][" + str(i) + "]")
    plt.imshow(W[1][:,i].reshape(28,28), "bwr", vmin = -0.5, vmax = 0.5)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[100]_W[1].png](https://qiita-image-store.s3.amazonaws.com/0/212365/ae52764b-d3b4-7107-2b10-13bb841839d2.png)

いろいろな形で特徴を抽出しようとしているのでしょうか？見た目だと具体的に何を抽出しようとしているかわかりません。

２階層目です。

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,5))
for i in range(10):
    plt.subplot(1,10,i+1)
    plt.title("W[2][" + str(i) + "]")
    plt.imshow(W[2][:,i].reshape(10,10), "bwr", vmin = -2, vmax = 2)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[100]_W[2].png](https://qiita-image-store.s3.amazonaws.com/0/212365/274cd0de-5468-4a51-07dd-f325d5ecf700.png)

こちらは、何なのかまったくわかりませんね。

どの数字がどれに影響しているか見てみます。２階層目の重みの大きい順に１０個と小さい順に１０個を表示してみます。

```python
for i in range(10):
    Wsorta = np.argsort(W[2][:,i])
    Wsortd = Wsorta[::-1]
    print(i)
    # top 10
    plt.figure(figsize=(20,21))
    for j in range(10):
        plt.subplot(1,10,j+1)
        plt.title("W1[{0:2d}] {1:.2f}".format(Wsortd[j],W[2][Wsortd[j],i]))
        plt.imshow(W[1][:,Wsortd[j]].reshape(28,28), "bwr", vmin = -0.5, vmax = 0.5)
    plt.show()
    # lower 10
    plt.figure(figsize=(20,21))
    for j in range(10):
        plt.subplot(1,10,j+1)
        plt.title("W1[{0:2d}] {1:.2f}".format(Wsorta[j],W[2][Wsorta[j],i]))
        plt.imshow(W[1][:,Wsorta[j]].reshape(28,28), "bwr", vmin = -0.5, vmax = 0.5)
    plt.show()
```

* 0

影響上位１０位

![imshow_[100]_w1_0_top10.png](https://qiita-image-store.s3.amazonaws.com/0/212365/40c33e13-2897-6ffd-0a7f-29ed3592d196.png)

これに当てはまると0の可能性が高い。

影響下位１０位

![imshow_[100]_w1_0_lower10.png](https://qiita-image-store.s3.amazonaws.com/0/212365/71407258-c476-9f3c-103b-a1e08626bf8d.png)

これに当てはまると0の可能性が低い。

* 1

影響上位１０位

![imshow_[100]_w1_1_top10.png](https://qiita-image-store.s3.amazonaws.com/0/212365/32f42a67-3b67-5ec4-a8ea-3ec970a0dcc8.png)

これに当てはまると1の可能性が高い。

影響下位１０位

![imshow_[100]_w1_1_lower10.png](https://qiita-image-store.s3.amazonaws.com/0/212365/6b0ced64-f575-48e7-fcd6-da663c2875d7.png)

これに当てはまると1の可能性が低い。

やはり、ぱっと見よくわからないですね。

## u,z
テストデータの先頭５データについて、u1,z1を表示してみます。

### u1

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(10,11))
for j in range(5):
    plt.subplot(1,5,j+1)
    plt.title(str(j) + "-u[1]")
    plt.imshow(u_test[1][j,:].reshape(10,10), "bwr", vmin = -5, vmax = 5)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[100]_u1_0-4.png](https://qiita-image-store.s3.amazonaws.com/0/212365/03911d4e-5ef3-0347-8255-096f76f67083.png)

正解は、7,2,1,0,4の順です。
これだけ見てもわからないですね。

### z1

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(10,11))
for j in range(5):
    plt.subplot(1,5,j+1)
    plt.title(str(j) + "-z[1]")
    plt.imshow(z_test[1][j,:].reshape(10,10), "bwr", vmin = -5, vmax = 5)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[100]_z1_0-4.png](https://qiita-image-store.s3.amazonaws.com/0/212365/367f5b37-dd10-cceb-d129-7973a68ff9c0.png)

活性化関数として、ReLUを利用していますので、負（青色）が０になります。

１階層目の重さとデータを掛けた図を示します。テストデータの5番目まで表示してみます。

```python
import matplotlib.pyplot as plt

for j in range(5):
    print(j)
    plt.figure(figsize=(20,21))
    for i in range(100):
        plt.subplot(10,10,i+1)
        plt.title("u[1][{0:2d}]({1:.2f})".format(i, u_test[1][j,i]))
        plt.imshow((W[1][:,i]*nx_test[j]).reshape(28,28), "bwr", vmin = -0.5, vmax = 0.5)
        plt.xticks([])
        plt.yticks([])
        #plt.colorbar()
    plt.show()
```

テストデータの１データ目です。

* 7

![imshow_[100]_u1_0.png](https://qiita-image-store.s3.amazonaws.com/0/212365/901561dc-8249-ea5d-9f01-5c3bc1a5535d.png)

### u2

```python
import matplotlib.pyplot as plt

for j in range(5):
    print(j)
    plt.figure(figsize=(20,21))
    for i in range(10):
        plt.subplot(1,10,i+1)
        plt.title("u[2][{0:d}]({1:.2f})".format(i, u_test[2][j,i]))
        plt.imshow((W[2][:,i]*z_test[1][j]).reshape(10,10), "bwr", vmin = -2, vmax = 2)
        plt.xticks([])
        plt.yticks([])
        #plt.colorbar()
    plt.show()
```

テストデータの１データ目です。

* 7

![imshow_[100]_u2_0.png](https://qiita-image-store.s3.amazonaws.com/0/212365/047c0352-bcef-3e7e-4d05-a9c3bafd4291.png)

7が赤が多く強く反応しています。

* 2

![imshow_[100]_u2_1.png](https://qiita-image-store.s3.amazonaws.com/0/212365/a6a2745e-cf42-8e88-f1d0-b5de3b53d827.png)

他の数字も同様です。

## 中間層 784ノード
中間層を784ノードとして実行してみます。

```python
# 学習回数
epoch = 50
# ノード数
mds = [[784]]
# 学習率
lrs = [0.9]
# バッチサイズ
batch_sizes = [100]
```

50エポック後には、学習データに対する正解率 100%、テストデータに対する正解率 約98.4%です。

重さの図です。

* 1階層目

スペースの関係からタイトルを省略しています。

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,21))
for i in range(784):
    plt.subplot(28,28,i+1)
    #plt.title("W[1][" + str(i) + "]")
    plt.imshow(W[1][:,i].reshape(28,28), "bwr", vmin = -0.25, vmax = 0.25)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[784]_W[1].png](https://qiita-image-store.s3.amazonaws.com/0/212365/a2651b8d-805a-06cf-413b-30cd4b32ba19.png)

* 2階層目

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,5))
for i in range(10):
    plt.subplot(1,10,i+1)
    plt.title("W[2][" + str(i) + "]")
    plt.imshow(W[2][:,i].reshape(28,28), "bwr", vmin = -0.5, vmax = 0.5)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[784]_W[2].png](https://qiita-image-store.s3.amazonaws.com/0/212365/efa8a300-315b-ddd2-0cc5-c14598ef96b7.png)

何を抽出しているのか、やはりわかりませんね。

# 中間層数－２
中間層を100,100ノードとして実行してみます。

```python
# 学習回数
epoch = 50
# ノード数
mds = [[100,100]]
# 学習率
lrs = [0.5]
# バッチサイズ
batch_sizes = [100]
```

50エポック後には、学習データに対する正解率 100%、テストデータに対する正解率 約98.2%です。

重さの図です。

* 1階層目

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,21))
for i in range(100):
    plt.subplot(10,10,i+1)
    plt.title("W[1][" + str(i) + "]")
    plt.imshow(W[1][:,i].reshape(28,28), "bwr", vmin = -0.25, vmax = 0.25)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[100,100]_W[1].png](https://qiita-image-store.s3.amazonaws.com/0/212365/2ec2d11e-1b15-b7e3-2b61-024891753e13.png)

* 2階層目

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,21))
for i in range(100):
    plt.subplot(10,10,i+1)
    plt.title("W[2][" + str(i) + "]")
    plt.imshow(W[2][:,i].reshape(10,10), "bwr", vmin = -0.5, vmax = 0.5)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[100,100]_W[2].png](https://qiita-image-store.s3.amazonaws.com/0/212365/ea703f67-234b-f8f8-ddd4-d7af060c95bd.png)

* 3階層目

```python
import matplotlib.pyplot as plt

plt.figure(figsize=(20,5))
for i in range(10):
    plt.subplot(1,10,i+1)
    plt.title("W[3][" + str(i) + "]")
    plt.imshow(W[3][:,i].reshape(10,10), "bwr", vmin = -1, vmax = 1)
    plt.xticks([])
    plt.yticks([])
    #plt.colorbar()
plt.show()
```

![imshow_[100,100]_W[3].png](https://qiita-image-store.s3.amazonaws.com/0/212365/a2793d68-c3a2-86b3-2ad4-1d830039acc9.png)

複雑になるばかりです。

学習の中身を覗いてみましたが、いかがでしたでしょうか？
やはり、説明はできないが、分類ができるということでしょうか、