非结构化数据指的是那些没有固定格式的数据,如文本、图像、视频和音频等。这类数据没有预定义的行、列、值或特征,比结构化数据更加杂乱无章。深度学习模型的设计灵感来源于模仿人脑的处理能力,因此在解决这类问题时更为强大。本文将使用MNIST手写数字数据集,该数据集包含了手写数字的图像,将逐步实现人工神经网络(ANN)的构建和训练。
在构建任何模型之前,首先需要导入必要的库并读取数据。以下是导入库和读取MNIST数据集的代码示例:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
from tensorflow.keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train和X_test包含灰度RGB代码(范围从0到255),而y_train和y_test包含从0到9的标签,代表实际的数字。以下是如何可视化训练数据集中的图像:
plt.imshow(X_train[0])
for i in range(20):
plt.subplot(5, 5, i+1)
plt.imshow(X_train[i], cmap=plt.get_cmap('gray'))
plt.show()
检查训练和测试数据的形状:
print(X_train.shape)
print(X_test.shape)
# 输出: (60000, 28, 28) 和 (10000, 28, 28)
训练数据(X_train)包含60000张28*28大小的图像,测试数据(X_test)包含10000张图像。每张图像是二维的,像素值范围从0到255。在预处理步骤中,需要将这些图像从二维转换为一维,以输入到人工神经网络模型中,将使用reshape函数。
X_train_flat = X_train.reshape(len(X_train), 28*28)
X_test_flat = X_test.reshape(len(X_test), 28*28)
print(X_train_flat.shape)
print(X_test_flat.shape)
# 输出: (60000, 784) 和 (10000, 784)
接下来,在预处理中,需要对像素值进行归一化,以便输入到模型中。将像素值归一化到0-1的范围。
X_train_flat = X_train_flat / 255
X_test_flat = X_test_flat / 255
归一化后,现在可以构建模型了。深度学习模型的构建包括以下几个步骤:定义模型、编译模型、拟合模型、评估模型和进行预测。
首先,将构建一个非常简单的模型,其中只有输入层、输出层和激活函数。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential()
model.add(Dense(10, input_shape=(784,), activation='softmax'))
在上面的代码中,使用Sequential()函数定义模型,并添加输入形状和输出层。使用softmax激活函数,因为有一个多类分类问题,并且有超过两个类别标签。
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
在第二步中,使用损失函数、优化器和指标来编译模型。使用sparse_categorical_crossentropy作为损失函数,因为数据集中有多个标签。对于优化器,使用Adam来更新权重,以实现模型中的最小损失,并使用准确度作为指标。
model.fit(X_train_flat, y_train, epochs=10)
在这里,将定义的模型拟合到训练和测试数据集上,并指定迭代次数。一个完整的前向传播和反向传播训练数据集的过程被认为是一个epoch。
从上面的输出中,可以看到训练准确度为93%,损失为0.25。让也在测试数据上评估模型。
model.evaluate(X_test_flat, y_test)
对于测试准确度,得到了92%,损失为0.28。
y_predict = model.predict(X_test_flat)
y_predict[3] # 打印第3个索引
在上面的输出中,得到了10个值,因为目标变量有10个标签(0到9)。概率最高的值是预测输出。要获得概率最高的值,将使用以下代码。
np.argmax(y_predict[3])
上面的代码输出为0,这意味着预测的数字是0。
现在需要检查预测输出是否与实际输出相同。为此,将检查测试数据中的第三个索引图像,因为在输出中得到了0,这意味着预测与实际相同。
plt.imshow(X_test[3])
绘制混淆矩阵以检查实际与预测标签。
y_predict_labels = np.argmax(y_predict, axis=1)
from sklearn.metrics import confusion_matrix
matrix = confusion_matrix(y_test, y_predict_labels)
plt.figure(figsize=(10, 7))
sns.heatmap(matrix, annot=True, fmt='d')
model2 = Sequential()
model2.add(Dense(100, input_shape=(784,), activation='relu'))
model2.add(Dense(64, activation='relu'))
model2.add(Dense(32, activation='relu'))
model2.add(Dense(10, activation='softmax'))
model2.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model2.fit(X_train_flat, y_train, epochs=10)
model2.evaluate(X_test_flat, y_test)