import tensorflow as tf
import tensorflow.keras as keras
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# x:[60k,28,28]
# y:[60k,10]
(x,y),_ = keras.datasets.mnist.load_data()
# x:[0~255]->[0~1.]
x = tf.convert_to_tensor(x,dtype = tf.float32) / 255.
y = tf.convert_to_tensor(y,dtype = tf.int32)
train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(200)
train_iter = iter(train_db)
sample = next(train_iter)
#print(sample)
#print('batch:',sample[0].shape,sample[1].shape)
#[b,784] => [b,512] => [b,128] => [b,10]
#[dim_in,dim_out],[dim_out]
w1 = tf.Variable(tf.random.truncated_normal([784,256],stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
w2 = tf.Variable(tf.random.truncated_normal([256,128],stddev=0.1))
b2 = tf.Variable(tf.zeros([128]))
w3 = tf.Variable(tf.random.truncated_normal([128,10],stddev=0.1))
b3 = tf.Variable(tf.zeros([10]))
lr = 1e-3
for epoch in range(10):
for step,(x,y) in enumerate(train_db):
# x:[128,28,28]
# y:[128]
#[b,28,28] => [b,28*28]
x = tf.reshape(x, [-1,28*28])
with tf.GradientTape() as tape:
# x:[b,28*28]
# h1 = x@w1 + b1
# [b,784]@[784,256] + [256] => [b,256]@[256,128] + [128] => [b,128]@[128,10] + [10]
h1 = x@w1 + b1
h1 = tf.nn.relu(h1)
h2 = h1@w2 + b2
h2 = tf.nn.relu(h2)
out = h2@w3 + b3
#print("out:",out)
#print("y_onehot:",y_onehot)
# y:[b] => [b,10]
y_onehot = tf.one_hot(y,depth = 10)
#compute loss
# h3:[b,10]
# mse = mean(sum(y - out)^2)
loss = tf.square(y_onehot - out)
# mean: scalar
loss = tf.reduce_mean(loss)
#compute gradients
grads = tape.gradient(loss,[w1,b1,w2,b2,w3,b3])
w1.assign_sub(lr * grads[0])
b1.assign_sub(lr * grads[1])
w2.assign_sub(lr * grads[2])
b2.assign_sub(lr * grads[3])
w3.assign_sub(lr * grads[4])
b3.assign_sub(lr * grads[5])
if step % 100 == 0:
print(step,'loss:',float(loss))
import tensorflow as tf
import tensorflow.keras as keras
import os
导入了TensorFlow和TensorFlow.keras库,并导入了os库用于设置环境变量。
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
设置TensorFlow的日志等级为2,即只显示错误信息。
(x, y), _ = keras.datasets.mnist.load_data()
使用TensorFlow.keras加载MNIST数据集,将训练数据存储在x中,对应的标签存储在y中。
x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
y = tf.convert_to_tensor(y, dtype=tf.int32)
将x和y转换为TensorFlow的张量,并将x的数据类型转换为float32,并归一化到[0,1]范围。
train_db = tf.data.Dataset.from_tensor_slices((x, y)).batch(200)
使用TensorFlow的tf.data.Dataset.from_tensor_slices()函数创建训练数据集,以每批次200个样本进行训练。
w1 = tf.Variable(tf.random.truncated_normal([784,256],stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
w2 = tf.Variable(tf.random.truncated_normal([256,128],stddev=0.1))
b2 = tf.Variable(tf.zeros([128]))
w3 = tf.Variable(tf.random.truncated_normal([128,10],stddev=0.1))
b3 = tf.Variable(tf.zeros([10]))
定义了三层全连接神经网络的参数:w1、b1为第一层的权重和偏置,w2、b2为第二层的权重和偏置,w3、b3为输出层的权重和偏置。
lr = 1e-3
设置学习率为1e-3。
for epoch in range(10):
for step,(x,y) in enumerate(train_db):
...
使用嵌套的循环进行模型训练。外层循环是迭代次数,内层循环遍历每个批次的样本。
x = tf.reshape(x, [-1,28*28])
将输入数据x的形状从[b,28,28]变为[b,784],将二维图像展平为一维向量。
h1 = x@w1 + b1
h1 = tf.nn.relu(h1)
h2 = h1@w2 + b2
h2 = tf.nn.relu(h2)
out = h2@w3 + b3
执行前向传播过程,计算网络中每一层的输出。使用ReLU作为激活函数。
y_onehot = tf.one_hot(y, depth=10)
loss = tf.square(y_onehot - out)
loss = tf.reduce_mean(loss)
将标签y转换为one-hot编码形式,并计算均方误差损失。
grads = tape.gradient(loss,[w1,b1,w2,b2,w3,b3])
w1.assign_sub(lr * grads[0])
b1.assign_sub(lr * grads[1])
w2.assign_sub(lr * grads[2])
b2.assign_sub(lr * grads[3])
w3.assign_sub(lr * grads[4])
b3.assign_sub(lr * grads[5])
使用自动微分机制tf.GradientTape()计算损失对于各个参数的梯度,并根据学习率更新模型参数。
if step % 100 == 0:
print(step,'loss:',float(loss))
每100个批次打印当前批次的损失值。