【深度學習】TensorFlow實現線性迴歸,程式碼演示。全md文件筆記(程式碼文件已分享)

發表於2024-02-27

本系列文章md筆記(已分享)主要討論深度學習相關知識。可以讓大家熟練掌握機器學習基礎,如分類、迴歸(含程式碼),熟練掌握numpy,pandas,sklearn等框架使用。在演算法上,掌握神經網路的數學原理,手動實現簡單的神經網路結構,在應用上熟練掌握TensorFlow框架使用,掌握神經網路影像相關案例。具體包括:TensorFlow的資料流圖結構,神經網路與tf.keras,卷積神經網路(CNN),商品物體檢測專案介紹,YOLO與SSD,商品檢測資料集訓練和模型匯出與部署。

全套筆記和程式碼自取移步gitee倉庫: gitee倉庫獲取完整文件和程式碼

感興趣的小夥伴可以自取哦,歡迎大家點贊轉發~


共 9 章,60 子模組

TensorFlow介紹

說明TensorFlow的資料流圖結構
應用TensorFlow操作圖
說明會話在TensorFlow程式中的作用
應用TensorFlow實現張量的建立、形狀型別修改操作
應用Variable實現變數op的建立
應用Tensorboard實現圖結構以及張量值的顯示
應用tf.train.saver實現TensorFlow的模型儲存以及載入
應用tf.app.flags實現命令列引數新增和使用
應用TensorFlow實現線性迴歸

2.7 案例:實現線性迴歸

學習目標

  • 目標

    • 應用op的name引數實現op的名字修改
    • 應用variable_scope實現圖程式作用域的新增
    • 應用scalar或histogram實現張量值的跟蹤顯示
    • 應用merge_all實現張量值的合併
    • 應用add_summary實現張量值寫入檔案
    • 應用tf.train.saver實現TensorFlow的模型儲存以及載入
    • 應用tf.app.flags實現命令列引數新增和使用
    • 應用reduce_mean、square實現均方誤差計算
    • 應用tf.train.GradientDescentOptimizer實現有梯度下降最佳化器建立
    • 應用minimize函式最佳化損失
    • 知道梯度爆炸以及常見解決技巧
  • 應用

    • 實現線性迴歸模型
  • 內容預覽

    • 2.7.1 線性迴歸原理複習
    • 2.7.2 案例:實現線性迴歸的訓練
    • 2.7.3 增加其他功能

      • 1 增加變數顯示
      • 2 增加名稱空間
      • 3 模型的儲存與載入
      • 4 命令列引數使用

2.7.1 線性迴歸原理複習

根據資料建立迴歸模型,w1x1+w2x2+…..+b = y,透過真實值與預測值之間建立誤差,使用梯度下降最佳化得到損失最小對應的權重和偏置。最終確定模型的權重和偏置引數。最後可以用這些引數進行預測。

2.7.2 案例:實現線性迴歸的訓練

1 案例確定

  • 假設隨機指定100個點,只有一個特徵
  • 資料本身的分佈為 y = 0.8 * x + 0.7

    這裡將資料分佈的規律確定,是為了使我們訓練出的引數跟真實的引數(即0.8和0.7)比較是否訓練準確

2 API

運算

  • 矩陣運算

    • tf.matmul(x, w)
  • 平方

    • tf.square(error)
  • 均值

    • tf.reduce_mean(error)

梯度下降最佳化

  • tf.train.GradientDescentOptimizer(learning_rate)

    • 梯度下降最佳化
    • learning_rate:學習率,一般為0~1之間比較小的值
    • method:

      • minimize(loss)
    • return:梯度下降op

3 步驟分析

  • 1 準備好資料集:y = 0.8x + 0.7 100個樣本
  • 2 建立線性模型

    • 隨機初始化W1和b1
    • y = W·X + b,目標:求出權重W和偏置b
  • 3 確定損失函式(預測值與真實值之間的誤差)-均方誤差
  • 4 梯度下降最佳化損失:需要指定學習率(超引數)

4 實現完整功能

import tensorflow as tf
import os

