2.2 Mnist手写数据集

2.2 Mnist手写数据集

全连接网络:网络层的每一个结点都与上一层的所有结点相连。

在这里插入图片描述

多隐层全连接神经网络:
在这里插入图片描述

代码如下:

1. 导入必要的模块

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import tensorflow as tf
from tensorflow.keras import datasets, Input, Model
from tensorflow.keras.layers import Flatten, Dense, Activation, BatchNormalization
from tensorflow.keras.initializers import TruncatedNormal

2. 载入Mnist数据集

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

输出如下:

(60000, 28, 28)
(60000,)
(10000, 28, 28)
(10000,)

维度 ( 60000 , 28 , 28 ) → ( 60000 , 784 ) (60000, 28, 28) \to (60000, 784) (60000,28,28)(60000,784)

x_train = x_train.reshape(-1, 28 * 28)
x_test = x_test.reshape(-1, 28 * 28)

归一化处理:

x_train = x_train / 255
x_test = x_test / 255

3. 模型搭建

用到的api:

全连接层tf.keras.layers.Dense

用到的参数:

  • units:输入整数,全连接层神经元个数。

  • activation:激活函数。

    可选项:

    • ‘sigmoid’:sigmoid激活函数
    • ‘tanh’:tanh激活函数
    • ‘relu’:relu激活函数
    • 'elu’或tf.keras.activations.elu(alpha=1.0):elu激活函数
    • ‘selu’:selu激活函数
    • ‘swish’: swish激活函数(tf2.2版本以上才有)
    • ‘softmax’: softmax函数
  • kernel_initializer:权重初始化,默认是’glorot_uniform’(即Xavier均匀初始化)。

    可选项:

    • 'RandomNormal’或tf.keras.initializers.TruncatedNormal(mean=0.0, stddev=0.05):正态分布采样,均值为0,标准差0.05
    • ‘glorot_normal’:正态分布采样,均值为0,方差为2 / (fan_in + fan_out)
    • ‘glorot_uniform’:均匀分布采样,范围[-limit, limit],limit = sqrt(6 / (fan_in + fan_out))
    • ‘lecun_normal’:正态分布采样,均值为0,方差为1 / fan_in
    • ‘lecun_uniform’:均匀分布采样,范围[-limit, limit],limit = sqrt(3 / fan_in)
    • ‘he_normal’:正态分布采样,均值为0,方差为2 / fan_in
    • ‘he_uniform’:均匀分布采样,范围[-limit, limit],limit = sqrt(6 / fan_in)

    fan_in是输入的神经元个数,fan_out是输出的神经元个数。

  • name:输入字符串,给该层设置一个名称。

输入层tf.keras.Input

用到的参数:

  • shape:输入层的大小。

  • name:输入字符串,给该层设置一个名称。

BN层tf.keras.layers.BatchNormalization

用到的参数:

  • axis:需要做批处理的维度,默认为-1,也就是输入数据的最后一个维度。

  • name:输入字符串,给该层设置一个名称。

模型设置tf.keras.Sequential.compile

用到的参数:

  • loss:损失函数,多分类任务一般使用"sparse_categorical_crossentropy",sparse表示先对标签做one hot编码。

  • optimizer:优化器,这里选用"sgd".

  • metrics:评价指标,这里选用"accuracy".

构建50个隐层的神经网络,每层100个神经元

inputs = Input(shape = 28 * 28, name = 'input')


x = Dense(units = 100, activation = 'tanh', kernel_initializer = TruncatedNormal(mean = 0.0, stddev = 1), name = 'dense_0')(inputs)

for i in range (49):
    x = Dense(units = 100, activation = 'tanh', kernel_initializer = TruncatedNormal(mean = 0.0, stddev = 1), name = 'dense_' + str(i + 1))(x)

outputs = Dense(units = 10, activation = 'softmax', name = 'output')(x)

model = Model(inputs = inputs, outputs = outputs)

model.compile(loss = 'sparse_categorical_crossentropy', optimizer = 'sgd', metrics = ['accuracy'])

查看模型:

model.summary()

在这里插入图片描述

在这里插入图片描述

4. 模型训练

model.fit(x = x_train, y = y_train, batch_size = 128, epochs = 10, validation_split = 0.3, shuffle = True)

在这里插入图片描述

至此,模型的准确率不足 15 % 15\% 15%

画出每一层的直方图:

layer_names = ['input', 'dense_0', 'dense_1', 'dense_1', 'dense_2', 'dense_3', 'dense_4']

fig, ax = plt.subplots(1, len(layer_names), figsize = (10, 5))

