Tensorflow從0到1(3)之實戰傳統機器算法


計算圖中的操作

代碼實現:

import numpy as np
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
sess = tf.Session()
x_vals = np.array([1., 3., 5., 7., 9.])
x_data = tf.placeholder(dtype=tf.float32)
m_const = tf.constant(3.)
my_product = tf.multiply(x_data, m_const)
for x_val in x_vals:
    print(sess.run(my_product, feed_dict={x_data:x_val}))

執行結果:

 

 

Tensorflow的嵌入Layer

代碼實現:

import numpy as np
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
sess = tf.Session()
# 創建數據和占位符
my_array = np.array([[1., 3., 5., 7., 9.],
                     [-2., 0., 2., 4., 6.],
                     [-6., -3., 0., 3., 6.]])
x_vals = np.array([my_array, my_array+1])
x_data = tf.placeholder(shape=(3,5), dtype=tf.float32)
# 創建常量矩陣
m1 = tf.constant([[1.], [0.], [-1.], [2.], [4.]]) # 5x1矩陣
m2 = tf.constant([[2.]]) # 1x1矩陣
a1 = tf.constant([[10.]]) # 1x1矩陣
# 聲明操作, 表示成計算圖
prod1 = tf.matmul(x_data, m1) # 3x5 乘以 5x1 = 3x1
prod2 = tf.matmul(prod1, m2) # 3x1 乘以標量 = 3x1
add1 = tf.add(prod2, a1)
# 賦值
for x_val in x_vals:
    print(sess.run(add1, feed_dict={x_data: x_val}))
sess.close()

執行結果:

注意:對於事先不知道的維度大小,可以用None代替。例如:

x_data = tf.placeholder(dtype=tf.float32, shape=(3,None)) 

Tensorflow的多層layer

對2D圖像數據進行滑動窗口平均,然后通過自定義操作層Layer返回結果。

代碼實現:

import numpy as np
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
sess = tf.Session()
# 創建2D圖像,4X4像素。
x_shape = [1, 4, 4, 1] # [batch, in_height, in_width, in_channels] tensorflow處理(圖片數量,高度、寬度、顏色)思維圖像數據
x_val = np.random.uniform(size=x_shape)
# 占位符
x_data = tf.placeholder(dtype=tf.float32, shape=x_shape)
# 創建滑動窗口
my_filter = tf.constant(0.25, shape=[2,2,1,1]) # [filter_height, filter_width, in_channels, out_channels]
my_strides = [1, 2, 2, 1] # 長寬方向滑動步長均為2
mov_avg_layer = tf.nn.conv2d(x_data, my_filter, my_strides,
                            padding='SAME', name='Moving_avg_Window')
# 定義一個自定義Layer,操作上一步滑動窗口的2x2的返回值。
# 自定義函數將輸入張量乘以一個2X2的矩陣張量,然后每個元素加1.因為矩陣乘法只計算二維矩陣,所以裁剪多余維度(大小為1的維度)。Tensorflow通過內建函數squeeze()函數裁剪。
def custom_layer(input_matrix):
    input_matrix_squeezed = tf.squeeze(input_matrix)
    A = tf.constant([[1., 2.], [-1., 3.]])
    b = tf.constant(1., shape=[2,2])
    temp1 = tf.matmul(A, input_matrix_squeezed)
    temp = tf.add(temp1, b) # Ax+b
    return (tf.sigmoid(temp))
# 把剛剛定義的Layer加入到計算圖中,並用tf.name_scope()命名Layer名稱。
with tf.name_scope('Custom_Layer') as scope:
    custom_layer1 = custom_layer(mov_avg_layer)
# 傳入數據,執行
print(sess.run(custom_layer1, feed_dict={x_data:x_val}))
# 關閉會話,釋放資源
sess.close()

執行結果:

 

 

Tensorflow實現損失函數

損失函數對機器學習來講非常重要,它度量模型輸出值與目標值之間的差距。

回歸問題常用損失函數

代碼實現:

