飞道的博客

1、使用Keras构建图像分类器

211人阅读  评论(0)

使用Keras构建图像分类器

  • 数据集:Fashion MNISIT
  • 模型:MLP
  • 框架:Keras

1、导入具体工具包

1.1 由于Keras是TensorFlow的高级API,因此有两种使用Keras的方法:

  1. 下载TensorFlow, 从TensorFlow中导入Keras,
from tensorflow import keras
  1. 直接下载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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场