import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
mnist=tf.keras.datasets.mnist
(train_x,train_y),(text_x,text_y)=mnist.load_data()
look_photo_x=text_x[:] #备用验证
look_photo_y=text_y[:]
#定义训练参数
lun_shu=20 #训练轮数
yang_benshu=50 #单次训练样本数
xue_xilv=0.001 #学习率
cunt=0 #记录学习轮数
loss_train_save=[] #保存训练集损失函数值
acc_train_save=[] #保存训练集Acc值
#图像拉直.....变为一维数组
print(train_x[0].shape) #数据验证
train_x=train_x.reshape(-1,784)
text_x=text_x.reshape(-1,784)
print(train_x[0].shape)#数据验证
#特征数据归一化代码块
train_x=tf.cast(train_x/255.0,tf.float32)
text_x=tf.cast(text_x/255.0,tf.float32)
#标签数据变成独热码形式
train_y=tf.one_hot(train_y,depth=10)
text_y=tf.one_hot(text_y,depth=10)
#模型变量的定义
Input_Dim=784
H1_NN=64
W1=tf.Variable(tf.random.normal( [Input_Dim , H1_NN], mean=0.0,stddev=1.0,dtype=tf.float32))
B1=tf.Variable(tf.zeros([H1_NN]), dtype=tf.float32)
Output_Dim=10
W2=tf.Variable(tf.random.normal( [H1_NN , Output_Dim], mean=0.0,stddev=1.0,dtype=tf.float32))
B2=tf.Variable(tf.zeros( [Output_Dim] ) , dtype=tf.float32)
W=[W1,W2]
B=[B1,B2]
#模型的构建
def model(x,w,b):
x=tf.matmul(x,w[0]) + b[0]
x=tf.nn.relu(x)
x=tf.matmul(x,w[1]) + b[1]
pred=tf.nn.softmax(x)
return pred
#定义损失函数
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_) #求均值,得出均方差
#梯度计算函数
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=xue_xilv)
#定义准确率
def accuracy(x,y,w,b):
pred=model(x,w,b)
one_or_zero=tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
#准确率,将布尔型转换为浮点型并计算均值
return tf.reduce_mean(tf.cast(one_or_zero,tf.float32))
#直线图封装函数
def zhi_xian_tu(x_,y_):
plt.rcParams['font.sans-serif']='SimHei' #设置字体为黑体
plt.plot(x_,label='学习率',color='r') #创建直线图
plt.plot(y_,label='损失率',color='b')
plt.ylim(0,1) #设置纵坐标长度为1
plt.xlabel('百分比',fontsize=12) #显示图例
plt.xlabel('学习次数',fontsize=12)
plt.title('手写数字识别学习率与损失率直观图',fontsize=16) #设置标题
plt.legend() #显示图例
plt.show() #显示完整直线图
total_step=int(len(train_x)/yang_benshu)
for i in range(lun_shu):
cunt+=1
for m in range(total_step):
xs=train_x[m*yang_benshu:(m+1)*yang_benshu]
ys=train_y[m*yang_benshu:(m+1)*yang_benshu]
grads=grad(xs,ys,W,B)#计算梯度
optimizer.apply_gradients(zip(grads,W+B)) #优化器根据梯度自动调整梯度
loss_train=loss(train_x,train_y,W,B).numpy() #计算当前轮训练损失率
acc_train=accuracy(train_x,train_y,W,B).numpy() #计算当前识别率
loss_train_save.append(loss_train)
acc_train_save.append(acc_train)
print('正在学习第:%d轮 损失率:%4f 识别正确率:%4f' % (cunt,loss_train,acc_train))
zhi_xian_tu(acc_train_save,loss_train_save) #打印直线图