import numpy as np
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
sess = tf.Session()
# 創建2D圖像,4X4像素。
x_shape = [1, 4, 4, 1] # [batch, in_height, in_width, in_channels] tensorflow處理(圖片數量,高度、寬度、顏色)思維圖像數據
x_val = np.random.uniform(size=x_shape)
# 占位符
x_data = tf.placeholder(dtype=tf.float32, shape=x_shape)
# 創建滑動窗口
my_filter = tf.constant(0.25, shape=[2,2,1,1]) # [filter_height, filter_width, in_channels, out_channels]
my_strides = [1, 2, 2, 1] # 長寬方向滑動步長均為2
mov_avg_layer = tf.nn.conv2d(x_data, my_filter, my_strides,
                            padding='SAME', name='Moving_avg_Window')
# 定義一個自定義Layer,操作上一步滑動窗口的2x2的返回值。
# 自定義函數將輸入張量乘以一個2X2的矩陣張量,然后每個元素加1.因為矩陣乘法只計算二維矩陣,所以裁剪多余維度(大小為1的維度)。Tensorflow通過內建函數squeeze()函數裁剪。
def custom_layer(input_matrix):
    input_matrix_squeezed = tf.squeeze(input_matrix)
    A = tf.constant([[1., 2.], [-1., 3.]])
    b = tf.constant(1., shape=[2,2])
    temp1 = tf.matmul(A, input_matrix_squeezed)
    temp = tf.add(temp1, b) # Ax+b
    return (tf.sigmoid(temp))
# 把剛剛定義的Layer加入到計算圖中,並用tf.name_scope()命名Layer名稱。
with tf.name_scope('Custom_Layer') as scope:
    custom_layer1 = custom_layer(mov_avg_layer)
# 傳入數據,執行
print(sess.run(custom_layer1, feed_dict={x_data:x_val}))
# 關閉會話,釋放資源
sess.close()

執行結果:

 

 

關於Huber函數

L1正則在目標值處不平滑。L2正則在異常值處過大,會放大異常值的影響。因此,Huber函數在目標值附近(小於delta)是L2正則,在大於delta處是L1正則。解決上述問題。
參考
Huber損失函數

繪圖展示回歸算法損失函數

x_array = sess.run(x_vals) plt.plot(x_array, l2_y_out, 'b-', label='L2 Loss') plt.plot(x_array, l1_y_out, 'r--', label='L1 Loss') plt.plot(x_array, phuber1_y_out, 'k-', label='P-Huber Loss (0.25)') plt.plot(x_array, phuber2_y_out, 'g:', label='P-Huber Loss (0.5)') plt.ylim(-0.2, 0.4) plt.legend(loc='lower right', prop={'size':11}) plt.show() 

回歸算法損失函數入下圖所示:


 
regression_loss_function.png

可以看出,L2損失函數離0點越遠,損失會被2次方放大。L1損失函數在0點處不可導。P-Huber損失函數則在0點出是近似的L2損失函數,在遠離零點處是近似的斜線。既解決了L1損失梯度下降算法可能不收斂的問題,又減少了異常值的影響。

分類問題常用損失函數

