2020機器學習感知機(1)

machine_learning.jpg

今天我們通過分享內(nèi)容讓大家了解一下機器是如何通過學習來識別物體,以及這些物體在機器是怎么看這些物體。今天用單層感知機來模擬機器視圖,這里選擇數(shù)據(jù)集中為 10 衣帽圖片。這里通過線性方程加上分類激活函數(shù) softmax 完成圖片分類任務。這個流程雖然簡單,但是通過這個過程我們來了解機器是如何通過梯度下降優(yōu)化,以減少損失函數(shù)為目標不斷更新參數(shù)來找到一個適合模型(函數(shù));

import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
from sklearn.metrics import confusion_matrix

from tensorflow import keras

%matplotlib inline

介紹 fashion_mnist 數(shù)據(jù)集

我們這里使用 fashion_mnist 數(shù)據(jù)集,一共 70000 張圖片其中 60000 張為訓練集 10000 張為測試集。圖片大小 28 * 28 大小圖片

fashion_mnist = keras.datasets.fashion_mnist
(X_train,y_train),(X_test,y_test) = fashion_mnist.load_data()
print(X_train.shape)
print(X_test.shape)
(60000, 28, 28)
(10000, 28, 28)
img_size = 28
img_size_flat = img_size * img_size
img_shape = (img_size,img_size)
num_classes = 10
print(y_train.shape)
print(y_train[0:5])
(60000,)
[9 0 0 3 0]
def plot_images(images,cls,cls_pred=None):
    cls_names = ['T-shirt','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankle boot']
    fig, axes = plt.subplots(3, 3)
    fig.subplots_adjust(hspace=0.3, wspace=0.3)
    for i, ax in enumerate(axes.flat):
        ax.imshow(imgs[i].reshape(img_shape), cmap='binary')
        if cls_pred is None:
            xlabel = "True: {0}".format(cls_names[cls_true[i]])
        else:
            xlabel = "True: {0}, Pred: {1}".format(cls_true[i],cls_pred[i])
        ax.set_xlabel(xlabel)
        ax.set_xticks([])
        ax.set_yticks([])
    plt.show()

可視化數(shù)據(jù)集

通過上面函數(shù)讀取圖片,將數(shù)據(jù)集中圖片顯示出來,這樣便于大家更加直觀觀察數(shù)據(jù)集圖,這里有 10 物體,標簽標示物體是什么物體

imgs = X_test[0:9]
cls_true = y_test[0:9]

plot_images(imgs,cls_true)
output_9_0.png

因為我們數(shù)據(jù)集 y 值為[0,3,5,...,6],需要轉換后生成one-hot 編碼來參與運算。

# print(a)
# a_one_hot_encode = tf.one_hot(a,num_classes,axis=0)
# print(a_one_hot_encode.shape)
from sklearn.preprocessing import OneHotEncoder
# print(y_test.shape)
# print(y_test)
y_train_cls = y_train
y_test_cls = y_test

y_train = OneHotEncoder(sparse=False).fit_transform(y_train_cls.reshape(-1,1))
y_test = OneHotEncoder(sparse=False).fit_transform(y_test_cls.reshape(-1,1))
print(y_train_cls.shape)
print(y_test_cls.shape)
# help(OneHotEncoder)
X_train = X_train.reshape(-1,784)
X_test = X_test.reshape(-1,784)

print(X_train.shape)
print(y_train.shape)
print(y_train_cls.shape)

print(y_test.shape)
print(y_test_cls.shape)
(60000,)
(10000,)
(60000, 784)
(60000, 10)
(60000,)
(10000, 10)
(10000,)
# 定義 x 占位符作為圖片輸入,輸入 x 形狀[None,784]
x = tf.placeholder(tf.float32, [None, img_size_flat],name="x")
# 定義 y_true 為實際值,這里數(shù)據(jù)集中真實值形狀[[0,0,0,1,...,0]]
# 真實值形式為 [None,10]
y_true = tf.placeholder(tf.float32, [None, num_classes],name="y_true")
# 標簽這里是由表示類別數(shù)據(jù)[None] 例如 [1,0,1,9,...,3]
y_true_cls = tf.placeholder(tf.int64, [None],name="y_true_cls")
# 權重 y(None,10) = x (None,784) (784,10) + [10]
weights = tf.Variable(tf.zeros([img_size_flat, num_classes]))
biases = tf.Variable(tf.zeros([num_classes]))
# $$y = x * w + b$$
logits = tf.matmul(x, weights) + biases
y_pred = tf.nn.softmax(logits)
y_pred_cls = tf.argmax(y_pred, axis=1)
# 損失函數(shù)使用交叉熵來計算損失函數(shù)
cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits,
                                                           labels=y_true)
