線性迴歸(Linear regression)是利用迴歸方程(函數)對一個或多個自變量(特徵值)和因變量(目標值)之間關係進行建模的一種分析方式。python
特色:只有一個自變量的狀況稱爲單變量回歸,大於一個自變量狀況的叫作多元迴歸算法
通用公式:h(w) = w1x1+w2x2+w3x3+...+b=wTx + b網絡
根據數據創建迴歸模型,w1x1+w2x2+…..+b = y,經過真實值與預測值之間創建偏差,使用梯度降低優化獲得損失最小對應的權重和偏置。最終肯定模型的權重和偏置參數,最後能夠用這些參數進行預測。app
線性迴歸案例:dom
假設隨機指定100個點,只有一個特徵
數據自己的分佈爲 y = 0.7 * x + 0.8
這裏將數據分佈的規律肯定,是爲了使咱們訓練出的參數跟真實的參數(即0.7和0.8)比較是否訓練準確函數
TensorFlow計算API:
運算學習
矩陣運算
tf.matmul(x, w)
平方
tf.square(error)
均值
tf.reduce_mean(error)優化
梯度降低優化spa
tf.train.GradientDescentOptimizer(learning_rate)
梯度降低優化
learning_rate:學習率,通常爲0~1之間比較小的值
method:
minimize(loss)
return:梯度降低op命令行
步驟分析:
一、準備數據的特徵值和目標值 inputs
獲取特徵值目標值數據數據
def inputs(self):
"""
獲取特徵值目標值數據數據
:return:
"""
x_data = tf.random_normal([100, 1], mean=1.0, stddev=1.0, name="x_data")
y_true = tf.matmul(x_data, [[0.7]]) + 0.8
return x_data, y_true
二、根據特徵值創建線性迴歸模型(肯定參數個數形狀) inference
根據輸入數據創建模型,模型的參數必須使用變量OP建立
def inference(self, feature):
"""
根據輸入數據創建模型
:param feature:
:param label:
:return:
"""
with tf.variable_scope("linea_model"):
# 創建迴歸模型,分析別人的數據的特徵數量--->權重數量, 偏置b
# 因爲有梯度降低算法優化,因此一開始給隨機的參數,權重和偏置
# 被優化的參數,必須得使用變量op去定義
# 變量初始化權重和偏置
# weight 2維[1, 1] bias [1]
# 變量op當中會有trainable參數決定是否訓練
self.weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0),
name="weights")
self.bias = tf.Variable(0.0, name='biases')
# 創建迴歸公式去得出預測結果
y_predict = tf.matmul(feature, self.weight) + self.bias
return y_predict
三、根據模型得出預測結果,創建損失 loss
求出模型跟真實數據之間的損失
def loss(self, y_true, y_predict):
"""
目標值和真實值計算損失
:return: loss
"""
# 均方偏差公式
loss = tf.reduce_mean(tf.square(y_true - y_predict))
return loss
四、梯度降低優化器優化損失 sgd_op
使用梯度降低優化器優化
def sgd_op(self, loss):
"""
獲取訓練OP
:return:
"""
# 填充學習率:0 ~ 1 學習率是很是小,
# 學習率大小決定你到達損失一個步數多少
# 最小化損失
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
return train_op
學習率的設置、步長的設置與梯度爆炸
學習率越大,訓練到較好結果的步長越小;學習率越小,訓練到較好結果的步長越大。可是學習過大會出現梯度爆炸現象(在極端狀況下,權重的值變得很是大,以致於溢出,致使 NaN 值)
如何解決梯度爆炸問題:
1. 從新設計網絡
2. 調整學習率
3. 使用梯度截斷(在訓練過程當中檢查和限制梯度的大小)
4. 使用激活函數
變量的trainable設置觀察
trainable的參數做用,指定是否訓練
weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0), name="weights", trainable=False)
增長變量顯示
目的:在TensorBoard當中觀察模型的參數、損失值等變量值的變化
一、收集變量
tf.summary.scalar(name=’’,tensor) 收集對於損失函數和準確率等單值變量,name爲變量的名字,tensor爲值
tf.summary.histogram(name=‘’,tensor) 收集高維度的變量參數
tf.summary.image(name=‘’,tensor) 收集輸入的圖片張量能顯示圖片
# 收集張量的值
tf.summary.scalar("losses", loss)
tf.summary.histogram("w", self.weight)
tf.summary.histogram('b', self.bias)
二、合併變量寫入事件文件
merged = tf.summary.merge_all()
運行合併:summary = sess.run(merged),每次迭代都需運行
添加:FileWriter.add_summary(summary,i),i表示第幾回的值
# 合併變量
merged = tf.summary.merge_all()
# 生成事件文件,觀察圖結構
file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)
# 運行收集變量的結果
summary = sess.run(merged)
# 添加到文件
file_writer.add_summary(summary, i)
模型的保存與加載
tf.train.Saver(var_list=None,max_to_keep=5)
保存和加載模型(保存文件格式:checkpoint文件)
var_list:指定將要保存和還原的變量。它能夠做爲一個dict或一個列表傳遞.
max_to_keep:指示要保留的最近檢查點文件的最大數量。建立新文件時,會刪除較舊的文件。若是無或0,則保留全部檢查點文件。默認爲5(即保留最新的5個檢查點文件。)
指定目錄+模型名字
saver.save(sess, '/tmp/ckpt/test/myregression.ckpt')
saver.restore(sess, '/tmp/ckpt/test/myregression.ckpt')
如要判斷模型是否存在,直接指定目錄
checkpoint = tf.train.latest_checkpoint("./tmp/model/")
saver.restore(sess, checkpoint)
完整代碼:
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
# 定義一些經常使用的命令行參數
# 訓練步數
tf.app.flags.DEFINE_integer("max_step", 10, "訓練模型的步數")
# 定義模型的路徑
tf.app.flags.DEFINE_string("model_dir", "./tmp/model/myregression.ckpt ", "模型保存的路徑+模型名字")
FLAGS = tf.app.flags.FLAGS
class MyLinearRegression(object):
"""
自實現線性迴歸
"""
def __init__(self):
pass
def inputs(self):
"""
獲取特徵值目標值數據
:return:
"""
x_data = tf.random_normal([100, 1], mean=1.0, stddev=1.0, name="x_data")
y_true = tf.matmul(x_data, [[0.7]]) + 0.8
return x_data, y_true
def inference(self, feature):
"""
根據輸入數據創建模型
創建迴歸模型,分析別人的數據的特徵數量--->權重數量, 偏置b
:param feature:
:return:
"""
with tf.variable_scope("linea_model"):
# 因爲有梯度降低算法優化,因此一開始給隨機的參數,權重和偏置
# 被優化的參數,必須得使用變量op去定義
# 變量初始化權重和偏置
# weight 2維[1, 1] bias [1]
# 變量op當中會有trainable參數決定是否訓練
self.weight = tf.Variable(
tf.random_normal([1, 1], mean=0.0, stddev=1.0),
name="weights"
)
self.bias = tf.Variable(0.0, name='biases')
# 創建迴歸公式去得出預測結果
y_predict = tf.matmul(feature, self.weight) + self.bias
return y_predict
def loss(self, y_true, y_predict):
"""
目標值和真實值計算損失
求出咱們模型跟真實數據之間的損失
:return: loss
"""
# 均方偏差公式
loss = tf.reduce_mean(tf.square(y_true - y_predict))
return loss
def merge_summary(self, loss):
# 一、收集張量的值
tf.summary.scalar("losses", loss)
tf.summary.histogram("w", self.weight)
tf.summary.histogram('b', self.bias)
# 二、合併變量
merged = tf.summary.merge_all()
return merged
def sgd_op(self, loss):
"""
獲取訓練OP
:return:
"""
# 使用梯度降低優化器優化
# 填充學習率:0 ~ 1 學習率是很是小,
# 學習率大小決定你到達損失一個步數多少
# 最小化損失
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
return train_op
def train(self):
"""
訓練模型
:param loss:
:return:
"""
g = tf.get_default_graph()
with g.as_default():
x_data, y_true = self.inputs()
y_predict = self.inference(x_data)
loss = self.loss(y_true, y_predict)
train_op = self.sgd_op(loss)
# 收集觀察的結果值
merged = self.merge_summary(loss)
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# 在沒訓練,模型的參數值
print("初始化的權重:%f, 偏置:%f" % (self.weight.eval(), self.bias.eval()))
# 加載模型
checkpoint = tf.train.latest_checkpoint("./tmp/model/")
if checkpoint:
print('Restoring', checkpoint)
saver.restore(sess, checkpoint)
# 開啓訓練
# 訓練的步數(依據模型大小而定)
print(FLAGS.max_step)
for i in range(FLAGS.max_step):
sess.run(train_op)
# 生成事件文件,觀察圖結構
file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)
print("訓練第%d步以後的損失:%f, 權重:%f, 偏置:%f" % (
i,
loss.eval(),
self.weight.eval(),
self.bias.eval()))
# 運行收集變量的結果
summary = sess.run(merged)
# 添加到文件
file_writer.add_summary(summary, i)
if i % 100 == 0:
# 保存的是會話當中的變量op值,其餘op定義的值不保存
print(sess)
saver.save(sess, FLAGS.model_dir)
if __name__ == '__main__':
lr = MyLinearRegression()
lr.train()
訓練結果: