TensorFlow實現線性迴歸

線性迴歸(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()

 

訓練結果:

相關文章
相關標籤/搜索