欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MNIST手写数字识别-03 softmax回归模型

程序员文章站 2022-04-30 20:37:30
...

MNIST手写数字识别——03 softmax回归模型

加载 MNIST 数据集

import tensorflow as tf

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
print(x_train.shape, type(x_train))
print(y_train.shape, type(y_train))

1.数据处理:规范化

# 将图像本身从[28,28]转换为[784,]
X_train = x_train.reshape(60000, 784)
X_test = x_test.reshape(10000, 784)
print(X_train.shape, type(X_train))
print(X_test.shape, type(X_test))
# 将数据类型转换为float32
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
# 数据归一化
X_train /= 255
X_test /= 255

2.统计训练数据中各标签数量

import numpy as np
import matplotlib.pyplot as plt

label, count = np.unique(y_train, return_counts=True)
print(label, count)
fig = plt.figure()
plt.bar(label, count, width = 0.7, align='center')
plt.title("Label Distribution")
plt.xlabel("Label")
plt.ylabel("Count")
plt.xticks(label)
plt.ylim(0,7500)

for a,b in zip(label, count):
    plt.text(a, b, '%d' % b, ha='center', va='bottom',fontsize=10)

plt.show()

MNIST手写数字识别-03 softmax回归模型

3.数据处理:one-hot 编码

几种编码方式的对比
Binary Gray code One-hot
000 000 00000001
001 001 00000010
010 011 00000100
011 010 00001000
100 110 00010000
101 111 00100000
110 101 01000000
111 100 10000000
one-hot 应用(独热编码)

MNIST手写数字识别-03 softmax回归模型

n_classes = 10
print("Shape before one-hot encoding: ", y_train.shape)
Y_train = tf.keras.utils.to_categorical(y_train, n_classes)
print("Shape after one-hot encoding: ", Y_train.shape)
Y_test = tf.keras.utils.to_categorical(y_test, n_classes)
print(y_train[0])
print(Y_train[0])

4. 使用 Keras sequential model 定义神经网络

Softmax回归:只通过一层简单的以softmax为**函数的全连接层,就可以得到分类的结果。

Sequential = tf.keras.models.Sequential
Dense = tf.keras.layers.Dense
Activation = tf.keras.layers.Activation

# Sequential 序贯模型
# 使用.add()方法将各层添加到模型中:
model = Sequential()
model.add(Dense(10))
model.add(Activation('softmax'))

编译模型

model.compile()

compile(optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')

训练模型,并将指标保存到 history 中

model.fit()

fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)
history = model.fit(X_train,
                    Y_train,
                    batch_size=128,
                    epochs=10,
                    verbose=2, # 日志输出的复杂度
                    validation_data=(X_test, Y_test))

print(history.history)

loss:训练集损失值

accuracy:训练集准确率

val_loss:测试集损失值

val_accruacy:测试集准确率

可视化指标

fig = plt.figure()
plt.subplot(2, 1, 1)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model Accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='lower right')

plt.subplot(2, 1, 2)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model Loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper right')
plt.tight_layout()

plt.show()

MNIST手写数字识别-03 softmax回归模型
以下5种情况可供参考:

train loss 不断下降,test loss不断下降,说明网络仍在学习;(最好的)

train loss 不断下降,test loss趋于不变,说明网络过拟合;(max pool或者正则化)

train loss 趋于不变,test loss不断下降,说明数据集100%有问题;(检查dataset)

train loss 趋于不变,test loss趋于不变,说明学习遇到瓶颈,需要减小学习率或批量数目;

train loss 不断上升,test loss不断上升,说明网络结构设计不当,训练超参数设置不当,数据集经过清洗等问题。(最不好的情况)

保存模型

model.save()

You can use model.save(filepath) to save a Keras model into a single HDF5 file which will contain:

  • the architecture of the model, allowing to re-create the model
  • the weights of the model
  • the training configuration (loss, optimizer)
  • the state of the optimizer, allowing to resume training exactly where you left off.

tf.io.gfile

You can then use keras.models.load_model(filepath) to reinstantiate your model. load_model will also take care of compiling the model using the saved training configuration (unless the model was never compiled in the first place).

import os

gfile = tf.io.gfile

save_dir = "./mnist/softmax-model/"

if gfile.exists(save_dir):
    gfile.rmtree(save_dir)
gfile.mkdir(save_dir)

model_name = 'keras_mnist.h5'
model_path = os.path.join(save_dir, model_name)
model.save(model_path)
print('Saved trained model at %s ' % model_path)

加载模型

mnist_model = tf.keras.models.load_model(model_path)

统计模型在测试集上的分类结果

loss_and_metrics = mnist_model.evaluate(X_test, Y_test, verbose=2)
    
print("Test Loss: {}".format(loss_and_metrics[0]))
print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))

predicted_classes = mnist_model.predict_classes(X_test)

correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
print("Classified correctly count: {}".format(len(correct_indices)))
print("Classified incorrectly count: {}".format(len(incorrect_indices)))