> For the complete documentation index, see [llms.txt](https://bing-dong.gitbook.io/tensorflow/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bing-dong.gitbook.io/tensorflow/tf.keras--clssification.md).

# tf.keras--classification

```python
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import pandas as pd
import sklearn
import os
import sys
import time
import tensorflow as tf
from tensorflow import keras

print(tf.__version__)
```

```
2.0.0
```

```python
# 学习时可用第三方数据集进行联系，这里使用keras.datasets.fashion_mnist
fashion_mnist = keras.datasets.fashion_mnist
(x_train_all,y_train_all),(x_test,y_test) = fashion_mnist.load_data()
# 将训练集拆分为训练集和验证集 共60000张图片，前5000张为验证集，后55000张为训练集
x_valid,x_train = x_train_all[:5000],x_train_all[5000:]
y_valid,y_train = y_train_all[:5000],y_train_all[5000:]

print(x_valid.shape,y_valid.shape)
print(x_train.shape,y_train.shape)
print(x_test.shape,y_test.shape)
```

```
(5000, 28, 28) (5000,)
(55000, 28, 28) (55000,)
(10000, 28, 28) (10000,)
```

```python
# 显示一张图片，查看数据集
def show_single_image(img_arr):
    plt.imshow(img_arr,cmap="binary")
    plt.show()
show_single_image(x_train[0])
```

![](/files/-M35emlipH01vjOGr_A_)

```python
# 显示多张图片
def show_imgs(n_rows,n_cols,x_data,y_data,class_name):
    assert len(x_data) == len(y_data)
    assert n_rows * n_cols < len(x_data)
# 用figure定义一张大图，其中可显示子图
# figsize以英寸为单位 1英寸为 2.54cm
    plt.figure(figsize = (n_cols * 1.4, n_rows * 1.6))
    for row in range(n_rows):
        for col in range(n_cols):
            index = row * n_cols + col
#             共分为n_rows行，n_rows列个子图，从左上到右下的编号，起始为1
            plt.subplot(n_rows, n_cols, index+1)
            plt.imshow(x_data[index],cmap="binary",interpolation="nearest")
#             不显示坐标轴
            plt.axis('off')
            plt.title(class_name[y_data[index]])
    plt.show()

class_name = ['T-shirt', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
show_imgs(3, 5, x_train, y_train, class_name)
```

![](/files/-M35ed47sAcfmZ59JDac)

```
# 数据标准化
# x = (x - u)/std  u:均值  std:标准差
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
# 进行转换：  只能对二位矩阵进行处理，所以要将三维矩阵先转为二维，之后再转换回去
# 又因为原数据为int型，因要做除法，所以先转为float型
x_train_scaled = scaler.fit_transform(x_train.astype(np.float32).reshape(-1,1)).reshape(-1,28,28) 

# scaler.fit_transform与scaler.transform的区别为前者会记录均值与标准差的值
# 当再用scaler.transform的时候就不用计算均值与标准差了
x_valid_scaled = scaler.transform(x_valid.astype(np.float32).reshape(1,-1)).reshape(-1,28,28)
x_test_scaled = scaler.transform(x_test.astype(np.float32).reshape(1,-1)).reshape(-1,28,28)

print(np.max(x_train_scaled), np.min(x_train_scaled))
```

```python
#构建分类训练模型 

# tf.keras.models.Sequential()
# 定义一个顺序模型
model = keras.models.Sequential()

'''  
# 将输入矩阵[28,28]经过第一层后展平为[28*28,1]
model.add(keras.layers.Flatten(input_shape=[28,28]))
# 全连接层Dense,输出为300个节点
# relu: y = max(0, x)
model.add(keras.layers.Dense(300,activation='relu'))
model.add(keras.layers.Dense(100,activation='relu'))
# 最后输出10个分类,softmax会将向量变为概率
model.add(keras.layers.Dense(10,activation='softmax'))
'''

# 另一种构建模型的方式，传入一个列表，列表中为各层
model = keras.models.Sequential([
    # 第一层要明确一下输入数据的shape，即input_shape=x_train.shape[1:]
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.Dense(300,activation='relu'),
    keras.layers.Dense(100,activation='relu'),
    keras.layers.Dense(10,activation='softmax')
])

# 损失函数loss:用sparse是因为每个y_train是一个值，而不是一个向量，需要将其转换为[10,1]的向量
# sparse以后就相当于对其进行了one-hot编码
# 若y_train本来就是向量的话，损失函数用categorical_crossentropy
model.compile(loss='sparse_categorical_crossentropy', 
            # 目标函数的优化算法，类似还有梯度下降、sgd等等               
             optimizer = 'adam',
# 评价指标metrics  其和损失函数类似，只不过其结果并不会作用于训练过程，只是输出作为参考。其中accuracy为模型的精确度
             metrics = ["accuracy"])
```

```python
# 查看模型层次
model.layers
```

```
[<tensorflow.python.keras.layers.core.Flatten at 0x22bc80c35f8>,
 <tensorflow.python.keras.layers.core.Dense at 0x22bd80cc550>,
 <tensorflow.python.keras.layers.core.Dense at 0x22bd80cc5f8>,
 <tensorflow.python.keras.layers.core.Dense at 0x22bd84694a8>]
```

```python
# 查看模型概况
model.summary()

# 之下的第二层参数23500是由784*300+300得来的
```

```
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten (Flatten)            (None, 784)               0         
_________________________________________________________________
dense (Dense)                (None, 300)               235500    
_________________________________________________________________
dense_1 (Dense)              (None, 100)               30100     
_________________________________________________________________
dense_2 (Dense)              (None, 10)                1010      
=================================================================
Total params: 266,610
Trainable params: 266,610
Non-trainable params: 0
_________________________________________________________________
```

```python
# 开始训练  返回值为训练过程中的历史数据, 可用于画图分析训练效果
history = model.fit(x_train_scaled, y_train, epochs=10, validation_data=(x_valid_scaled, y_valid))
```

```
Train on 55000 samples, validate on 5000 samples
Epoch 1/10
55000/55000 [==============================] - 9s 155us/sample - loss: 2.4121 - accuracy: 0.7447 - val_loss: 0.6983 - val_accuracy: 0.7502
Epoch 2/10
55000/55000 [==============================] - 9s 159us/sample - loss: 0.5410 - accuracy: 0.8124 - val_loss: 0.5479 - val_accuracy: 0.8132
Epoch 3/10
55000/55000 [==============================] - 7s 127us/sample - loss: 0.4812 - accuracy: 0.8295 - val_loss: 0.4271 - val_accuracy: 0.8476
Epoch 4/10
55000/55000 [==============================] - 7s 131us/sample - loss: 0.4524 - accuracy: 0.8384 - val_loss: 0.4915 - val_accuracy: 0.8334
Epoch 5/10
55000/55000 [==============================] - 7s 124us/sample - loss: 0.4283 - accuracy: 0.8468 - val_loss: 0.4761 - val_accuracy: 0.8360
Epoch 6/10
55000/55000 [==============================] - 8s 141us/sample - loss: 0.4101 - accuracy: 0.8525 - val_loss: 0.4200 - val_accuracy: 0.8602
Epoch 7/10
55000/55000 [==============================] - 8s 137us/sample - loss: 0.3947 - accuracy: 0.8587 - val_loss: 0.3972 - val_accuracy: 0.8604
Epoch 8/10
55000/55000 [==============================] - 8s 149us/sample - loss: 0.3800 - accuracy: 0.8656 - val_loss: 0.4187 - val_accuracy: 0.8624
Epoch 9/10
55000/55000 [==============================] - 8s 149us/sample - loss: 0.3672 - accuracy: 0.8682 - val_loss: 0.4299 - val_accuracy: 0.8560
Epoch 10/10
55000/55000 [==============================] - 7s 125us/sample - loss: 0.3581 - accuracy: 0.8730 - val_loss: 0.4038 - val_accuracy: 0.8678
```

```python
# history存储的是模型在训练过程中的每一次epoch后指标的数值  history为字典类型
history.history
```

```
{'loss': [2.4120644999330696,
  0.5410326600681652,
  0.481207834982872,
  0.45235550054203383,
  0.428294502436031,
  0.410146419041807,
  0.3946501224777915,
  0.3800405863350088,
  0.3672192143873735,
  0.3580564272761345],
 'accuracy': [0.7447091,
  0.81241816,
  0.82952726,
  0.8384,
  0.8467818,
  0.85252726,
  0.8587091,
  0.8656,
  0.8681818,
  0.8730364],
 'val_loss': [0.6983262790679932,
  0.5478786983251571,
  0.42707746143341063,
  0.4914981854915619,
  0.47605090074539186,
  0.41999548461437225,
  0.39724087767601013,
  0.4186679340481758,
  0.4299297041296959,
  0.4037889191329479],
 'val_accuracy': [0.7502,
  0.8132,
  0.8476,
  0.8334,
  0.836,
  0.8602,
  0.8604,
  0.8624,
  0.856,
  0.8678]}
```

```python
def plot_learning_curves(history):
#     DataFrame是一种二维表的类型，用来表示字典进行画图很合适
    pd.DataFrame(history.history).plot(figsize=(8, 5))
    plt.grid(True)
# 当前的图表和子图可以使用plt.gcf()和plt.gca()获得，分别表示"Get Current Figure"和"Get Current Axes"
# 设置y坐标的上下限
    plt.gca().set_ylim(0, 1)  
    plt.show()

plot_learning_curves(history)
```

![](/files/-M35ejBZD3Qc1yQH07Bp)

```
# 在测试集上验证效果
model.evaluate(x_test_scaled, y_test)
```

```
- 1s 53us/sample - loss: 0.2133 - accuracy: 0.8810
[0.3733668773114681, 0.881]
```