# 創建數據 x_vals = tf.linspace(-3., 5., 500) target = tf.constant(1.) targets = tf.fill([500,], 1) # Hinge 損失函數:評估支持向量機算法,有時也用來評估神經網絡算法。 hinge_y_vals = tf.maximum(0., 1. - tf.multiply(target, x_vals)) hinge_y_out = sess.run(hinge_y_vals) # 兩類交叉熵損失函數(cross-entropy loss): xentropy_y_vals = -tf.multiply(target, tf.log(x_vals)) - tf.multiply((1.-target), tf.log(1. - x_vals)) xentropy_y_out = sess.run(xentropy_y_vals) # Sigmoid交叉熵損失函數:與上面的交叉熵損失函數非常類似,只是先將x_vals值通過sigmoid轉換在計算交叉熵。 xentropy_sigmoid_y_vals = tf.nn.sigmoid_cross_entropy_with_logits(labels = target, logits = x_vals) xentropy_sigmoid_y_out = sess.run(xentropy_sigmoid_y_vals) # 加權交叉熵損失函數:Sigmoid交叉熵損失函數的加權,對正目標加權。 weight = tf.constant(0.5) xentropy_weighted_y_vals = tf.nn.weighted_cross_entropy_with_logits(targets = targets, logits = x_vals, pos_weight = weight) xentropy_weighted_y_out = sess.run(xentropy_weighted_y_vals) # Softmax交叉熵損失函數:作用於非歸一化的輸出結果,只針對單個目標分類的計算損失。 unsacled_logits = tf.constant([[1., -3., 10.]]) target_dist = tf.constant([[0.1, 0.02, 0.88]]) softmax_xentropy = tf.nn.sotfmax_entropy_with_logits(logits = unscaled_logits, labels = target_dist) print(sess.run(softmax_xentropy) # 稀疏Softmax交叉熵損失函數 unscaled_logits = tf.constant([[1., -3., 10.]]) sparse_target_dist = tf.constant([2]) sparese_xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = unscaled_logits, labels = sparse_target_dist) print(sess.run(sparse_xentropy)) 

關於交叉熵的說明

1 信息量

假設我們聽到了兩件事:
A:巴西隊進入了2018世界杯決賽圈;B:中國隊進入了2018世界杯決賽圈。
直覺上來說,事件B比事件A包含的信息量大,因為小概率事件發生了,一定是有些我們不知道的東西。因此,這樣定義信息量:
假設X是一個離散型隨機變量,其取值集合為\chi,概率分布函數 p(x) = Pr(X=x),x\in \chi,則定義事件X=x_0的信息量為:
I(x_0) = -log(p(x_0))

信息量函數如下圖所示:

 
image

 

可以看出-log(x)函數刻畫的信息量,x越接近零越大,越接近1越小。這里便可以理解二分類問題中的logistics回歸的損失函數-y*log(y_hat)-(1-y)*log(1-y_hat), 它會給錯誤分類很大的懲罰。比如,在y=1是,y_hat如果接近0,會導致loss很大,同樣y=0時,y_hat接近1,也會導致loss很大。因此在最小化Loss函數時,會盡可能的將y=1的y_hat預測成1,y=0的y_hat預測為0。

2 熵

對於某個事件,有n中可能,那么求其n中可能的信息量的期望,便是熵。即熵:
H(X) = - \Sigma_{i=1}^np(x_i)*log(p(x_i))

3 相對熵(KL散度)

相對熵又稱KL散度,如果對於隨機變量x有兩個概率分布P(x)和Q(x),我們可以使用KL散度來衡量兩個分布的差異。KL散度的計算公式:
D_{KL}(p||q)=\Sigma_{i=1}^np(x_i)*log(\frac{p(x_i)}{q(x_i)})
可見當q和p的分布越接近時,KL散度越小。當q和p為相同的分布是,KL散度為0。

4 交叉熵

在機器學習里,p是樣本的真實分布。比如貓狗鼠的分類問題,一個樣本點(是貓)的實際分布是(1,0,0)。而q是模型預測分布,比如(0.8,0.1,0.1)。那么我們模型訓練的目標可以設置為是的p、q的KL散度最小化,即q盡可能接近真實的p分布。
而:
\begin{aligned} D_{KL}(p||q) &= \Sigma_{i=1}^np(x_i)*log(\frac{p(x_i)}{q(x_i)}) \\ &=\Sigma_{i=1}^np(x_i)*log(p(x_i))-\Sigma_{i=1}^np(x_i)*log(q(x_i)) \\ &=-H(p(x))+H(p,q) \end{aligned}
其中,H(p(x))=-\Sigma_{i=1}^np(x_i)*log(p(x_i)),是p分布的熵;H(p,q)=-\Sigma_{i=1}^np(x_i)*log(q(x_i))是p和q的交叉熵。由於p是樣本的真實分布,所以H(p(x))是一個常數值。那么KL散度最小化也就等價於交叉熵的最小化。

參考
關於交叉熵在loss函數中使用的理解

關於Softmax損失函數和稀疏Softmax損失函數的說明