def linear_regression():
    """
    自實現線性迴歸
    :return: None
    """
    # 1)準備好資料集:y = 0.8x + 0.7 100個樣本
    # 特徵值X, 目標值y_true
    X = tf.random_normal(shape=(100, 1), mean=2, stddev=2)
    # y_true [100, 1]
    # 矩陣運算 X(100, 1)* (1, 1)= y_true(100, 1)
    y_true = tf.matmul(X, [[0.8]]) + 0.7
    # 2)建立線性模型:
    # y = W·X + b,目標:求出權重W和偏置b
    # 3)隨機初始化W1和b1
    weights = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)))
    bias = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)))
    y_predict = tf.matmul(X, weights) + bias
    # 4)確定損失函式(預測值與真實值之間的誤差)-均方誤差
    error = tf.reduce_mean(tf.square(y_predict - y_true))
    # 5)梯度下降最佳化損失:需要指定學習率(超引數)
    # W2 = W1 - 學習率*(方向)
    # b2 = b1 - 學習率*(方向)
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)

    # 初始化變數
    init = tf.global_variables_initializer()
    # 開啟會話進行訓練
    with tf.Session() as sess:
        # 執行初始化變數Op
        sess.run(init)
        print("隨機初始化的權重為%f, 偏置為%f" % (weights.eval(), bias.eval()))
        # 訓練模型
        for i in range(100):
            sess.run(optimizer)
            print("第%d步的誤差為%f,權重為%f, 偏置為%f" % (i, error.eval(), weights.eval(), bias.eval()))

    return None

6 變數的trainable設定觀察

trainable的引數作用,指定是否訓練

weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0), name="weights", trainable=False)

2.7.3 增加其他功能

  • 增加名稱空間
  • 命令列引數設定

2 增加名稱空間

是程式碼結構更加清晰,Tensorboard圖結構清楚

with tf.variable_scope("lr_model"):
def linear_regression():
    # 1)準備好資料集:y = 0.8x + 0.7 100個樣本
    # 特徵值X, 目標值y_true
    with tf.variable_scope("original_data"):
        X = tf.random_normal(shape=(100, 1), mean=2, stddev=2, name="original_data_x")
        # y_true [100, 1]
        # 矩陣運算 X(100, 1)* (1, 1)= y_true(100, 1)
        y_true = tf.matmul(X, [[0.8]], name="original_matmul") + 0.7
    # 2)建立線性模型:
    # y = W·X + b,目標:求出權重W和偏置b
    # 3)隨機初始化W1和b1
    with tf.variable_scope("linear_model"):
        weights = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)), name="weights")
        bias = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)), name="bias")
        y_predict = tf.matmul(X, weights, name="model_matmul") + bias
    # 4)確定損失函式(預測值與真實值之間的誤差)-均方誤差
    with tf.variable_scope("loss"):
        error = tf.reduce_mean(tf.square(y_predict - y_true), name="error_op")
    # 5)梯度下降最佳化損失:需要指定學習率(超引數)
    # W2 = W1 - 學習率*(方向)
    # b2 = b1 - 學習率*(方向)
    with tf.variable_scope("gd_optimizer"):
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01, name="optimizer").minimize(error)

    # 2)收集變數
    tf.summary.scalar("error", error)
    tf.summary.histogram("weights", weights)
    tf.summary.histogram("bias", bias)

    # 3)合併變數
    merge = tf.summary.merge_all()

    # 初始化變數
    init = tf.global_variables_initializer()
    # 開啟會話進行訓練
    with tf.Session() as sess:
        # 執行初始化變數Op
        sess.run(init)
        print("隨機初始化的權重為%f, 偏置為%f" % (weights.eval(), bias.eval()))
        # 1)建立事件檔案
        file_writer = tf.summary.FileWriter(logdir="./summary", graph=sess.graph)
        # 訓練模型
        for i in range(100):
            sess.run(optimizer)
            print("第%d步的誤差為%f,權重為%f, 偏置為%f" % (i, error.eval(), weights.eval(), bias.eval()))
            # 4)執行合併變數op
            summary = sess.run(merge)
            file_writer.add_summary(summary, i)

    return None

3 模型的儲存與載入

  • 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)

4 命令列引數使用

  • 1、
  • 2、 tf.app.flags.,在flags有一個FLAGS標誌,它在程式中可以呼叫到我們

前面具體定義的flag_name

  • 3、透過tf.app.run()啟動main(argv)函式
  
  
# 定義一些常用的命令列引數
  
  
  
  
# 訓練步數
  
  
tf.app.flags.DEFINE_integer("max_step", 0, "訓練模型的步數")
  
  
# 定義模型的路徑
  
  
tf.app.flags.DEFINE_string("model_dir", " ", "模型儲存的路徑+模型名字")

  
  
# 定義獲取命令列引數
  
  
FLAGS = tf.app.flags.FLAGS

  
  
# 開啟訓練
  
  
  
  
# 訓練的步數(依據模型大小而定)
  
  
for i in range(FLAGS.max_step):
     sess.run(train_op)

完整程式碼

