tf.GrandientTape 訓練簡單的線性梯度下降模型
添加引用
首先需要添加TensorFlow引用和Eager Execution,如下:
from __future__ import absolute_import, division, print_function
import tensorflow as tf
tf.enable_eager_execution()
tfe = tf.contrib.eager
構造模型和樣本數(shù)據(jù)
構造一個樣本數(shù)=1000眼坏,權重=3扣溺,偏差=2的模型砂心,并且加入噪點天揖,如下:
NUM_EXAMPLES = 1000 # 樣本數(shù)1000
training_inputs = tf.random_normal([NUM_EXAMPLES]) # 輸出正態(tài)分布的隨機值
noise = tf.random_normal([NUM_EXAMPLES])
training_outputs = training_inputs * 3 + 2 + noise # 構造標簽樣本(權重=3,偏差=2瘸爽,并且加入噪點)
定義函數(shù)
定義預測函數(shù)展运、損失函數(shù)和梯度下降函數(shù)活逆,如下:
# 預測函數(shù)
def prediction(input, weight, bias):
return input * weight + bias
# 使用“均方差”的損失函數(shù)
def loss(weights, biases):
error = prediction(training_inputs, weights, biases) - training_outputs
return tf.reduce_mean(tf.square(error))
# 執(zhí)行梯度下降精刷,返回下降之后的權重和偏差
def grad(weights, biases):
with tf.GradientTape() as tape:
loss_value = loss(weights,biases)
return tape.gradient(loss_value,[weights,biases])
訓練模型
初始化
初始化訓練次數(shù)、學習率蔗候、權重和偏差怒允,如下:
train_steps = 200
learning_rate = 0.01
# 權重和偏差設置任意值
W = tfe.Variable(5.)
B = tfe.Variable(10.)
訓練
for i in range(train_steps):
dW, dB = grad(W, B)
W.assign_sub(dW * learning_rate)
B.assign_sub(dB * learning_rate)
print("Loss at step {:03d}: {:.3f}".format(i, loss(W, B)))
得到訓練后的權重和方差,即我們的模型锈遥。
print("Final loss: {:.3f}".format(loss(W, B)))
print("W = {}, B = {}".format(W.numpy(), B.numpy()))
image
權重=3.018173... 偏差=2.17251... 與我們設定的3和2基本相符纫事。
完整實例代碼如下:
方式一:
from __future__ import absolute_import, division, print_function
import tensorflow as tf
tf.enable_eager_execution()
tfe = tf.contrib.eager
NUM_EXAMPLES = 1000 # 樣本數(shù)1000
training_inputs = tf.random_normal([NUM_EXAMPLES]) # 輸出正態(tài)分布的隨機值
noise = tf.random_normal([NUM_EXAMPLES])
training_outputs = training_inputs * 3 + 2 + noise # 構造標簽樣本(權重=3,偏差=2所灸,并且加入噪點)
# 預測函數(shù)
def prediction(input, weight, bias):
return input * weight + bias
# 使用“均方差”的損失函數(shù)
def loss(weights, biases):
error = prediction(training_inputs, weights, biases) - training_outputs
return tf.reduce_mean(tf.square(error))
# 執(zhí)行梯度下降丽惶,返回下降之后的權重和偏差
def grad(weights, biases):
with tf.GradientTape() as tape:
loss_value = loss(weights,biases)
return tape.gradient(loss_value,[weights,biases])
train_steps = 200
learning_rate = 0.01
# 權重和偏差設置任意值
W = tfe.Variable(5.)
B = tfe.Variable(10.)
print("Initial loss: {:.3f}".format(loss(W, B)))
for i in range(train_steps):
dW, dB = grad(W, B)
W.assign_sub(dW * learning_rate)
B.assign_sub(dB * learning_rate)
print("Loss at step {:03d}: {:.3f}".format(i, loss(W, B)))
print("Final loss: {:.3f}".format(loss(W, B)))
print("W = {}, B = {}".format(W.numpy(), B.numpy()))
方式二(通過將 tfe.Variable 與 tf.GradientTape 結合使用可以更好地封裝模型參數(shù)):
from __future__ import absolute_import, division, print_function
import tensorflow as tf
tf.enable_eager_execution()
tfe = tf.contrib.eager
class Model(tf.keras.Model):
'''自定義模型'''
def __init__(self):
super(Model, self).__init__()
self.W = tfe.Variable(5., name = 'weight')
self.B = tfe.Variable(10., name = 'bias')
def call(self, inputs):
return inputs * self.W + self.B
# 構造樣本數(shù)據(jù)
NUM_EXAMPLES = 2000
training_inputs = tf.random_normal([NUM_EXAMPLES]) # 隨機正態(tài)分布的值
nosie = tf.random_normal([NUM_EXAMPLES]) # 噪點
training_outputs = training_inputs * 3 + 2 + nosie
# 定義損失和梯度函數(shù)
def loss(model, inputs, targets):
error = model(inputs) - targets
return tf.reduce_mean(tf.square(error))
def grad(model, inputs, targets):
with tf.GradientTape() as tape:
loss_value = loss(model, inputs, targets)
return tape.gradient(loss_value, [model.W, model.B])
# 訓練
# 1. 實例化模型
# 2. 模型損失函數(shù)的導數(shù)
# 3. 更新變量的策略
model = Model()
optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.01) # 優(yōu)化器
print("Initial loss: {:.3f}".format(loss(model, training_inputs, training_outputs).numpy()))
# 訓練循環(huán)
for i in range(300):
grads = grad(model, training_inputs, training_outputs)
optimizer.apply_gradients(zip(grads, [model.W, model.B]),global_step=tf.train.get_or_create_global_step())
if i % 20 == 0:
print('Loss at step {:03d}: {:.3f}'.format(i,loss(model, training_inputs,training_outputs).numpy()))
print('Final loss: {:.3f}'.format(loss(model, training_inputs, training_outputs).numpy()))
print('W = {}, B = {}'.format(model.W.numpy(), model.B.numpy()))