首先,Softmax和系數Softmax損失函數最大的不同是輸入的labels不同。對於某一個樣本點,Softmax損失函數輸入的labels是各分類的實際概率,例如貓狗鼠分類,就是(1,0,0)這樣的向量。對於m各樣本點,輸入的labels則是一個m*3的矩陣。而稀疏Softmax,輸入labels是實際所屬類別的index,比如這里是(1,0,0),則輸入就是0。m個樣本點,輸入是m維向量,向量里面的內容是該樣本點所屬類別的索引。
對於單個樣本點,多分類的交叉熵如下:
H_i = -\Sigma_{j=1}^k[y_i]_j*log([p(x_i)]_j), 其中,y_i是樣本點i各類別的實際概率分布(例如(1,0,0)),p(x_i)是預測概率分布(例如(0.7,0.2,0.1))。對於Softmax函數,我們需要計算log(0.7),log(0.2),log(0.1)。但由於log(0.2),log(0.1)前面乘以的實際的[y_i]_j是零,實際上是沒有必要計算的。這樣,Softmax損失函數就會造成算力的浪費,尤其深度學習的數據量非常大,這種浪費往往不能忍受。而稀疏Softmax則只計算[y_i]_j=1時的log([p(x_i)]_j)(這里即log(0.7),可以大大的提升計算性能。因此,對於這種實際分布只有一個1,其他全為零的排他性分類問題,Softmax和稀疏Softmax損失函數沒有本質上的區別,只是后者在計算性能上有一個優化。

評價機器學習模型的其他指標

指標 描述
R^2 對簡單線性模型來講,用於度量因變量中可由自變量解釋部分所占比例。
RMSE (平均方差) 對連續模型來講,是度量預測值和觀測值之差的樣本標准差。
混淆矩陣(Confusion matrix) 對分類模型來講,以矩陣形式將數據集中的記錄按照真實的類別與預測類別兩個標准進行分析匯總,其列代表預測類別,行代表實際類別。理想情況下,混淆矩陣是對角矩陣。
查全率(Recall) 正類中有多少被正確預測(正類中被正確預測為正類的比例)。
查准率(Precision) 被預測為正類的樣本中有多少是真的正類。
F值(F-score) 對於分類模型來講,F值是查全率和查准率的調和平均數

Tensorflow實現反向傳播

簡單的回歸例子

這個例子很簡單,是一個一元線性回歸模型y=Ax。x是均值為1,標准差0.1的標准正態分布生成的100個樣本點。y都是10。這樣回歸參數A應該是10左右。

代碼實現:

import numpy as np
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
# 2 創建會話
sess = tf.Session()
# 3 生成數據,創建占位符和變量
x_vals = np.random.normal(1, 0.1, 100) # 均值為1,標准差為0.1,100個樣本點
y_vals = np.repeat(10., 100) # 10
x_data = tf.placeholder(shape=[1], dtype=tf.float32)
y_target = tf.placeholder(shape=[1], dtype=tf.float32)
A = tf.Variable(tf.random_normal(shape=[1]))
# 4 模型
my_output = tf.multiply(x_data, A)
# 5 增加L2正則損失函數
loss = tf.square(my_output - y_target) # 這里損失函數是單個樣本點的損失,因為一次訓練只隨機選擇一個樣本點
# 6 初始化變量
init = tf.initialize_all_variables()
sess.run(init)
# 7 聲明變量的優化器。設置學習率。
my_opt = tf.train.GradientDescentOptimizer(learning_rate=0.02)
train_step = my_opt.minimize(loss)
# 8 訓練算法
for i in range(100):
    rand_index = np.random.choice(100) # 隨機選擇一個樣本點
    rand_x = [x_vals[rand_index]]
    rand_y = [y_vals[rand_index]]
    sess.run(train_step, feed_dict={x_data:rand_x, y_target:rand_y})
    if (i+1)%25 == 0:
        print('Step #' + str(i) + ' A = ' + str(sess.run(A)))
        print('Loss = ' + str(sess.run(loss, feed_dict={x_data:rand_x, y_target:rand_y})))
# 9 關閉會話
sess.close()
執行結果: 

簡單的分類例子

這是一個簡單的二分類問題。100個樣本點,其中50個由N(-1,1)生成,標簽為0,50個由N(3,1)生成,標簽為1。用sigmoid函數實現二分類問題。模型設置為sigmoid(A+x)。兩類數據中心點的中點是1,可見A應該在-1附近。

代碼實現:

import numpy as np
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
# 2 創建會話
sess = tf.Session()
# 3 生成數據,創建變量和占位符
x_vals = np.concatenate((np.random.normal(-1, 1, 50),
                         np.random.normal(3, 1, 50)))
y_vals = np.concatenate((np.repeat(0., 50),
                         np.repeat(1., 50)))
x_data = tf.placeholder(shape=[1], dtype=tf.float32)
y_target = tf.placeholder(shape=[1], dtype=tf.float32)
A = tf.Variable(tf.random_normal(mean=10, shape=[1]))

# 模型。y_pre = sigmoid(A+x)。
# 這里不必封裝sigmoid函數,因為損失函數中會實現此功能
my_output = tf.add(x_data, A)

# 增加一個批量維度,使其滿足損失函數的輸入要求。
my_output_expanded = tf.expand_dims(my_output, 0)
y_target_expanded = tf.expand_dims(y_target, 0)

# 初始化變量A
init = tf.initialize_all_variables()
sess.run(init)

# 損失函數
xentropy = tf.nn.sigmoid_cross_entropy_with_logits(logits=my_output_expanded,
                                                   labels=y_target_expanded)

# 優化器
my_opt = tf.train.GradientDescentOptimizer(learning_rate=0.05)
train_step = my_opt.minimize(xentropy)

# 迭代訓練
for i in range(1400):
    rand_index = np.random.choice(100)
    rand_x = [x_vals[rand_index]]
    rand_y = [y_vals[rand_index]]

    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})
    if (i + 1) % 200 == 0:
        print('Step #' + str(i + 1) + ' A= ' + str(sess.run(A)))
        print('Loss = ' + str(sess.run(xentropy, feed_dict={x_data: rand_x,
                                                            y_target: rand_y})))
