TensorFlow-2.x-01-從0開始的線性迴歸

        之前我一直使用的是TensorFlow-1.x的版本,雖說靜態圖模式比較繁瑣,但用習慣了之後還是覺得挺不錯的,後來TensorFlow-2.x的版本推出了,聽說採用了Keras的高階API,而且默認使用eager模式,然後我也隨便看了一下構建模型的代碼,第一感覺是跟Pytorch、mxnet好像,如果學習過這兩個DNN框架的朋友們去學TF-2.x的話應該來說比較容易,反正我也不知道到底好不好用,下面我就要像一個小白一樣重新開始學習TensorFlow-2.x了(感覺TF-1.x白學了…)。

        先說一下我的機器上的環境,Python-3.6.7、Tensorflow-2.0.2,CUDA-10.0。我在我的機器上配置了兩個環境,一個是TF-1.13.1的環境,一個就是虛擬環境TF-2.0.2的環境,並沒有使用Anaconda,我用過這東西,可能是我不習慣吧,對它實在是折騰不來,後來通過pip配置了虛擬環境。

        跟mxnet的教程博文一樣,本篇章與mxnet一一對應,有些理論部分就不講解了。

        本章對應的mxnet文章:MXNET深度學習框架-03-採用ndarray和autograd實現線性迴歸

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 =0.1)
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += tf.random.normal(labels.shape,stddev=0.01)
print(features)

1000個2維數據點的結果:
在這裏插入圖片描述
        看起來是不是特簡單,直接打印就行了,要在TF-1.X種,還得使用sess.run()方法。

2、繪製散點圖查看數據

def set_figsize(figsize=(3.5, 2.5)):
    plt.scatter(features[:, 1], labels, 1) # 第二特徵和標籤的對應關係
    plt.show()
set_figsize() #調用function顯示散點圖

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

3、讀取數據

def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        j = indices[i: min(i+batch_size, num_examples)]
        yield tf.gather(features, axis=0, indices=j), tf.gather(labels, axis=0, indices=j)
# 取batch數據
for batch_x, batch_y in data_iter(10, features, labels):
    print("特徵:",batch_x,"\n","標籤:",batch_y)
    break

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

4、定義模型參數

w = tf.Variable(tf.random.normal((num_inputs, 1), stddev=0.01))
b = tf.Variable(tf.zeros((1,)))

5、定義模型結構

def linreg(X, w, b):
    return tf.matmul(X, w) + b

6、定義損失函數

def squared_loss(y_hat, y):
    return (y_hat - tf.reshape(y, y_hat.shape)) ** 2 /2 #爲什麼要除以2?好求導

7、定義小批量隨機梯度下降-SGD

def sgd(params, lr, batch_size, grads):
    for i, param in enumerate(params):
        param.assign_sub(lr * grads[i] / batch_size)

8、訓練模型

lr = 0.03
num_epochs = 50
net = linreg
loss = squared_loss
batch_size=100
for epoch in range(num_epochs):
    train_loss,num_count=0,0
    for X, y in data_iter(batch_size, features, labels):
        num_count+=1  # 取多少次結束
        with tf.GradientTape() as t:
            t.watch([w,b])
            l = loss(net(X, w, b), y)

        grads = t.gradient(l, [w, b])# 通過調用反向函數t.gradients計算小批量隨機梯度,並調用優化算法sgd迭代模型參數
        sgd([w, b], lr, batch_size, grads)
    train_loss+=tf.reduce_sum(l).numpy()

    print('epoch %d, loss %f' % (epoch + 1, train_loss/num_count))

結果:
在這裏插入圖片描述
9、預測結果:

print(true_w, "",w)
print(true_b, "",b)

結果:
在這裏插入圖片描述
可以看到,預測的結果已經很接近了。

下面放上所有代碼:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import random


#1、生成1000個數據
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)
# print(features)


#2、繪製散點圖查看數據
def set_figsize(figsize=(3.5, 2.5)):
    plt.scatter(features[:, 1], labels, 1) # 第二特徵和標籤的對應關係
    plt.show()
set_figsize() #調用function顯示散點圖


#3、讀取數據
def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        j = indices[i: min(i+batch_size, num_examples)]
        yield tf.gather(features, axis=0, indices=j), tf.gather(labels, axis=0, indices=j)
# 取batch數據
for batch_x, batch_y in data_iter(10, features, labels):
    print("特徵:",batch_x,"\n","標籤:",batch_y)
    break

#4、定義權重參數
w = tf.Variable(tf.random.normal((num_inputs, 1), stddev=0.01))
b = tf.Variable(tf.zeros((1,)))

#5、定義模型結構
def linreg(X, w, b):
    return tf.matmul(X, w) + b

#6、定義損失函數
def squared_loss(y_hat, y):
    return (y_hat - tf.reshape(y, y_hat.shape)) ** 2 /2 #爲什麼要除以2?好求導

#7、定義小批量隨機梯度下降-SGD
def sgd(params, lr, batch_size, grads):
    for i, param in enumerate(params):
        param.assign_sub(lr * grads[i] / batch_size)

#8、訓練
lr = 0.03
num_epochs = 50
net = linreg
loss = squared_loss
batch_size=100
for epoch in range(num_epochs):
    train_loss,num_count=0,0
    for X, y in data_iter(batch_size, features, labels):
        num_count+=1  # 取多少次結束
        with tf.GradientTape() as t:
            t.watch([w,b])
            l = loss(net(X, w, b), y)

        grads = t.gradient(l, [w, b])# 通過調用反向函數t.gradients計算小批量隨機梯度,並調用優化算法sgd迭代模型參數
        sgd([w, b], lr, batch_size, grads)
    train_loss+=tf.reduce_sum(l).numpy()

    print('epoch %d, loss %f' % (epoch + 1, train_loss/num_count))
print(true_w, "",w)
print(true_b, "",b)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章