cost = tf.reduce_mean(cross_entropy)
# 定義梯度下降,學習率給 0.5 
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.5).minimize(cost)
# 這里推測 softmax 計算出估計概率分布值轉為一個值 進行對比 
correct_prediction = tf.equal(y_pred_cls, y_true_cls)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
session = tf.Session()
# 初始化變量
session.run(tf.global_variables_initializer())
batch_size = 100
num_train = len(x_train)
batch_size = 32
idx = np.random.randint(low=0, high=num_train, size=batch_size)
print(idx)
def random_batch(batch_size=32):
    idx = np.random.randint(low=0, high=num_train, size=batch_size)
    x_batch = X_train[idx]
    y_batch = y_train[idx]
    y_batch_cls = y_train_cls[idx]

    return x_batch, y_batch, y_batch_cls
[32525 10192  5890  2494 36637 42087  4928 52251 22363 50428 22872 45213
 26151  4918 18285  8225 20240 24740 48514 17688  8004 51821 30665 36699
 33706 40797 39813 11795 36770 56473  9096 46205]

優(yōu)化

# 優(yōu)化 num_iterations 是迭代次數(shù)
def optimize(num_iterations):
    for i in range(num_iterations):
        # 獲取訓練集的一定的樣本數(shù),每次取出一定數(shù)量樣本視為一個批次樣本
        # x_batch
        x_batch, y_true_batch, _ = random_batch(batch_size=batch_size)
        
        # 在 tensorflow 中使用 feed_dict 將輸入數(shù)據(jù)傳入到圖
        #         
        # 這里沒有將 y_true_cls 傳入因為這些數(shù)據(jù)并不參與訓練.
        feed_dict_train = {x: x_batch,
                           y_true: y_true_batch}

        session.run(optimizer, feed_dict=feed_dict_train)
feed_dict_test = {x: X_test,y_true: y_test,y_true_cls: y_test_cls}

輸出精度

def print_accuracy():
    # 計算 accuracy.
    acc = session.run(accuracy, feed_dict=feed_dict_test)
    
    # 輸出 accuracy.
    print("Accuracy on test-set: {0:.1%}".format(acc))

輸出混淆矩陣

def print_confusion_matrix():
    cls_true = y_test_cls
    
    cls_pred = session.run(y_pred_cls, feed_dict=feed_dict_test)

    cm = confusion_matrix(y_true=cls_true,
                          y_pred=cls_pred)

    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)

    plt.tight_layout()
    plt.colorbar()
    tick_marks = np.arange(num_classes)
    plt.xticks(tick_marks, range(num_classes))
    plt.yticks(tick_marks, range(num_classes))
    plt.xlabel('Predicted')
    plt.ylabel('True')
    
    plt.show()

輸出錯誤


def plot_example_errors():

    correct, cls_pred = session.run([correct_prediction, y_pred_cls],
                                    feed_dict=feed_dict_test)

    incorrect = (correct == False)
    
    images = X_test[incorrect]
    
    cls_pred = cls_pred[incorrect]

    cls_true = y_test_cls[incorrect]
    
    plot_images(images=images[0:9],
                cls=cls_true[0:9],
                cls_pred=cls_pred[0:9])

通過顯示權重,我們可以了解到機器到底學到什么,機器是怎么認識


def plot_weights():
    
    # 獲取權重 w 的值
    #  784 * 10 矩陣,10 維度對應 10 個類別,   
    w = session.run(weights)
    
    # 要做這件事,我們需要先找到權重的最小值和最大值。
    w_min = np.min(w)
    w_max = np.max(w)

    fig, axes = plt.subplots(3, 4)
    fig.subplots_adjust(hspace=0.3, wspace=0.3)

    for i, ax in enumerate(axes.flat):
        # 只顯示 10 權重圖
        if i<10:
            image = w[:, i].reshape(img_shape)

            ax.set_xlabel("Weights: {0}".format(i))

            ax.imshow(image, vmin=w_min, vmax=w_max, cmap='seismic')

        ax.set_xticks([])
        ax.set_yticks([])
        
    # Ensure the plot is shown correctly with multiple plots
    # in a single Notebook cell.
    plt.show()
print_accuracy()
Accuracy on test-set: 10.0%
plot_example_errors()
output_40_0.png
optimize(num_iterations=1)
print_accuracy()
Accuracy on test-set: 19.8%
plot_example_errors()
output_43_0.png
plot_weights()
output_44_0.png
在張圖,機器把鞋學的不錯,機器可以清晰認出coat 和 鞋子
optimize(num_iterations=9)
print_accuracy()
Accuracy on test-set: 54.5%
plot_example_errors()
output_48_0.png
plot_weights()
output_49_0.png
optimize(num_iterations=50)

訓練到 50 發(fā)現(xiàn)機器表現(xiàn)還不錯 76.8 別忘了這里只有一層神經(jīng)網(wǎng)的,可以認為感知機。

print_accuracy()
Accuracy on test-set: 76.8%
plot_example_errors()
output_53_0.png
plot_weights()
output_54_0.png

過擬合

當訓練次數(shù)增加學習成績反而下降

optimize(num_iterations=990)
print_accuracy()
Accuracy on test-set: 68.3%
plot_example_errors()
output_58_0.png
plot_weights()
output_59_0.png

最后希望大家關注我們微信公眾號


wechat.jpeg
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容