慕課:《深度學習應用開發-TensorFlow實踐》
章節:第七講 MNIST手寫數字識別:分類應用入門
TensorFlow版本為2.3
理論篇:MNIST手寫數字識別:分類應用入門(理論篇)
目錄
數據集加載與預處理
數據集下載與導入
有關數據集下載在理論篇里講了,這里就只放代碼,想知道詳細的可以去看看理論篇
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
tf.__version__
mnist=tf.keras.datasets.mnist
(train_images,train_labels),(test_images,test_labels)=mnist.load_data()
划分驗證集
在TF2中,沒有單獨划分驗證集,而在TF1中是有進行划分的,因此我們要自己划分一下驗證集
total_num=len(train_images)
valid_split=0.2# 驗證集占20%
train_num=int(total_num*(1-valid_split))
train_x=train_images[:train_num]
train_y=train_labels[:train_num]
valid_x=train_images[train_num:]
valid_y=train_labels[train_num:]
test_x=test_images
test_y=test_labels
接下來我們把(28,28)的結構拉直為一行784
train_x=train_x.reshape(-1,784)# -1表示不指定,他會在計算過程自動生成
valid_x=valid_x.reshape(-1,784)
test_x=test_x.reshape(-1,784)
特征數據歸一化
train_x=tf.cast(train_x/255.0,tf.float32)
valid_x=tf.cast(valid_x/255.0,tf.float32)
test_x=tf.cast(test_x/255.0,tf.float32)
獨熱編碼
我們要將標簽數據進行獨熱編碼,這一步同樣是TF1已經做好了,但TF2沒做。
train_y=tf.one_hot(train_y,depth=10)
valid_y=tf.one_hot(valid_y,depth=10)
test_y=tf.one_hot(test_y,depth=10)
構建模型
def model(x,w,b):
pred=tf.matmul(x,w)+b
return tf.nn.softmax(pred)
模型訓練
定義變量
W=tf.Variable(tf.random.normal([784,10],mean=0.0,stddev=1.0,dtype=tf.float32))
B=tf.Variable(tf.zeros([10]),dtype=tf.float32)
定義交叉熵損失函數
def loss(x,y,w,b):
pred=model(x,w,b)
loss_=tf.keras.losses.categorical_crossentropy(y_true=y,y_pred=pred)
return tf.reduce_mean(loss_)
設置超參數
training_epochs=20
batch_size=50
lr=0.001
定義梯度計算函數
def grad(x,y,w,b):
with tf.GradientTape() as tape:
loss_=loss(x,y,w,b)
return tape.gradient(loss_,[w,b])# 返回梯度向量
選擇優化器
我們依舊選用Adam
優化器
optimizer=tf.keras.optimizers.Adam(learning_rate=lr)
定義准確率
def accuracy(x,y,w,b):
pred=model(x,w,b)
corr=tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
return tf.reduce_mean(tf.cast(corr,tf.float32))
訓練
total_step=int(train_num/batch_size)
loss_list_train=[]#train loss
loss_list_valid=[]
acc_list_train=[]#train loss
acc_list_valid=[]
for epoch in range(training_epochs):
for step in range(total_step):
xs=train_x[step*batch_size:(step+1)*batch_size,:]
ys=train_y[step*batch_size:(step+1)*batch_size]
grads=grad(xs,ys,W,B)#計算梯度
optimizer.apply_gradients(zip(grads,[W,B]))#優化器調參
loss_train=loss(train_x,train_y,W,B).numpy()
loss_valid=loss(valid_x,valid_y,W,B).numpy()
acc_train=accuracy(train_x,train_y,W,B).numpy()
acc_vaild=accuracy(valid_x,valid_y,W,B).numpy()
loss_list_train.append(loss_train)
loss_list_valid.append(loss_valid)
acc_list_train.append(acc_train)
acc_list_valid.append(acc_vaild)
print(f"epoch={epoch+1},train_loss={loss_train},valid_loss={loss_valid},train_accuracy={acc_train},valid_accuracy={acc_vaild}")
我們可以可視化一下訓練過程
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.plot(loss_list_train,'blue',label="Train Loss")
plt.plot(loss_list_valid,'red',label='Valid Loss')
plt.legend(loc=1)
模型評估
acc_test=accuracy(test_x,test_y,W,B).numpy()
print(f'Test acc={acc_test}')
輸出
Test acc=0.9061999917030334
學習筆記,僅供參考,如有錯誤,敬請指正!