TensorFlow-2.x-05-MLP的從0開始

         本章主要利用多層感知機實現圖像分類,具體將構造參數、模型結構、準確率等等。

1、數據集讀取及歸一化

(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train, x_test = tf.cast(x_train / 255.0,tf.float32), tf.cast(x_test / 255.0,tf.float32)
print(x_train.shape,y_train.shape)
# 將訓練數據的特徵和標籤組合
batch_size=256
train_dataset = tfdata.Dataset.from_tensor_slices((x_train, y_train)).shuffle(x_train.shape[0])
test_dataset = tfdata.Dataset.from_tensor_slices((x_test, y_test))
train_iter=train_dataset.batch(batch_size)
test_iter=test_dataset.batch(batch_size)

2、定義模型參數

num_inputs=28*28
num_hidden=128
num_outputs=10

W1 = tf.Variable(tf.random.normal(shape=(num_inputs, num_hidden),mean=0, stddev=0.01, dtype=tf.float32))
b1 = tf.Variable(tf.zeros(num_hidden, dtype=tf.float32))
W2 = tf.Variable(tf.random.normal(shape=(num_hidden, num_outputs),mean=0, stddev=0.01, dtype=tf.float32))
b2 = tf.Variable(tf.random.normal([num_outputs], stddev=0.1))

3、定義relu激活函數

def relu(x):
    return tf.math.maximum(x, 0)

4、定義模型

根據f(x)=Xw+b進行計算:

def net(x):
    x = tf.reshape(x, [-1, num_inputs])
    result1 = relu(tf.matmul(x, W1) + b1)
    return tf.math.softmax(tf.matmul(result1, W2) + b2)

5、定義損失函數

#爲了有更好的數值穩定性,使用API
def loss(y_hat,y_true):
    return tf.losses.sparse_categorical_crossentropy(y_true,y_hat)

6、定義準確率

def accuracy(y_hat, y):
    return np.mean((tf.cast(tf.argmax(y_hat, axis=1), tf.int32) == tf.cast(y, tf.int32)))

7、定義驗證集準確率

def evaluate_accuracy(test_iter):
    acc_sum, n = 0.0, 0
    for X, y in test_iter:
        n += 1
        y = tf.cast(y, dtype=tf.int32)
        output = net(X)
        acc_sum += accuracy(output, y)
    return acc_sum / n

8、定義SGD優化器

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

9、訓練

def train(num_epochs,lr,params):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            n+=1   #一個epoch取多少次
            with tf.GradientTape() as t:
                t.watch(params)
                l = tf.reduce_mean(loss(net(X), y))
            grads = t.gradient(l, params)  # 通過調用反向函數t.gradients計算小批量隨機梯度,並調用優化算法sgd迭代模型參數
            sgd(params, lr, batch_size, grads)
            train_acc_sum+=accuracy(net(X),y)
            train_l_sum+=l.numpy()
        test_acc=evaluate_accuracy(test_iter)
        print("epoch %d, train loss:%.6f, train acc:%.5f, test acc:%.5f"%(epoch,train_l_sum/n,train_acc_sum/n,test_acc))

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

10、預測

def show_image(image): # 顯示圖像
    n=image.shape[0]
    _,figs=plt.subplots(1,n,figsize=(15,15))
    for i in range(n):
        figs[i].imshow(image[i].reshape((28,28)))
    plt.show()
def get_fashion_mnist_labels(labels):# 顯示圖像標籤
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]

def predict(image_10):
    label_10 = y_test[:10] # 拿到前10個數據
    show_image(image_10)
    print("真實樣本標籤:", label_10)
    print("真實數字標籤對應的服飾名:", get_fashion_mnist_labels(label_10))

    image_10 = tf.cast(image_10/255.0,tf.float32)
    predict_label = tf.argmax(net(image_10),1).numpy()
    print("預測樣本標籤:", predict_label.astype("int8"))
    print("預測數字標籤對應的服飾名:", get_fashion_mnist_labels(predict_label))

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

附上所有源碼:

import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
import matplotlib.pyplot as plt
import numpy as np
from tensorflow import data as tfdata

