使用Keras构建图像分类器
- 数据集:Fashion MNISIT
- 模型:MLP
- 框架:Keras
1、导入具体工具包
1.1 由于Keras是TensorFlow的高级API,因此有两种使用Keras的方法:
- 下载TensorFlow, 从TensorFlow中导入Keras,
from tensorflow import keras
- 直接下载Keras,直接导入
import keras
1.2 由于数据格式是 ndarray ,因此,导入numpy进行处理
import numpy as np
2、加载数据
2.1 Keras本身提供了一些常用的数据集,这里直接加载即可:
fashion_mnist = keras.datasets.fashion_mnist
(x_train_full, y_train_full), (x_test_full, y_test_full) = fashion_mnist.load_data()
3、数据处理与查看
3.1 Fashion MNIST中每张图片都是28×28的维度,图片中的像素都是0-255的整数,这里对每张图片进行归一化处理,具体如下:
# 从全部训练集中拆出5000作为验证集,并归一化
x_valid, x_train = x_train_full[:5000] / 255.0, x_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
3.2 查看各个数据集的维度: 使用np.shape()进行查看
print("训练集数据量: ",np.shape(x_train))
print("训练集标签: ",np.shape(y_train))
print("验证集数据量: ",np.shape(x_valid))
print("验证集标签: ",np.shape(y_valid))
输出:
训练集数据量: (55000, 28, 28)
训练集标签: (55000,)
验证集数据量: (5000, 28, 28)
验证集标签: (5000,)
4、构建模型
采用全连接捕获图片特征
model = keras.models.Sequential(name="MLP") # name:指定该模型的名称
model.add(keras.layers.Flatten(input_shape=[28, 28])) # input_shape:仅指定实例的形状,不指定batch_size
model.add(keras.layers.Dense(300, activation="relu")) # 300:该层的神经元个数;activation:激活函数
model.add(keras.layers.Dense(100, activation="relu")) # 100:该层的神经元个数;activation:激活函数
model.add(keras.layers.Dense(10, activation="softmax")) # 10:该层的神经元个数;activation:激活函数
上述代码解读:
Sequential:
- Sequential指Keras中的顺序模型,即该模型只有一个输入一个输出,并且隐藏层之间仅相邻,不能跳跃!Keras有两种模型:Sequential(顺序模型)和 Model(函数式模型)
Flatten:
- Flatten:将输入数据平铺,如:将输入28×28的数据,处理为1×784
Dense
- Dense:即全连接
上述代码中可以替换的地方:
- 激活函数如:activation=“relu” 可以改写为:activation=keras.activations.relu
- Sequential顺序模型,不仅可以通过add不断加入新的层,也可以直接放入一个list中传入,如:
model = keras.models.Sequential([keras.layers.Flatten(input_shape=[28, 28]),
keras.layers.Dense(300, activation="relu"),
keras.layers.Dense(100, activation="relu"),
keras.layers.Dense(10, activation="softmax")])
5、模型信息查看:
5.1 model.summary() 方法:会直接打印模型所有层的信息:层的名称、层的输出数据维度、参数量
model.summary()
5.2 model.layers:获取模型每层的信息,并全部信息以一个list返回
model.layers
5.3 get_weights 可以获取某层的所以参数,如权重和偏置
# 获取第2层的所有权重和偏置
weights, biases = model.layers[1].get_weights()
6、编译模型
神经网络搭建好后,便可以指定损失函数和优化器进行训练!
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
同理可以使用如下的方法: keras.optimizers.SGD()中可以指定学习率
model.compile(loss=keras.losses.sparse_categorical_crossentropy, optimizer=keras.optimizers.SGD(learning_rate=0.01), metrics=["accuracy"])
7、训练和评估模型
使用fit()方法进行训练:
# x_train, y_train:为训练数据和标签
# epochs:为训练的轮次
# validation_data:为验证集,每轮训练结束后,在验证集上进行验证看效果如何
history = model.fit(x_train, y_train, epochs=5, validation_data=(x_valid, y_valid))
上述中:validation_data=(x_valid, y_valid) 中的验证集是之前数据处理时,在训练集中抽取的,我们也可以不进行抽取!直接使用 validation_split=0.1 :即模型抽取训练集的10%数据进行验证!,具体如下:
history = model.fit(x_train, y_train, epochs=5, validation_split=0.1)
8、绘制结果
步骤7中的 fit() 会返回一个 history对象,其包含:
- history.params:训练的参数
- history.epoch:训练的轮次
- history.history:每个轮次后训练集和验证集上的损失和指标(准确率等等)
pd.DataFrame(history.history).plot() # 绘图
plt.grid(True) # 显示网格
plt.gca().set_ylim(0, 1) # y轴的坐标范围
plt.show() # 显示
9、在测试集上评估:
调整数据、网络结构、超参数、采样比、权重等等后,当模型在验证集上的效果不错后,那么便可以在测试集上进行评估,并将模型部署到实际环境中。
使用model.evaluate() 对测试集进行预测;
loss, acc = model.evaluate(x_test, y_test_full) # 返回测试集的loss和acc
print(loss, acc)
10、使用模型进行预测
10.1 取测试集中的一些数据,进行预测概率 model.predict():
x_pre = x_test[:5] # 取测试集前5个
y_pre = model.predict(x_pre).round(2) # 进行预测, 得到的概率保留2为小数
print(y_pre) # 得到每个类别的概率
输出:
[[0. 0. 0. 0. 0. 0.19 0. 0.19 0. 0.62]
[0. 0. 0.69 0. 0. 0. 0.31 0. 0. 0. ]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. ]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. ]
[0.19 0. 0.08 0.02 0.01 0. 0.7 0. 0.01 0. ]]
10.2 若不关心概率,可以通过 model.predict_classes 直接得到概率最大值所在的index:
# 标签的映射
class_name = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"] # 数据集真实对应的标签
y_pre_class = model.predict_classes(x_pre) # 预测出最大概率出的index
print(y_pre_class)
print(np.array(class_name)[y_pre_class])
输出:
[9 2 1 1 6]
['Ankle boot' 'Pullover' 'Trouser' 'Trouser' 'Shirt']
11、完整代码:
# import tensorflow as tf
import keras
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 加载数据
fashion_mnist = keras.datasets.fashion_mnist
(x_train_full, y_train_full), (x_test_full, y_test_full) = fashion_mnist.load_data()
# 数据处理
x_valid, x_train = x_train_full[:5000] / 255.0, x_train_full[5000:] / 255.0 # 归一化,取5000张图片作为验证集,剩下为训练集
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
x_test = x_test_full / 255.0
# 查看数据维度:
print("训练集数据量: ",np.shape(x_train))
print(type(x_train))
print("训练集标签: ",np.shape(y_train))
print("验证集数据量: ",np.shape(x_valid))
print("验证集标签: ",np.shape(y_valid))
# 构建神经网络
model = keras.models.Sequential(name="MLP")
model.add(keras.layers.Flatten(input_shape=[28, 28])) # 仅仅指定实例的形状,不指定batch_size
model.add(keras.layers.Dense(300, activation="relu"))
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))
# 打印网络结构和参数量等信息
model.summary()
# 打印:网络的层列表
print("神经网络的层列表: ", model.layers)
print("神经网络第二层的名称: ", model.layers[1].name)
weights, biases = model.layers[1].get_weights()
print("神经网络第二层的权重: ", weights)
print("神经网络第二层权重的维度: ", weights.shape)
print("神经网络第二层的偏置: ", biases)
print("神经网络第二层偏置的维度: ", biases.shape)
# 编译模型
model.compile(loss=keras.losses.sparse_categorical_crossentropy, optimizer=keras.optimizers.SGD(learning_rate=0.01), metrics=["accuracy"])
# 训练和评估
history = model.fit(x_train, y_train, epochs=2, validation_data=(x_valid, y_valid))
# 打印训练效果
pd.DataFrame(history.history).plot() # 绘图
plt.grid(True) # 显示网格
plt.gca().set_ylim(0, 1) # y轴的坐标范围
plt.show() # 显示
# 在测试集评估:
print("在测试集中进行预测:----------------------")
loss, acc = model.evaluate(x_test, y_test_full) # 返回测试集的loss和acc
print(loss, acc)
# 使用模型进行预测
x_pre = x_test[:5]
y_pre = model.predict(x_pre).round(2)
print(y_pre)
# 标签的映射
class_name = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
y_pre_class = model.predict_classes(x_pre)
print(y_pre_class)
print(np.array(class_name)[y_pre_class])
转载:https://blog.csdn.net/weixin_44177568/article/details/115839343