# 關閉會話
sess.close()

 

# 輸出結果如下: 

算法步驟總結

  1. 生成數據或加載數據
    2.設置占位符和變量,初始化變量。
    3.創建損失函數。
    4.定義優化器算法。
    5.通過隨機樣本反復迭代,更新變量。

Tensorflow 實現隨機訓練和批量訓練

上面的反向傳播算法的例子,一次操作一個數據點,可能會導致比較古怪的學習過程。本節介紹隨機批量訓練。

代碼實現:

import numpy as np
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
# 2 創建會話
sess = tf.Session()

# 1 聲明批量大小。即一次傳入多少數據量
batch_size = 20
# 2 生成數據,設置占位符和變量
x_vals = np.random.normal(1, 0.1, 100)
y_vals = np.repeat(10., 100)
x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)  # None會自動匹配batch大小
y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)
A = tf.Variable(tf.random_normal(shape=[1, 1]))
# 3 模型
my_output = tf.matmul(x_data, A)
# 4 損失函數
loss = tf.reduce_mean(tf.square(my_output - y_target))
# 5 聲明優化器
my_opt = tf.train.GradientDescentOptimizer(0.02)
train_step = my_opt.minimize(loss)
# 初始化變量A
init = tf.initialize_all_variables()
sess.run(init)
# 6 迭代訓練
loss_batch = []
for i in range(100):
    rand_index = np.random.choice(100, size=batch_size)
    rand_x = np.transpose([x_vals[rand_index]])
    rand_y = np.transpose([y_vals[rand_index]])

    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})
    if (i + 1) % 5 == 0:
        print('Step # ' + str(i + 1) + ' A = ' + str(sess.run(A)))
        temp_loss = sess.run(loss, feed_dict={x_data: rand_x, y_target: rand_y})
        print('Loss = ' + str(temp_loss))
        loss_batch.append(temp_loss)
# 關閉會話
sess.close()

執行結果:

