import tensorflow as tf
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras import losses, optimizers
mnist = tf.keras.datasets.mnist
(train_data, train_label), (test_data, test_label) = mnist.load_data()
# MNIST中的图像默认为uint8(0-255的数字)。以下代码将其归一化到0-1之间的浮点数,并在最后增加一维作为颜色通道
train_data = np.expand_dims(train_data.astype(np.float32) / 255.0, axis=-1) # [60000, 28, 28, 1]
test_data = np.expand_dims(test_data.astype(np.float32) / 255.0, axis=-1) # [10000, 28, 28, 1]
train_label = train_label.astype(np.int32) # [60000]
test_label = test_label.astype(np.int32) # [10000]
# 将x_train,y_train组成一个数据集,方便运算
dataset_train = tf.data.Dataset.from_tensor_slices((train_data, train_label))
dataset_test = tf.data.Dataset.from_tensor_slices((test_data, test_label))
# 设置训练batch为100,重复次数为2,
dataset_train = dataset_train.batch(50).repeat(20)
dataset_test = dataset_test.batch(50)
network = Sequential([
tf.keras.layers.Conv2D(6,kernel_size=3,strides=1),
tf.keras.layers.MaxPooling2D(pool_size=2,strides=2),
tf.keras.layers.ReLU(),
tf.keras.layers.Conv2D(16,kernel_size=3,strides=1),
tf.keras.layers.MaxPooling2D(pool_size=2,strides=2),
tf.keras.layers.ReLU(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(120,activation='relu'),
tf.keras.layers.Dense(84,activation='relu'),
tf.keras.layers.Dense(10)
])
network.build(input_shape=(50,28,28,1))
network.summary()
'''输出
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_6 (Conv2D) multiple 60
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 multiple 0
_________________________________________________________________
re_lu_6 (ReLU) multiple 0
_________________________________________________________________
conv2d_7 (Conv2D) multiple 880
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 multiple 0
_________________________________________________________________
re_lu_7 (ReLU) multiple 0
_________________________________________________________________
flatten_3 (Flatten) multiple 0
_________________________________________________________________
dense_9 (Dense) multiple 48120
_________________________________________________________________
dense_10 (Dense) multiple 10164
_________________________________________________________________
dense_11 (Dense) multiple 850
=================================================================
Total params: 60,074
Trainable params: 60,074
Non-trainable params: 0
_________________________________________________________________
'''
losscal = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
acc = tf.keras.metrics.Accuracy()
for step, (x, y) in enumerate(dataset_train):
with tf.GradientTape() as tape:
y_pred = network(x)
y_onehot = tf.one_hot(y, depth=10)
loss = losscal(y_true=y_onehot, y_pred=y_pred)
acc.update_state(tf.argmax(y_pred, axis=1), y)
grads = tape.gradient(loss, network.trainable_variables)
# 自动更新参数
optimizer.apply_gradients(zip(grads, network.trainable_variables))
#输出训练结果
if step % 200 == 0:
print(step, 'loss:', float(loss), 'acc:', acc.result().numpy())
acc.reset_states()
'''输出 训练正确率
23000 loss: 0.18163304030895233 acc: 0.9603
23200 loss: 0.14714375138282776 acc: 0.9587
23400 loss: 0.12835447490215302 acc: 0.9593
23600 loss: 0.1189718022942543 acc: 0.96
23800 loss: 0.0826355516910553 acc: 0.9545
'''
correct, total = 0, 0
for step, (x, y) in enumerate(dataset_test):
y_pred = network(x)
y_pred = tf.argmax(y_pred, axis=1)
y = tf.cast(y, tf.int64)
correct += float(tf.reduce_sum(tf.cast(tf.equal(y_pred,y), tf.float32)) )
total += x.shape[0]
print("acc_test:", correct/total)
'''输出 测试正确率
acc_test: 0.9585
'''