【Tensorflow1.0】利用神經網絡實現線性迴歸的預測

以前講到了基於tensorflow解決線性迴歸的預測問題:Tensorflow——實現最簡單的線性迴歸模型的預測(原)python

其中,咱們是在已知直線方程 y = w * x + b的前提下,經過機器學習來反推出w和b的值git

可是若是在沒有已知方程的前提下,如何來根據給定的x值預測y的值呢?那麼這時候就須要用到(多層)神經網絡了github

====================================================網絡

咱們將以前的代碼改爲神經網絡的實現,只須要將模型部分修改一下就能夠了app

W = tf.Variable(tf.zeros([1]))
B = tf.Variable(tf.zeros([1]))
OUT = X * W + B

把這部分模型改爲(多層)神經網絡dom

下面一共有三層,L1和L2是神經網絡層(隱藏層),OUT爲輸出層L1有10個神經元,L2有10個神經元,OUT只有一個輸出(就是y的預測值)機器學習

W1 = tf.Variable(tf.random_normal([1, 10]))
B1 = tf.Variable(tf.random_normal([10]))
L1 = tf.nn.relu(tf.add(tf.matmul(X, W1), B1))

W2 = tf.Variable(tf.random_normal([10, 10]))
B2 = tf.Variable(tf.random_normal([10]))
L2 = tf.nn.relu(tf.add(tf.matmul(L1, W2), B2))

WOUT = tf.Variable(tf.random_normal([10, 1]))
BOUT = tf.Variable(tf.random_normal([1]))
OUT = tf.nn.relu(tf.add(tf.matmul(L2, WOUT), BOUT))

至於W1爲何是1*10,W2爲何是10*10,WOUT爲何是10*1函數

在神經網絡中的意義:學習

  • 輸入層1個節點鏈接到L1層的10個節點
  • L1層的10個節點鏈接到L2層的10個節點
  • L2層的10個節點鏈接到輸出層的1個節點

在矩陣運算中的意義:.net

  • input的1*1和L1的1*10矩陣相乘獲得一個1*10的矩陣
  • 再和L2的10*10矩陣相乘,仍然是一個1*10的矩陣
  • 最後和輸出層的10*1矩陣相乘,獲得一個1*1的矩陣,就是output

參數B(B一、B二、BOUT)爲偏移量,長度和當層神經元的個數相同

====================================================

可是僅僅作這些修改是沒法正常運行的,會有運行時異常,由於神經網絡的運算是矩陣運算,因此咱們須要將相關的地方都改爲矩陣

佔位改爲1*1的矩陣

X = tf.placeholder(tf.float32, [1, 1])
Y = tf.placeholder(tf.float32, [1, 1])

訓練和預測的部分輸入值也必須是1*1矩陣

sess.run([optimizer, loss], feed_dict={X: [[x_data]], Y: [[y_data]]})
sess.run(OUT, feed_dict={X: [[x_data]]})

損失函數仍然使用以前的方差函數,爲了將訓練速度加快,咱們將訓練步長改成0.01

loss = tf.reduce_mean(tf.square(Y - OUT))
optimizer = tf.train.AdamOptimizer(0.01).minimize(loss)

訓練過程以下:

由於沒有使用直線方程做爲模型,不存在變量w和b,因此這邊就沒有打印w和b的值

epoch= 0 _loss= 2499.2158
epoch= 5000 _loss= 26.200289
epoch= 10000 _loss= 18.451694
epoch= 15000 _loss= 27.851042
epoch= 20000 _loss= 0.80013156
epoch= 25000 _loss= 6.399736
epoch= 30000 _loss= 0.42621955
epoch= 35000 _loss= 6.539572
epoch= 40000 _loss= 118.756004
epoch= 45000 _loss= 9.849824

預測結果以下:

從中能夠發現第3次的預測結果相差很大,其餘的預測結果仍是很接近的

x= 6.701938926943123 y預測= [[13.210411]] y實際= 12.461334480606848
x= 14.517219202811821 y預測= [[55.388046]] y實際= 54.116778350987005
x= 0.5071548382130286 y預測= [[-0.]] y實際= -20.556864712324558
x= 4.522887130946821 y預測= [[1.7613227]] y實際= 0.8469884079465544
x= 15.859426349977381 y預測= [[62.63169]] y實際= 61.27074244537944
x= 20.760960906047075 y預測= [[89.08439]] y實際= 87.3959216292309
x= 27.817233959488124 y預測= [[127.16579]] y實際= 125.0058570040717
x= 7.207120423200983 y預測= [[15.936781]] y實際= 15.153951855661237
x= 18.68547195335005 y預測= [[77.88335]] y實際= 76.33356551135576
x= 6.211735333477534 y預測= [[10.56487]] y實際= 9.848549327435254