C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=65029
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects'])
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.12.0
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
runfile('C:/app/PycharmProjects/ArtificialIntelligence/classification.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\compat\v2_compat.py:96: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
2020-06-16 17:30:17.580660: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2020-06-16 17:30:17.598160: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x2155425f5d0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-06-16 17:30:17.600376: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\util\tf_should_use.py:235: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
Step # 5 A = [[3.53069]]
Loss = 40.98304
Step # 10 A = [[4.7239804]]
Loss = 26.532007
Step # 15 A = [[5.6892867]]
Loss = 18.928028
Step # 20 A = [[6.4685965]]
Loss = 13.320193
Step # 25 A = [[7.113227]]
Loss = 8.6985
Step # 30 A = [[7.6286054]]
Loss = 6.2374206
Step # 35 A = [[8.06992]]
Loss = 4.8240232
Step # 40 A = [[8.409104]]
Loss = 3.530541
Step # 45 A = [[8.694167]]
Loss = 3.467298
Step # 50 A = [[8.906876]]
Loss = 2.0321229
Step # 55 A = [[9.090424]]
Loss = 1.8405815
Step # 60 A = [[9.211552]]
Loss = 1.0624132
Step # 65 A = [[9.347725]]
Loss = 0.8500676
Step # 70 A = [[9.444745]]
Loss = 0.53573257
Step # 75 A = [[9.507953]]
Loss = 0.43884102
Step # 80 A = [[9.555529]]
Loss = 1.6697924
Step # 85 A = [[9.639705]]
Loss = 0.6063883
Step # 90 A = [[9.675548]]
Loss = 0.71441334
Step # 95 A = [[9.686658]]
Loss = 0.3382503
Step # 100 A = [[9.711099]]
Loss = 1.0318668

 

本段實現的仍是那個線性回歸的例子。唯一的不同是,上面每次優化過程計算的損失函數只用到一個隨機樣本點。而本處用到batch_size=20個隨機樣本點,損失函數是這20個隨機樣本點損失函數的平均值。


TensorFlow實現創建分類器

這里用到iris鳶尾花數據集。iris有三種花,這里只預測是否是山鳶尾。

代碼實現:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
# 2 創建會話
sess = tf.Session()

# 2 導入數據集
iris = datasets.load_iris()
binary_target = np.array([1. if x==0 else 0. for x in iris.target]) # 山鳶尾標簽設置為0
iris_2d = np.array([[x[2], x[3]] for x in iris.data])

# 3 聲明批大小、占位符和變量
batch_size = 20
x1_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)
x2_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)
y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)
A = tf.Variable(tf.random_normal(shape=[1,1]))
b = tf.Variable(tf.random_normal(shape=[1,1]))

# 4 模型:x1 - Ax2 -b
my_mult = tf.matmul(x2_data, A)
my_add = tf.add(my_mult, b)
my_output = tf.subtract(x1_data, my_add)

# 5 Loss函數
xentropy = tf.nn.sigmoid_cross_entropy_with_logits(labels = y_target, logits = my_output)

# 6 優化器
my_opt = tf.train.GradientDescentOptimizer(0.05)
train_step = my_opt.minimize(xentropy)

# 7 初始化變量
init = tf.initialize_all_variables()
sess.run(init)

# 8 訓練模型
for i in range(1000):
    rand_index = np.random.choice(len(iris_2d), size=batch_size)
    rand_x = iris_2d[rand_index]
    rand_x1 = np.array([[x[0]] for x in rand_x])
    rand_x2 = np.array([[x[1]] for x in rand_x])
    rand_y = np.array([[y] for y in binary_target[rand_index]])
    sess.run(train_step, feed_dict={x1_data:rand_x1, x2_data:rand_x2, y_target:rand_y})
    if (i+1)%200 == 0:
        print('Step #' + str(i+1) +' A= '+ str(sess.run(A)) + ',b='+str(sess.run(b)))
