TensorFlow-2.x-02-線性迴歸的簡潔實現

        這裏我們實現的是接上一篇的從0開始的線性迴歸,TF-2.x中有比較簡潔的實現方式。mxnet中也有對應章節:MXNET深度學習框架-04-使用gluon實現線性迴歸

1、生成數據集

num_inputs = 2
num_examples = 1000
true_w = [2, -3.4] #真實權重
true_b = 4.2 # 真實偏置值
features = tf.random.normal((num_examples, num_inputs),stddev =1)
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += tf.random.normal(labels.shape,stddev=0.01)

2、讀取數據集

batch_size = 10
# 將訓練數據的特徵和標籤組合
dataset = tfdata.Dataset.from_tensor_slices((features, labels))
# 隨機讀取小批量
dataset = dataset.shuffle(buffer_size=num_examples) #shuffle 的 buffer_size 參數應大於等於樣本數,相當於開闢一個存儲數據的空間,batch 可以指定 batch_size 的分割大小。
dataset = dataset.batch(batch_size) #取數據

for batch_x, batch_y in dataset :
    print(batch_x, batch_y)
    break

結果:
在這裏插入圖片描述

3、定義模型和初始化參數

def linreg():
    model=tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(1,kernel_initializer=tf.random_normal_initializer(stddev=0.01)))
    return model

4、定義損失函數

loss = tf.losses.MeanSquaredError()

5、定義優化器

trainer = tf.keras.optimizers.SGD(learning_rate=0.03)

6、訓練

num_epochs = 10
for epoch in range(1, num_epochs + 1):
    train_loss, num_count = 0, 0
    for X, y in dataset:
        num_count+=1
        with tf.GradientTape() as tape:
            l = loss(net(X, training=True), y)
        grads = tape.gradient(l, net.trainable_variables) #通過 model.trainable_variables 找到需要更新的變量
        trainer.apply_gradients(zip(grads, net.trainable_variables))#使用 trainer.apply_gradients 更新權重
        train_loss += tf.reduce_sum(l).numpy()
    print('epoch %d, loss: %f' % (epoch, train_loss/num_count))

結果:
在這裏插入圖片描述

7、預測結果

print(true_w, net.get_weights()[0])
print(true_b,net.get_weights()[1])

結果:
在這裏插入圖片描述
        可以看到,上節我們使用了整整50個epoch纔將loss訓練到比較小的地步,而使用高階API,訓練速度還加快了。

下面附上所有代碼:

import tensorflow as tf

from tensorflow import data as tfdata

#1、生成數據集
tf.random.set_seed(99)
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4] #真實權重
true_b = 4.2 # 真實偏置值
features = tf.random.normal((num_examples, num_inputs),stddev =1)
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += tf.random.normal(labels.shape,stddev=0.01)

#2、讀取數據
batch_size = 10
# 將訓練數據的特徵和標籤組合
dataset = tfdata.Dataset.from_tensor_slices((features, labels))
# 隨機讀取小批量
dataset = dataset.shuffle(buffer_size=num_examples) #shuffle 的 buffer_size 參數應大於等於樣本數,相當於開闢一個存儲數據的空間,batch 可以指定 batch_size 的分割大小。
dataset = dataset.batch(batch_size) #取數據

for batch_x, batch_y in dataset:
    print(batch_x, batch_y)
    break

#3、定義模型和初始化參數
def linreg():
    model=tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(1,kernel_initializer=tf.random_normal_initializer(stddev=0.01)))
    return model

net=linreg()

#4、定義損失函數
loss = tf.losses.MeanSquaredError()

#5、定義優化器
trainer = tf.keras.optimizers.SGD(learning_rate=0.03)

#6、訓練
'''
通過調用tf.GradientTape記錄動態圖梯度,執行tape.gradient獲得動態圖中各變量梯度。
通過 model.trainable_variables 找到需要更新的變量,並用 trainer.apply_gradients 更新權重,
完成一步訓練。
'''
num_epochs = 10
for epoch in range(1, num_epochs + 1):
    train_loss, num_count = 0, 0
    for X, y in dataset:
        num_count+=1
        with tf.GradientTape() as tape:
            l = loss(net(X, training=True), y)
        grads = tape.gradient(l, net.trainable_variables) #通過 model.trainable_variables 找到需要更新的變量
        trainer.apply_gradients(zip(grads, net.trainable_variables))#使用 trainer.apply_gradients 更新權重
        train_loss += tf.reduce_sum(l).numpy()
    print('epoch %d, loss: %f' % (epoch, train_loss/num_count))

#7、預測結果
print(true_w, net.get_weights()[0])
print(true_b,net.get_weights()[1])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章