====================================================

因爲神經網絡的不肯定性,哪怕是相同的模型和相同的樣本,每次的訓練結果也會不同

這裏是由於選用的損失函數可能有點問題,不是每次訓練都會成功

另外,若是預測結果精度不夠,能夠經過增長訓練的方法來提升精度,就是使用更多的樣原本進行訓練

epoch= 0 _loss= 2526.3677
epoch= 5000 _loss= 4273.6484
epoch= 10000 _loss= 10332.345
epoch= 15000 _loss= 65.311
epoch= 20000 _loss= 9910.367
epoch= 25000 _loss= 5564.832
epoch= 30000 _loss= 10158.441
epoch= 35000 _loss= 249.78651
epoch= 40000 _loss= 4314.363
epoch= 45000 _loss= 702.9666

x= 12.38727016058595 y預測= [[-0.]] y實際= 42.764149955923116
x= 10.922809365164358 y預測= [[-0.]] y實際= 34.95857391632603
x= 9.296139279977996 y預測= [[-0.]] y實際= 26.28842236228272
x= 4.085033713695978 y預測= [[-0.]] y實際= -1.4867703060004374
x= 5.896742509909711 y預測= [[-0.]] y實際= 8.169637577818758
x= 12.12864019253157 y預測= [[-0.]] y實際= 41.38565222619326
x= 26.964092732084474 y預測= [[-0.]] y實際= 120.45861426201024
x= 0.8534877898439863 y預測= [[-0.]] y實際= -18.710910080131555
x= 4.472453183527925 y預測= [[-0.]] y實際= 0.5781754682038382
x= 26.249269554849263 y預測= [[-0.]] y實際= 116.64860672734657

====================================================

完整代碼以下,在python3.6.八、tensorflow1.13環境下成功運行

https://github.com/yukiti2007/sample/blob/master/python/tensorflow/wx_b_nn.py

import random

import matplotlib.pyplot as plt
import tensorflow as tf


def create_data(for_train=False):
    w = 5.33
    b = -23.26
    x = random.random() * 30
    y = w * x + b

    if for_train:
        noise = (random.random() - 0.5) * 10
        y += noise

    return x, y


def draw():
    x_data, y_data = [], []
    for _ in range(100):
        x, y = create_data(True)
        x_data.append(x)
        y_data.append(y)
    plt.figure()
    plt.scatter(x_data, y_data)
    plt.show()


def run():
    LOSS = []
    STEP = []
    X = tf.placeholder(tf.float32, [1, 1])
    Y = tf.placeholder(tf.float32, [1, 1])

    W1 = tf.Variable(tf.random_normal([1, 10]))
    B1 = tf.Variable(tf.random_normal([10]))
    L1 = tf.nn.relu(tf.add(tf.matmul(X, W1), B1))

    W2 = tf.Variable(tf.random_normal([10, 10]))
    B2 = tf.Variable(tf.random_normal([10]))
    L2 = tf.nn.relu(tf.add(tf.matmul(L1, W2), B2))

    WOUT = tf.Variable(tf.random_normal([10, 1]))
    BOUT = tf.Variable(tf.random_normal([1]))
    OUT = tf.nn.relu(tf.add(tf.matmul(L2, WOUT), BOUT))

    loss = tf.reduce_mean(tf.square(Y - OUT))
    optimizer = tf.train.AdamOptimizer(0.01).minimize(loss)

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        for epoch in range(50000):
            x_data, y_data = create_data(True)
            _, _loss = sess.run([optimizer, loss], feed_dict={X: [[x_data]], Y: [[y_data]]})
            if 0 == epoch % 500:
                LOSS.append(_loss)
                STEP.append(epoch)
            if 0 == epoch % 5000:
                print("epoch=", epoch, "_loss=", _loss)

        print("")

        for step in range(10):
            x_data, y_data = create_data(False)
            prediction_value = sess.run(OUT, feed_dict={X: [[x_data]]})
            print("x=", x_data, "y預測=", prediction_value, "y實際=", y_data)

    plt.figure()
    plt.scatter(STEP, LOSS)
    plt.show()


if __name__ == "__main__":
    # draw()
    run()
相關文章
相關標籤/搜索