# 1、數據集讀取及歸一化
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
image_10=x_test[:10]
x_train, x_test = tf.cast(x_train / 255.0,tf.float32), tf.cast(x_test / 255.0,tf.float32)
print(x_train.shape, y_train.shape)
# 將訓練數據的特徵和標籤組合
batch_size = 256
train_dataset = tfdata.Dataset.from_tensor_slices((x_train, y_train)).shuffle(x_train.shape[0])
test_dataset = tfdata.Dataset.from_tensor_slices((x_test, y_test))
train_iter = train_dataset.batch(batch_size)
test_iter = test_dataset.batch(batch_size)

# 2、定義模型參數
num_inputs = 28 * 28  # 輸入神經元個數
num_hidden = 128  # 隱藏層個數
num_outputs = 10  # 分類數

W1 = tf.Variable(tf.random.normal(shape=(num_inputs, num_hidden), mean=0, stddev=0.01, dtype=tf.float32))
b1 = tf.Variable(tf.zeros(num_hidden, dtype=tf.float32))
W2 = tf.Variable(tf.random.normal(shape=(num_hidden, num_outputs), mean=0, stddev=0.01, dtype=tf.float32))
b2 = tf.Variable(tf.random.normal([num_outputs], stddev=0.1))


# 3、定義relu激活函數
def relu(x):
    return tf.math.maximum(x,0)


# 4、定義模型
def net(X):
    x = tf.reshape(X, shape=[-1, num_inputs])
    h = relu(tf.matmul(x, W1) + b1)
    return tf.math.softmax(tf.matmul(h, W2) + b2)


# 5、定義損失函數
# 爲了有更好的數值穩定性,使用API
def loss(y_hat, y_true):
    return tf.losses.sparse_categorical_crossentropy(y_true, y_hat)


# 6、計算準確率
def accuracy(y_hat, y):
    return np.mean((tf.cast(tf.argmax(y_hat, axis=1), tf.int32) == tf.cast(y, tf.int32)))

# 7、計算測試集準確率
def evaluate_accuracy(test_iter):
    acc_sum, n = 0.0, 0
    for X, y in test_iter:
        n += 1
        y = tf.cast(y, dtype=tf.int32)
        output = net(X)
        acc_sum += accuracy(output, y)
    return acc_sum / n


# 8、SGD優化器
def sgd(params, lr, batch_size, grads):
    for i, param in enumerate(params):
        param.assign_sub(lr * grads[i] / batch_size)

#9、訓練
def train(num_epochs,lr,params):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            n+=1   #一個epoch取多少次
            with tf.GradientTape() as t:
                t.watch(params)
                l = tf.reduce_mean(loss(net(X), y))
            grads = t.gradient(l, params)  # 通過調用反向函數t.gradients計算小批量隨機梯度,並調用優化算法sgd迭代模型參數
            sgd(params, lr, batch_size, grads)
            train_acc_sum+=accuracy(net(X),y)
            train_l_sum+=l.numpy()
        test_acc=evaluate_accuracy(test_iter)
        print("epoch %d, train loss:%.6f, train acc:%.5f, test acc:%.5f"%(epoch,train_l_sum/n,train_acc_sum/n,test_acc))
# 10、預測
def show_image(image): # 顯示圖像
    n=image.shape[0]
    _,figs=plt.subplots(1,n,figsize=(15,15))
    for i in range(n):
        figs[i].imshow(image[i].reshape((28,28)))
    plt.show()
def get_fashion_mnist_labels(labels):# 顯示圖像標籤
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]

def predict(image_10):
    label_10 = y_test[:10] # 拿到前10個數據
    show_image(image_10)
    print("真實樣本標籤:", label_10)
    print("真實數字標籤對應的服飾名:", get_fashion_mnist_labels(label_10))

    image_10 = tf.cast(image_10/255.0,tf.float32)
    predict_label = tf.argmax(net(image_10),1).numpy()
    print("預測樣本標籤:", predict_label.astype("int8"))
    print("預測數字標籤對應的服飾名:", get_fashion_mnist_labels(predict_label))
if __name__=="__main__":
    train(50,0.3,params=[W1,b1,W2,b2])
    predict(image_10)# 預測
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章