TensorFlow识别MNIST

Catalogue
  1. TensorFlow识别 MNIST
    1. 1.1 import
    2. 1.2 数据下载
    3. 1.3 数据查看
    4. 1.4 数据预处理
    5. 1.5 创建模型并训练
    6. 1.6 评估模型
  2. 原理
    1. 训练
      1. 1.2.1 Softmax
    2. 1.3 使用Softmax对MNIST分类
      1. 1.3.1 计算Logit
      2. 1.3.2 使用Softmax函数
      3. 1.3.3 Softmax回归在TensorFlow中的实现

本文主要是 通过Softmax对MNIST进行分类,通过一个简单的前馈神经网络模型实现,以此
(1).熟悉 算法工程 工作内容都有那些.
(2).熟悉TensorFlow框架的原理和使用
(3).熟悉Softmax和简单的网络模型
(4).熟悉基于python的TensorFlow框架工具

TensorFlow识别 MNIST

具体实现见:kaggle-digit-rec-tensorflow:ipynb

TensorFlow Version: 2.11.0

书中 使用的是 python2.7、tensorflow 1.14.0; 使用方式上有些差异. (可以关注下差异)

1.1 import

引入依赖

1
2
3
4
5
6
7
8
9
10
11
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

from scipy.io import loadmat
import matplotlib.pyplot as plt # 用于图像相关

import tensorflow as tf

from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential
from tensorflow.keras.utils import to_categorical

1.2 数据下载

tf2.x 也可以通过 下载数据.

1
2
3
4
5
6
# 引入依赖
# 原始数据是 784 * 70000 的二维数组(mnist['data']). 及70000条数据, 每条是 784维 的灰度图像.
mnist = loadmat("/kaggle/input/mnist-original/mnist-original.mat")

# label 是 1*70000的二维数组。
mnist['label']

1.3 数据查看

1
2
3
4
5
6
7
# 查看数据形状
images = mnist['data']
print(images.shape)
images

# 查看其中某一条图像
plt.imshow(images[20000].reshape(28,28))

1.4 数据预处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
print(images.shape)
mnistImages = images.T
print(mnistImages.shape)
# 归一化图像数据
mnistImages = mnistImages / 255.0
#images[60000]

labels = mnist['label'].squeeze()
print(labels.shape)

# 查看数据
plt.imshow(mnistImages[20100].reshape(28,28))
print(labels[20100])

# 将标签转换为独热编码(为什么)
model_labels = tf.keras.utils.to_categorical(labels, num_classes=10)
print(model_labels.shape)
model_labels[30000]

创建TensorFlow数据集

1
2
3
4
5
6
7
8
9
10
11
# 创建TensorFlow数据集
train_images = mnistImages[:60000]
train_labels = model_labels[:60000]
test_images = mnistImages[60000:]
test_labels = model_labels[60000:]

train_dataset = tf.data.Dataset.from_tensor_slices((train_images, train_labels)).batch(32)
test_dataset = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(32)

print(train_images.shape)
print(train_labels.shape)

1.5 创建模型并训练

创建一个简单的序贯模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建一个简单的序列模型
model = Sequential([
#Flatten(input_shape=(784,)), # 将28x28图像展平成784维向量
Dense(128, activation='relu', input_shape=(784,)), # 第一个隐藏层,具有128个神经元和ReLU激活函数
Dense(64, activation='relu'), # 添加一个具有128个神经元的隐藏层,使用ReLU激活函数
Dense(10, activation='softmax') # 添加一个输出层,具有10个神经元(对应10个类别),使用softmax激活函数
])

# 编译模型
model.compile(optimizer='adam',
loss='categorical_crossentropy', # 使用分类交叉熵作为损失函数
metrics=['accuracy']) # 跟踪训练和测试的准确率

# 打印模型概况
model.summary()

# 训练模型
model.fit(train_dataset, epochs=5, batch_size=32)

1.6 评估模型

1
2
3
# 评估模型
loss, accuracy = model.evaluate(test_dataset)
print(f"Test accuracy: {accuracy}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
data_index = 10108
single_data = mnistImages[data_index]
print(single_data.shape)
print(labels[data_index])
# 输入需要 一个行向量, 和训练数据类似.
prediction = model.predict(single_data.reshape(1,784))
# 打印 - 非科学计数法
np.set_printoptions(suppress=True)
result = np.array(prediction[0])
print(result)

# 获取预测结果中概率最高的类别索引
predicted_digit = np.argmax(prediction[0])
# 打印预测的数字
print(f"Predicted digit: {predicted_digit}")
plt.imshow(mnistImages[10108].reshape(28,28))

原理

训练

基础知识:Softmax回归(线性的多元分类模型).

Softmax目的:将打分结果(向量) 转化为 0-1区间的概率.

假设 x是单个样本的特征, W、b 是 Softmax模型的参数。

  • 对样本的理解: 这里 一条数据就是 一个样本,包含了一个特征向量。 (业务中: 也可以用id表示一个样本 ? )

在MNIST中,x就代表输入的图片, 它是一个 784维度的向量,而W是一个矩阵。
它的形状是 (784,10) , b是一个10维的向量。10代表的是类别数。

1.2.1 Softmax

Softmax回归是一个线性的多类分类模型。 实际上是直接从 Logiistic回归模型转化而来的。
区别在于Logistic回归模型为两类分类模型,而Softmax模型为多分类模型.

1
2
3
4
5
6
7
什么是回归?
回归是统计学和机器学习中的一种重要的分析方法,用于建立变量之间的关系模型,通常用于预测连续型变量的数值...
见:机器学习基本概念和算法

什么是逻辑回归?
(重要)在二分类问题中,采用逻辑函数 将线性组合的输出 转换为0-1之间的概率值,用于描述事件发生的概率.

逻辑回归公式:
$ h_\theta(x) = \frac{1}{1 + e^{-\theta^Tx}} $

Softmax回归公式:
$ Y_k = \frac{e^{Logit_k}}{\sum_{j=1}^{K} e^{Logit_j}} $

1.3 使用Softmax对MNIST分类

1.3.1 计算Logit

(简单的线性模型)

通过一下公式计算各个类别的Logit
$ \text{Logit} = z = W^T x + b $

1
2
3
W 是权重矩阵,
x 是输入的特征向量, 可以是经过前层神经网络处理后的特征表示.
b 是一个偏置向量,为每个类别提供一个可学习的偏置项.

1.3.2 使用Softmax函数

(激活函数-Softmax函数, 用于将线性组合转换为每个类别的概率分布)

使用Softmax函数将它转换为各个类别的概率值将

1.3.3 Softmax回归在TensorFlow中的实现

代码详见:Kaggle:digit-rec-tensowflow

todo:别的算法, 分别的结果评估、效果比对

总结算法公共工作过程?Tensorflow的原理和使用