tensorflow(十一):前向传播实战——三层神经网络
一、神经网络设计
𝑜𝑢𝑡 = 𝑟𝑒𝑙𝑢{𝑟𝑒𝑙𝑢 𝑟𝑒𝑙𝑢 𝑋@𝑊1 + 𝑏1 @𝑊2 + 𝑏2 @𝑊3 + 𝑏3
import tensorflow as tf from tensorflow import keras from tensorflow.keras import datasets #x:[60k, 28, 28] #y:[60K] (x,y),_ = datasets.mnist.load_data() x = tf.convert_to_tensor(x, dtype=tf.float32) / 255. y = tf.convert_to_tensor(y, dtype=tf.int32) print(x.shape,y.shape,x.dtype, y.shape) print(tf.reduce_min(x), tf.reduce_max(x)) print(tf.reduce_min(y), tf.reduce_max(y)) train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128) train_iter = iter(train_db) sample = next(train_iter) print('batch:', sample[0].shape, sample[1].shape) #[b, 784]=>[b,256] => [b,128] => [b,10] #w[dim_in, dim_out], b[dim_out] #要自动求导的值必须是Varible, 不设置方差会出现梯度离散 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] => [b, 256] + [b, 256] h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 256]) h1 = tf.nn.relu(h1) #[b, 256] => [b, 128] h2 = h1@w2 + b2 h2 = tf.nn.relu(h2) # [b, 128] = [b, 10] out = h2@w3 + b3 # compute loss # out: [b, 10] # y: [b] y_onehot = tf.one_hot(y, depth=10) #mse = mean(sum(y-out)^2) loss = tf.square(y_onehot - out) #mean:scalar #函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值 loss = tf.reduce_mean(loss) # compute gradients grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3]) # w1 = w1 -lr * w1_grad #相减之后成了tensor,不是Varible,所以不能相减 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(epoch, step, "loss", float(loss))