TensorFlow2.0 前向傳播 張量基礎的使用

TensorFlow2.0 前向傳播 張量基礎的使用

1.導入與設置

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets
print(tf.__version__)

# 使用GPU的 設置
# 獲取物理GPU的個數
gpus = tf.config.experimental.list_physical_devices("GPU")  
for gpu in gpus:
    # 設置內存自增長方式
    tf.config.experimental.set_memory_growth(gpu, True)  
print("物理GPU個數:", len(gpus))

# 獲取邏輯GPU的個數
logical_gpus = tf.config.experimental.list_logical_devices("GPU") 
print("邏輯GPU個數:", len(logical_gpus))

2.加載數據與預處理

# 加載數據集
(x, y), _ = datasets.mnist.load_data()
print(x.shape)
print(y.shape)

# 類型轉換
x = tf.convert_to_tensor(x, dtype = tf.float32)
y = tf.convert_to_tensor(y, dtype = tf.int32)
print(x.dtype)
print(y.dtype)

# 查看X的最小值 最大值
print(tf.reduce_min(x), tf.reduce_max(x))
print(tf.reduce_min(y), tf.reduce_max(y))

# 圖像預處理
# x[0, 255] -> [0, 1]
x = x / 255.0
print(tf.reduce_min(x), tf.reduce_max(x))

3.數據集製作 變量初始化

# 製作 Dataset
train_db = tf.data.Dataset.from_tensor_slices((x, y)).batch(128)

# 查看數據集 shape
train_iter = iter(train_db)
sample = next(train_iter)
print("batch:", sample[0].shape, sample[1].shape)

# 初始化 參數 學習率
lr = 1e-3

# 隨機初始化參數
# [b, 784] ==> [b, 256] ==> [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]))

4.訓練數據集 計算loss 計算梯度

# 循環訓練(外層循環)
for epoch in range(10):
    # 數據集循環(內層循環)
    for step, (x, y) in enumerate(train_db):
        # x:[128, 28, 28]
        # y:[128]
        
        # 維度變換
        # x:[128, 28, 28] ==> [128, 28*28]
        x = tf.reshape(x, [-1, 28*28])
        
        # 記住並更新 參數變量
        with tf.GradientTape() as tape: # tf.Variable
            
            # 第一層網絡 矩陣相乘 自動broadcast
            h1 = x @ w1 + tf.broadcast_to(b1, [x.shape[0], 256])
            # x:[b, 28 * 28]
            # h1 = x @ w1 + b1
            # [b, 784] @ [784, 256] + [256] ==> [b, 256] + [256] 
            # ==> [b, 256] + [b, 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

            # 計算誤差
            # 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)
            loss = tf.reduce_mean(loss)
            
        # 計算梯度 
        grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
        
        # 自減 更新參數變量(學習率 * 梯度變換)
        # w1 = w1 - lr * w1_grads
        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=", epoch, "step=", step, " loss:", float(loss))

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章