for i, name in enumerate(layer_names):
    layer_model = Model(inputs = model.input, outputs = model.get_layer(name).output)
    pred = layer_model.predict(x_train)
    ax[i].hist(pred.reshape(-1),bins = 100)
plt.show()

在这里插入图片描述

特点:训练数据大多分布在1和-1,处于中间不饱和态数据较少。

5. 测试集评估结果

model.evaluate(x_test, y_test)

在这里插入图片描述

可以看到,最终测试集准确率不足 12 % 12\% 12%

6. 使用权重初始化

(1)使用lecun_normal

inputs = Input(shape = 28 * 28, name = 'input')


x = Dense(units = 100, activation = 'tanh', kernel_initializer = 'lecun_normal', name = 'dense_0')(inputs)

for i in range (49):
    x = Dense(units = 100, activation = 'tanh', kernel_initializer = 'lecun_normal', name = 'dense_' + str(i + 1))(x)

outputs = Dense(units = 10, activation = 'softmax', name = 'output')(x)

model = Model(inputs = inputs, outputs = outputs)

model.compile(loss = 'sparse_categorical_crossentropy', optimizer = 'sgd', metrics = ['accuracy'])

训练集:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SLPoqdMe-1607829860380)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20201127085655160.png)]

直方图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ecyemJV7-1607829860381)(data:image/png;base64,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)]

测试集:

(2)使用he_normal

inputs = Input(shape = 28 * 28, name = 'input')


x = Dense(units = 100, activation = 'relu', kernel_initializer = 'he_normal', name = 'dense_0')(inputs)

for i in range (49):
    x = Dense(units = 100, activation = 'relu', kernel_initializer = 'he_normal', name = 'dense_' + str(i + 1))(x)

outputs = Dense(units = 10, activation = 'softmax', name = 'output')(x)

model = Model(inputs = inputs, outputs = outputs)

model.compile(loss = 'sparse_categorical_crossentropy', optimizer = 'sgd', metrics = ['accuracy'])

训练集:

在这里插入图片描述

直方图:
在这里插入图片描述

测试集:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bvsMaijR-1607829860385)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20201127090844034.png)]

(3)使用Batch Normalization

相似的,我们可以不通过修改kernel_initializer,添加Batch Normalization项对饱和函数区域的修复情况,这里的kernel_initializer改回TruncatedNormal

inputs = Input(shape = 28 * 28, name = 'input')


x = Dense(units = 100, kernel_initializer = TruncatedNormal(mean = 0.0, stddev = 1), name = 'dense_0')(inputs)
x = BatchNormalization(axis = -1)(x)
x = Activation(activation = 'tanh', name = 'activation_0')(x)

for i in range (49):
    x = Dense(units = 100, kernel_initializer = TruncatedNormal(mean = 0.0, stddev = 1), name = 'dense_' + str(i + 1))(x)
    x = BatchNormalization(axis = -1)(x)
    x = Activation(activation = 'tanh', name = 'activation_' + str(i + 1))(x)

outputs = Dense(units = 10, activation = 'softmax', name = 'output')(x)

model = Model(inputs = inputs, outputs = outputs)

model.compile(loss = 'sparse_categorical_crossentropy', optimizer = 'sgd', metrics = ['accuracy'])

在这里插入图片描述

在这里插入图片描述

可以看到,相比于最初的 12 % 12\% 12%Batch Normalization对于饱和函数区域的修复还是很可观的

epochs设定为100,最终将稳定在 89 % 89\% 89%

7. 可视化

(1)查看数据集图片

定义画图函数plot_images

参数介绍:

  • images:包含多张图片数据的序列。

  • labels:包含图片对应标签的序列(序列中的元素需要是0,1,2,…,9这样的正整数)。

def plot_images(images, labels):
    class_names = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    fig, axes = plt.subplots(3, 10, figsize=(20,8))
    axes = axes.flatten()
    for img, label, ax in zip(images, labels, axes):
        ax.imshow(img)
        ax.set_title(class_names[label])
        ax.axis('off')
    plt.tight_layout()
    plt.show()

随机抽取30张训练集图片进行查看

np.random.seed(99)
index_list = np.random.randint(0,59999,30)

plot_images(x_train[index_list], y_train[index_list])

在这里插入图片描述

随机抽取30张测试集图片进行查看
在这里插入图片描述

(2)画图查看history数据的变化趋势

history = model.fit(x=x_train, y=y_train, batch_size=32,
                     epochs=200, validation_split=0.4,
                     shuffle=True)
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.xlabel('epoch')
plt.show()

在这里插入图片描述

随着epoch的增加,

  • loss(蓝线)不断下降;

  • val_loss(绿线)先下降后抬升;

  • accuracy(黄线)不断上升;

  • val_accuracy(红线)刚开始上升后趋于平稳;

