Tensorflow-線性迴歸與手寫數字分類

清風紫雪發表於2021-01-26

線性迴歸

步驟

  • 構造線性迴歸資料
  • 定義輸入層
  • 設計神經網路中間層
  • 定義神經網路輸出層
  • 計算二次代價函式,構建梯度下降
  • 進行訓練,獲取預測值
  • 畫圖展示

程式碼

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
tf.compat.v1.disable_eager_execution()

#3-1非線性迴歸
#使用numpy生成200個隨機點,200行1列
x_data=np.linspace(-0.5,0.5,200)[:,np.newaxis]
noise=np.random.normal(0,0.02,x_data.shape)
#square為平方
y_data=np.square(x_data)+noise
print(x_data)
print(y_data)
print(y_data.shape)

#定義兩個placeholder
#輸入層:一個神經元
x=tf.compat.v1.placeholder(tf.float32,[None,1])
y=tf.compat.v1.placeholder(tf.float32,[None,1])

#定義神經網路中間層
#中間層:10個神經元
Weights_L1=tf.Variable(tf.compat.v1.random_normal([1,10]))
biases_L1=tf.Variable(tf.zeros([1,10]))
Wx_plus_b_L1=tf.matmul(x,Weights_L1)+biases_L1
#L1中間層的輸出,tanh為啟用函式
L1=tf.nn.tanh(Wx_plus_b_L1)


#定義神經網路輸出層
#輸出層:一個神經元
Weights_L2=tf.Variable(tf.compat.v1.random_normal([10,1]))
biases_L2=tf.Variable(tf.zeros([1,1]))
#輸出層的輸入就是中間層的輸出,故為L1
Wx_plus_b_L2=tf.matmul(L1,Weights_L2)+biases_L2
#預測結果
prediction=tf.nn.tanh(Wx_plus_b_L2)


#二次代價函式
#真實值減去預測值的平方的平均值
loss=tf.reduce_mean(tf.square(y-prediction))
#梯度下降:學習率,最下化為loss
train_step=tf.compat.v1.train.GradientDescentOptimizer(0.1).minimize(loss)

#定義會話
with tf.compat.v1.Session() as sess:
    # 變數初始化
    sess.run(tf.compat.v1.global_variables_initializer())
    # 開始訓練
    for _ in range(2000):
        #使用placeholder進行傳值,傳入樣本值
        sess.run(train_step,feed_dict={x:x_data,y:y_data})

    #訓練好後,獲得預測值,同時傳入樣本引數
    prediction_value=sess.run(prediction,feed_dict={x:x_data})

    #畫圖
    plt.figure()
    # 用散點圖,來畫出樣本點
    plt.scatter(x_data,y_data)
    # 預測圖,紅色實現,線款為5
    plt.plot(x_data,prediction_value,'r-',lw=5)
    plt.show()

展示

 

 

 

手寫數字分類

MNIST資料集

MNIST資料集的官網:Yann LeCun's website下載下來的資料集被分成兩部分:60000行的訓練資料集(mnist.train)和10000行的測試資料集(mnist.test)

資料集詳情

每一張圖片包含28*28個畫素,我們把這一個陣列展開成一個向量,長度是28*28=784。因此在
MNIST訓練資料集中mnist.train.images 是一個形狀為 [60000, 784] 的張量,第一個維度數字用
來索引圖片,第二個維度數字用來索引每張圖片中的畫素點。圖片裡的某個畫素的強度值介於0-1
之間。

 

 

 

 

 

 神經網路搭建

 

 Softmax函式

 

 程式碼

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
tf.compat.v1.disable_eager_execution()
import numpy as np


#載入資料集
mnist=input_data.read_data_sets("MNIST_data",one_hot=True)

#每個批次大小
batch_size=100
#計算一共有多少個批次
n_bath=mnist.train.num_examples // batch_size
print(n_bath)
#定義兩個placeholder
x=tf.compat.v1.placeholder(tf.float32,[None,784])
y=tf.compat.v1.placeholder(tf.float32,[None,10])