sess.close()
輸出如下:
C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=65328
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects'])
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.12.0
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
runfile('C:/app/PycharmProjects/ArtificialIntelligence/classification.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\compat\v2_compat.py:96: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
2020-06-16 17:33:16.698842: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2020-06-16 17:33:16.768906: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x27babe820b0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-06-16 17:33:16.771150: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\util\tf_should_use.py:235: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
Step #200 A= [[8.649565]],b=[[-3.4785087]]
Step #400 A= [[10.205365]],b=[[-4.7120676]]
Step #600 A= [[11.15341]],b=[[-5.4508886]]
Step #800 A= [[11.841216]],b=[[-6.0160065]]
Step #1000 A= [[12.429868]],b=[[-6.354217]]

Tensorflow實現模型評估

回歸

這里用MSE評估

代碼實現:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
# 2 創建會話
sess = tf.Session()
x_vals = np.random.normal(1., 0.1, 100)
y_vals = np.repeat(10., 100)
x_data = tf.placeholder(shape=[None, 1], dtype = tf.float32)
y_target = tf.placeholder(shape=[None, 1], dtype = tf.float32)
batch_size = 25
train_indices = np.random.choice(len(x_vals),
                                 round(len(x_vals)*0.8), replace=False) # False表示不放回
test_indices = np.array(list(set(range(len(x_vals))) - set(train_indices)))
x_vals_train = x_vals[train_indices]
x_vals_test = x_vals[test_indices]
y_vals_train = y_vals[train_indices]
y_vals_test = y_vals[test_indices]
A = tf.Variable(tf.random_normal(shape=[1,1]))

#2. 聲明算法模型、損失函數和優化器
my_output = tf.matmul(x_data, A)
loss = tf.reduce_mean(tf.square(my_output - y_target))
init = tf.initialize_all_variables()
sess.run(init)
my_opt = tf.train.GradientDescentOptimizer(0.02)
train_step = my_opt.minimize(loss)
#3. 訓練代碼
for i in range(100):
    rand_index = np.random.choice(len(x_vals_train), size=batch_size)
    rand_x = np.transpose([x_vals_train[rand_index]])
    rand_y = np.transpose([y_vals_train[rand_index]])
    sess.run(train_step, feed_dict={x_data:rand_x, y_target:rand_y})
    if (i+1)%25 == 0:
        print('Step #'+ str(i+1) + ' A= ' + str(sess.run(A)))
        print('Loss = ' + str(sess.run(loss, feed_dict={x_data:rand_x, y_target:rand_y})))
#4. 評估訓練模型
mse_test = sess.run(loss, feed_dict = {x_data:np.transpose([x_vals_test]),
                                       y_target:np.transpose([y_vals_test])})
mse_train = sess.run(loss, feed_dict = {x_data:np.transpose([x_vals_train]),
                                        y_target:np.transpose([y_vals_train])})
print('MSE on test:' + str(np.round(mse_test, 2 )))
print('MSE on train:' + str(np.round(mse_train, 2)))
sess.close()

執行結果:

C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=49353
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects'])
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.12.0
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
runfile('C:/app/PycharmProjects/ArtificialIntelligence/classification.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\compat\v2_compat.py:96: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
2020-06-16 17:36:56.899056: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2020-06-16 17:36:56.914877: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x2727286ecb0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-06-16 17:36:56.916799: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\util\tf_should_use.py:235: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
Step #25 A= [[6.9728527]]
Loss = 10.56796
Step #50 A= [[8.8468]]
Loss = 2.3120868
Step #75 A= [[9.482852]]
Loss = 1.2149283
Step #100 A= [[9.686576]]
Loss = 0.6710054
MSE on test:0.5
MSE on train:0.93

分類

代碼實現:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
# 創建計算圖、加載數據、創建占位符和變量
sess = tf.Session()
batch_size = 25
x_vals = np.concatenate((np.random.normal(-1, 1, 50), np.random.normal(3, 1, 50)))
y_vals = np.concatenate((np.repeat(0., 50), np.repeat(1., 50)))
x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)
y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)

# 分割數據集為訓練集和測試集
train_indices = np.random.choice(len(x_vals),
                                 round(len(x_vals) * 0.8), replace=False)  # False表示不放回