loss(蓝线)和val_loss(绿线)的变化趋势说明模型过拟合了。

8. 结果过拟合

(1) 增加训练数据量

  1. 采集更多的数据
  2. 数据增广(image augmentation):对已有数据做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模。这里不讲数据增广,有兴趣的可以查看tf.keras.preprocessing.image.ImageDataGenerator这个api
np.random.seed(43)
index_list = np.random.randint(0,59999,10000)#将随机抽取1000张改成随机抽取10000张

x_train = x_train[index_list] 
y_train = y_train[index_list]

在这里插入图片描述

val_loss抬升程度明显减小

accuracy: 0.9388

(2) 减小模型复杂度

  1. 减少隐层
  2. 减少神经元个数
model = Sequential()

# 展平层flatten
model.add(Flatten(input_shape=(28, 28), name='flatten'))

model.add(Dense(units=100, activation='tanh',kernel_initializer='lecun_normal'))

# 隐层dense
#for i in range(20):
#    model.add(Dense(units=500, activation='tanh',kernel_initializer='lecun_normal'))

# 加正则的隐层dense
#for i in range(20):
#    model.add(Dense(units=500, activation='tanh', kernel_initializer='lecun_normal',
#                    kernel_regularizer=tf.keras.regularizers.l2(1e-5)))

# dropout层
# model.add(Dropout(rate=0.5))

# 输出层
model.add(Dense(units=10, activation='softmax', name='logit'))

# 设置损失函数loss、优化器optimizer、评价标准metrics
model.compile(loss='sparse_categorical_crossentropy', optimizer=tf.keras.optimizers.SGD(
    learning_rate=0.001), metrics=['accuracy'])

在这里插入图片描述

 accuracy: 0.9053

(3) 加正则项

tf.keras.regularizers.l2

用到的参数:

  • l:惩罚项,默认为0.01。
model = Sequential()

# 展平层flatten
model.add(Flatten(input_shape=(28, 28), name='flatten'))


# 加正则的隐层dense
for i in range(20):
    model.add(Dense(units=500, activation='tanh', kernel_initializer='lecun_normal',
                    kernel_regularizer=tf.keras.regularizers.l2(1e-5)))


# 输出层
model.add(Dense(units=10, activation='softmax', name='logit'))

# 设置损失函数loss、优化器optimizer、评价标准metrics
model.compile(loss='sparse_categorical_crossentropy', optimizer=tf.keras.optimizers.SGD(
    learning_rate=0.001), metrics=['accuracy'])

在这里插入图片描述

(4) 提前停止

tf.keras.callbacks.EarlyStopping

用到的参数:

  • monitor:监控的数据,一般为’val_loss’。

  • min_delta:定义模型改善的最小量,只有大于min_delta才会认为模型有改善,默认为0。

  • patience:有多少个epoch,模型没有改善,训练就会停止,默认为0。

  • restore_best_weights:是否使用监控数据最好的模型参数,如果是False,使用的是训练最后一步的模型参数,默认False。

# 设置EarlyStopping,val_loss经过10个epoch都没有改善就停止训练
earlystop = EarlyStopping(monitor='val_loss', min_delta=1e-4, patience=10, restore_best_weights=True)

最终模型训练到96epoch即终止训练。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMy23PN9-1607833308906)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20200913135824031.png)]

图像:
在这里插入图片描述

(5)Dropout

tf.keras.layers.Dropout

用到的参数:

  • rate:神经元失效的概率,取值0~1的浮点数。

  • seed:随机种子,取正整数。

  • name:输入字符串,给该层设置一个名称。

model = Sequential()

# 展平层flatten
model.add(Flatten(input_shape=(28, 28), name='flatten'))

#model.add(Dense(units=100, activation='tanh',kernel_initializer='lecun_normal'))

# 隐层dense
#for i in range(20):
#    model.add(Dense(units=500, activation='tanh',kernel_initializer='lecun_normal'))

# 加正则的隐层dense
for i in range(18):
    model.add(Dense(units=500, activation='tanh', kernel_initializer='lecun_normal'))

model.add(Dense(units=500, activation='tanh', kernel_initializer='lecun_normal'))
# dropout层
model.add(Dropout(rate=0.5))
model.add(Dense(units=500, activation='tanh', kernel_initializer='lecun_normal'))
# dropout层
model.add(Dropout(rate=0.5))

# 输出层
model.add(Dense(units=10, activation='softmax', name='logit'))

# 设置损失函数loss、优化器optimizer、评价标准metrics
model.compile(loss='sparse_categorical_crossentropy', optimizer=tf.keras.optimizers.SGD(
    learning_rate=0.001), metrics=['accuracy'])
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值