import tensorflow as tf
import os

tf.app.flags.DEFINE_string("model_path", "./linear_regression/", "模型儲存的路徑和檔名")
FLAGS = tf.app.flags.FLAGS


def linear_regression():
    # 1)準備好資料集:y = 0.8x + 0.7 100個樣本
    # 特徵值X, 目標值y_true
    with tf.variable_scope("original_data"):
        X = tf.random_normal(shape=(100, 1), mean=2, stddev=2, name="original_data_x")
        # y_true [100, 1]
        # 矩陣運算 X(100, 1)* (1, 1)= y_true(100, 1)
        y_true = tf.matmul(X, [[0.8]], name="original_matmul") + 0.7
    # 2)建立線性模型:
    # y = W·X + b,目標:求出權重W和偏置b
    # 3)隨機初始化W1和b1
    with tf.variable_scope("linear_model"):
        weights = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)), name="weights")
        bias = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)), name="bias")
        y_predict = tf.matmul(X, weights, name="model_matmul") + bias
    # 4)確定損失函式(預測值與真實值之間的誤差)-均方誤差
    with tf.variable_scope("loss"):
        error = tf.reduce_mean(tf.square(y_predict - y_true), name="error_op")
    # 5)梯度下降最佳化損失:需要指定學習率(超引數)
    # W2 = W1 - 學習率*(方向)
    # b2 = b1 - 學習率*(方向)
    with tf.variable_scope("gd_optimizer"):
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01, name="optimizer").minimize(error)

    # 2)收集變數
    tf.summary.scalar("error", error)
    tf.summary.histogram("weights", weights)
    tf.summary.histogram("bias", bias)

    # 3)合併變數
    merge = tf.summary.merge_all()

    # 初始化變數
    init = tf.global_variables_initializer()

    # 開啟會話進行訓練
    with tf.Session() as sess:
        # 執行初始化變數Op
        sess.run(init)
        # 未經訓練的權重和偏置
        print("隨機初始化的權重為%f, 偏置為%f" % (weights.eval(), bias.eval()))
        # 當存在checkpoint檔案,就載入模型

        # 1)建立事件檔案
        file_writer = tf.summary.FileWriter(logdir="./summary", graph=sess.graph)
        # 訓練模型
        for i in range(100):
            sess.run(optimizer)
            print("第%d步的誤差為%f,權重為%f, 偏置為%f" % (i, error.eval(), weights.eval(), bias.eval()))
            # 4)執行合併變數op
            summary = sess.run(merge)
            file_writer.add_summary(summary, i)

    return None


def main(argv):
    print("這是main函式")
    print(argv)
    print(FLAGS.model_path)
    linear_regression()

if __name__ == "__main__":
    tf.app.run()

作業:將程式導向改為物件導向

參考程式碼

  
  
# 用tensorflow自實現一個線性迴歸案例
  
  

  
  
# 定義一些常用的命令列引數
  
  
  
  
# 訓練步數
  
  
tf.app.flags.DEFINE_integer("max_step", 0, "訓練模型的步數")
  
  
# 定義模型的路徑
  
  
tf.app.flags.DEFINE_string("model_dir", " ", "模型儲存的路徑+模型名字")

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):
        """
        根據輸入資料建立模型
        :param feature:
        :param label:
        :return:
        """
        with tf.variable_scope("linea_model"):
            # 2、建立迴歸模型,分析別人的資料的特徵數量--->權重數量, 偏置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

    def loss(self, y_true, y_predict):
        """
        目標值和真實值計算損失
        :return: loss
        """
        # 3、求出我們模型跟真實資料之間的損失
        # 均方誤差公式
        loss = tf.reduce_mean(tf.square(y_true - y_predict))

        return loss

    def merge_summary(self, loss):

        # 1、收集張量的值
        tf.summary.scalar("losses", loss)

        tf.summary.histogram("w", self.weight)
        tf.summary.histogram('b', self.bias)

        # 2、合併變數
        merged = tf.summary.merge_all()

        return merged

    def sgd_op(self, loss):
        """
        獲取訓練OP
        :return:
        """
        # 4、使用梯度下降最佳化器最佳化
        # 填充學習率: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()))

                # 開啟訓練
                # 訓練的步數(依據模型大小而定)
                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 __name__ == '__main__':
    lr = MyLinearRegression()
    lr.train()

未完待續, 同學們請等待下一期

全套筆記和程式碼自取移步gitee倉庫: gitee倉庫獲取完整文件和程式碼

感興趣的小夥伴可以自取哦,歡迎大家點贊轉發~

相關文章