# TesnsorFlow2 -1 初探 手寫辨識 by Keras
## import 套件+測試是否可連上GPU
```
import tensorflow as tf
import numpy as np
import pandas as pd
print(tf.config.list_physical_devices('GPU'))
print(tf.test.is_built_with_cuda())
print(tf.test.is_gpu_available())
```
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]
True
True
## 下載資料集
mnist 的load_data()會回傳已經先分割好的
training data 和 testing data
並且將每個 pixel 的值從 Int 轉成 floating point 同時做normalize
(這是很常見的preprocessing)
```
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
```
len(x_train) = 60000
x_train[0].shape = (28 ,28)
## 搭建模型
### 利用"Sequential"把每層 layer 疊起來
input 大小為 28 x 28
中間有一層是100個神經元(Dense代表層數)
Dropout代表中間隨機捨棄的神經元的比例
activation 用 softmax
最後 output 為 10 個 class (0~9)的機率
### model每層定義好後需要經過"compile"
選擇loss function為sparse_categorical_crossentropy
```
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
```
## 將資料放入模型開始訓練並測試
fit為訓練模型,epoch代表全部資料重新跑的次數
evaluate為測試model
會跑出每個epoch訓練的結果
最後輸出測試的結果
```
fit = model.fit(x_train, y_train, epochs=50)
model.evaluate(x_test, y_test, verbose=2)
```
(訓練進度過程)
.....
Epoch 48/50
1875/1875 [ ============================== ] - 1s 658us/step - loss: 0.0362 - accuracy: 0.9882
Epoch 49/50
1875/1875 [ ============================== ] - 1s 650us/step - loss: 0.0333 - accuracy: 0.9884
Epoch 50/50
1875/1875 [ ============================== ] - 1s 660us/step - loss: 0.0331 - accuracy: 0.9883
313/313 - 0s - loss: 0.1039 - accuracy: 0.9805
(輸出:測試的loss/accuracy)
[0.10388398170471191, 0.9804999828338623]
## 列出模型資訊
`model.summary()`
Model: "sequential"
----------
Layer (type) Output Shape Param #
flatten (Flatten) (None, 784) 0
dense (Dense) (None, 100) 78500
dropout (Dropout) (None, 100) 0
dense_1 (Dense) (None, 10) 1010
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
## 作圖- loss/accuracy
### 利用fit.history接收訓練過程資訊
fit為之前訓練步驟的model.fit,用變數fit接
用DataFrame存取
```
import matplotlib as mpl
import matplotlib.pyplot as plt
df = pd.DataFrame(fit.history)
```
### epoch-loss圖
x為DataFrame的index
y為DataFrame的loss欄位
```
x = list(df.index+1)
y = fit.history["loss"]
fig = plt.figure()
axes = plt.axes()
axes.plot(x, y)
axes.set_title('HandWriting Training')
axes.set_xlabel('epotch')
axes.set_ylabel('loss')
plt.show()
```

### epoch-accuracy圖
x為DataFrame的index
y為DataFrame的accuracy欄位
```
x = list(df.index+1)
y = fit.history["accuracy"]
fig = plt.figure()
axes = plt.axes()
axes.plot(x, y)
axes.set_title('HandWriting Training')
axes.set_xlabel('epotch')
axes.set_ylabel('accuracy')
plt.show()
```

## 畫出手寫辨識的資料
```
import matplotlib.pyplot as plt
fig, ax = plt.subplots(nrows=5, ncols=5, sharex='all', sharey='all')
ax = ax.flatten()
for i in range(25):
img = x_train[i]
ax[i].set_title(y_train[i])
ax[i].imshow(img, cmap='Greys', interpolation='nearest')
ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()
```