#建立一個簡單的神經網路
W=tf.Variable(tf.zeros([784,10]))
b=tf.Variable(tf.zeros([10]))
prediction=tf.nn.softmax(tf.matmul(x,W)+b)


#二次代價函式
loss=tf.reduce_mean(tf.square(y-prediction))
#梯度下降
train_step=tf.compat.v1.train.GradientDescentOptimizer(0.2).minimize(loss)

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

#結果存放在一個布林型列表中
#返回的是一系列的True或False argmax返回一維張量中最大的值所在的位置,對比兩個最大位置是否一致
correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))

#求準確率
#cast:將布林型別轉換為float,將True為1.0,False為0,然後求平均值
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))


with tf.compat.v1.Session() as sess:
    sess.run(init)
    for epoch in range(21):
        for batch in range(n_bath):
            #獲得一批次的資料,batch_xs為圖片,batch_ys為圖片標籤
            batch_xs,batch_ys=mnist.train.next_batch(batch_size)
            #進行訓練
            sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
        #訓練完一遍後,測試下準確率的變化

        acc=sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
        print("Iter "+str(epoch)+",Testing Accuracy "+str(acc))

輸出:

 

 優化程式碼

優化方面:

①批次個數減小到20

②權值不再為0,改為隨機數,設定引數要儘可能小

③增加一個隱藏層,節點數是sqrt(n*l),其中n是輸入節點數,l是輸出節點數,故為89

④代價函式更換為:交叉熵

⑤梯度下降函式更換為-->動量隨機梯度下降,如果上次的準確率比這次準確率還要大,則將0.2乘以0.5

程式碼:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
tf.compat.v1.disable_eager_execution()
import numpy as np


#載入資料集
mnist=input_data.read_data_sets("MNIST_data",one_hot=True)

#每個批次大小
batch_size=20
#計算一共有多少個批次
n_bath=mnist.train.num_examples // batch_size
print(n_bath)
#定義兩個placeholder
x=tf.compat.v1.placeholder(tf.float32,[None,784])
y=tf.compat.v1.placeholder(tf.float32,[None,10])

#建立一個簡單的神經網路
#1.初始化非常重要,引數要儘可能小
W=tf.Variable(tf.compat.v1.random_normal([784,89])/np.sqrt(784))
b=tf.Variable(tf.zeros([89]))
prediction=tf.nn.relu(tf.matmul(x,W)+b)

#第二層
#2.我增加了一個神經網路層,節點數是sqrt(n*l),其中n是輸入節點數,l是輸出節點數
W2=tf.Variable(tf.compat.v1.random_normal([89,10])/np.sqrt(89))
b2=tf.Variable(tf.zeros([10]))
#將其轉換為概率值
prediction2=tf.nn.softmax(tf.matmul(prediction,W2)+b2)


#二次代價函式
# loss=tf.reduce_mean(tf.square(y-prediction2))
#交叉熵
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction2))
#動量隨機梯度下降
#3.如果上次的準確率比這次準確率還要大,則將0.2乘以0.5
train_step=tf.compat.v1.train.MomentumOptimizer(0.2,0.5).minimize(loss)

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

#結果存放在一個布林型列表中
#返回的是一系列的True或False argmax返回一維張量中最大的值所在的位置,對比兩個最大位置是否一致
correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(prediction2,1))

#求準確率
#cast:將布林型別轉換為float,將True為1.0,False為0,然後求平均值
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))


with tf.compat.v1.Session() as sess:
    sess.run(init)
    for epoch in range(21):
        for batch in range(n_bath):
            #獲得一批次的資料,batch_xs為圖片,batch_ys為圖片標籤
            batch_xs,batch_ys=mnist.train.next_batch(batch_size)
            #進行訓練
            sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
        #訓練完一遍後,測試下準確率的變化

        acc=sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
        print("Iter "+str(epoch)+",Testing Accuracy "+str(acc))

輸出:

 

 

相關文章