test_indices = np.array(list(set(range(len(x_vals))) - set(train_indices)))
x_vals_train = x_vals[train_indices]
x_vals_test = x_vals[test_indices]
y_vals_train = y_vals[train_indices]
y_vals_test = y_vals[test_indices]
A = tf.Variable(tf.random_normal(mean=10, shape=[1, 1]))

# 設置模型
my_output = tf.add(x_data, A)

# 初始化變量
init = tf.initialize_all_variables()
sess.run(init)

# 損失函數和優化器
xentropy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=my_output, labels=y_target))
my_opt = tf.train.GradientDescentOptimizer(0.05)
train_step = my_opt.minimize(xentropy)

# 訓練模型
for i in range(1800):
    rand_index = np.random.choice(len(x_vals_train), size=batch_size)
    rand_x = np.transpose([x_vals_train[rand_index]])
    rand_y = np.transpose([y_vals_train[rand_index]])
    sess.run(train_step, feed_dict={x_data: rand_x,
                                    y_target: rand_y})
    if (i + 1) % 200 == 0:
        print('Step #' + str(i + 1) + ' A= ' + str(sess.run(A)))
        print('Loss = ' + str(sess.run(xentropy, feed_dict={x_data: rand_x, y_target: rand_y})))

# 模型評估
y_prediction = tf.round(tf.nn.sigmoid(tf.add(x_data, A)))
correct_prediction = tf.squeeze(tf.equal(y_prediction, y_target))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
acc_value_test = sess.run(accuracy, feed_dict={x_data: np.transpose([x_vals_test]),
                                               y_target: np.transpose([y_vals_test])})
acc_value_train = sess.run(accuracy, feed_dict={x_data: np.transpose([x_vals_train]),
                                                y_target: np.transpose([y_vals_train])})
print('Accuracy on train set:' + str(acc_value_train))
print('Accuracy on test set:' + str(acc_value_test))

# 畫圖
A_result = -sess.run(A)
bins = np.linspace(-5, 5, 50)
plt.hist(x_vals[0:50], bins, alpha=0.5, label='N(-1,1)', color='blue')
plt.hist(x_vals[50:100], bins[0:50], alpha=0.5, label='N(2,1)', color='red')
plt.axvline(A_result, color='k', ls='--', linewidth=1, label='A=' + str(np.round(A_result, 2)))
plt.legend(loc='upper right')
plt.show()
sess.close()

執行結果:

C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=49580
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects'])
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.12.0
Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
runfile('C:/app/PycharmProjects/ArtificialIntelligence/classification.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\compat\v2_compat.py:96: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
2020-06-16 17:39:03.348982: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2020-06-16 17:39:03.367638: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x1e273df9630 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-06-16 17:39:03.369480: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
WARNING:tensorflow:From C:\Anaconda3\lib\site-packages\tensorflow\python\util\tf_should_use.py:235: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
Step #200 A= [[4.155767]]
Loss = 2.250753
Step #400 A= [[0.26491255]]
Loss = 0.3568238
Step #600 A= [[-0.84668785]]
Loss = 0.19771285
Step #800 A= [[-1.1465402]]
Loss = 0.180008
Step #1000 A= [[-1.2240477]]
Loss = 0.19029576
Step #1200 A= [[-1.237976]]
Loss = 0.18425061
Step #1400 A= [[-1.2689428]]
Loss = 0.22775798
Step #1600 A= [[-1.2820176]]
Loss = 0.23119526
Step #1800 A= [[-1.2433089]]
Loss = 0.16477217
Accuracy on train set:0.95
Accuracy on test set:0.95

 

 

 

 

import numpy as np
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 使用靜態圖模式運行以下代碼
assert tf.__version__.startswith('2.')
sess = tf.Session()
x_vals = np.array([1., 3., 5., 7., 9.])
x_data = tf.placeholder(dtype=tf.float32)
m_const = tf.constant(3.)
my_product = tf.multiply(x_data, m_const)
for x_val in x_vals:
print(sess.run(my_product, feed_dict={x_data:x_val}))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM