6.正则化应用
import keras
import numpy as np
import matplotlib.pyplot as plt
#按照顺序构成的模型
from keras.models import Sequential
#Dense是全连接层
from keras.layers import Dense
#
from keras.optimizers import SGD
#导入Dropout
from keras.layers import Dense, Activation, Dropout
from keras.datasets import mnist
from keras.utils import np_utils
#导入正则化
from keras.regularizers import l2
Using TensorFlow backend.
#载入数据
(x_train, y_train),(x_test, y_test)=mnist.load_data()
#(60000,28*28)
print("x_shape ",x_train.shape)
#(60000)
print("y_shape ",y_train.shape)
x_shape (60000, 28, 28)
y_shape (60000,)
#数据shape转换 (60000,28,28)---->(60000,784)
#并且归一化
x_train = x_train.reshape(x_train.shape[0], -1)/255.0
x_test = x_test.reshape(x_test.shape[0], -1)/255.0
#y是一维的标签, 转成one_hot形式
y_train = np_utils.to_categorical(y_train,num_classes=10)
y_test = np_utils.to_categorical(y_test,num_classes=10)
#创建模型,第一层的输入为784个神经元,输出为200个神经元
model = Sequential([
Dense(units=200, input_dim=784, bias_initializer="one", \
activation="tanh", kernel_regularizer=l2(0.0003)),
#softmax激活函数一般放在最后,因此这里使用其它的激活函数
# 因为上一层次已经指定 输出层是200, 那么下面的一层的输入
#一定是200,因此就不用显示的写出来了, 只需要指定输出层即可
Dropout(0.4), #就是让40%的神经元不工作
Dense(units=200, bias_initializer="one", \
activation="tanh",kernel_regularizer=l2(0.0003)),
Dropout(0.4), #就是让40%的神经元不工作
#这一层是输出层, 输出10个分类, 激活函数使用softmax
Dense(units=10, bias_initializer="one", \
activation="softmax",kernel_regularizer=l2(0.0003))
])
#创建模型也可以使用如下等价做法, 和上面的 Sequential([
# Dense()
# Dense()
# ]) 是一致的
# model.add(Dense(...))
# model.add(Dense(...))
#自定义优化器
mysgd = SGD(lr=0.2)
#定义优化器,loss function ,同时在训练过程中也计算准确率
model.compile(
optimizer=mysgd,
#更改损失函数为交叉熵, 从结果可以看出交叉熵损失函数相比于mse更优
#它可以在较短的step内,收敛到较好的效果
#对于分类问题,交叉熵损失函数是个不错的选择
loss="categorical_crossentropy",
#可以计算准确率
metrics=["accuracy"]
)
#训练模型
#之前的训练方式是 model.train_on_batch(x_data, y_data)
model.fit(x_train,y_train,batch_size=32, epochs=10)
#评估模型, 即 在测试集上做测试,得到loss和accuracy
#注意:训练的时候,有dropout,那么神经元会随机的关闭一部分,
#而测试的时候,神经元是全部打开的,
#因此才会出现 test accuracy 0.9697 与训练记录显示的准确率不一致的情况
loss, accuracy = model.evaluate(x_test, y_test)
print("test loss", loss)
print("accuracy", accuracy)
#查看训练集的Loss和准确率
loss, accuracy = model.evaluate(x_train, y_train)
print("train loss", loss)
print("accuracy", accuracy)
Epoch 1/10
60000/60000 [==============================] - 3s 50us/step - loss: 0.6297 - acc: 0.8630
Epoch 2/10
60000/60000 [==============================] - 3s 49us/step - loss: 0.4451 - acc: 0.9134
Epoch 3/10
60000/60000 [==============================] - 3s 50us/step - loss: 0.3924 - acc: 0.9262
Epoch 4/10
60000/60000 [==============================] - 3s 48us/step - loss: 0.3652 - acc: 0.9316
Epoch 5/10
60000/60000 [==============================] - 3s 48us/step - loss: 0.3477 - acc: 0.9346
Epoch 6/10
60000/60000 [==============================] - 3s 48us/step - loss: 0.3345 - acc: 0.9367
Epoch 7/10
60000/60000 [==============================] - 3s 49us/step - loss: 0.3235 - acc: 0.9406
Epoch 8/10
60000/60000 [==============================] - 3s 49us/step - loss: 0.3222 - acc: 0.9401
Epoch 9/10
60000/60000 [==============================] - 3s 48us/step - loss: 0.3175 - acc: 0.9408
Epoch 10/10
60000/60000 [==============================] - 3s 50us/step - loss: 0.3130 - acc: 0.9425
10000/10000 [==============================] - 0s 19us/step
test loss 0.23628806715011597
accuracy 0.9655
60000/60000 [==============================] - 1s 16us/step
train loss 0.22543356195290884
accuracy 0.96835
#是否添加正则化,需要根据具体的情况来判断
#一般的,当数据集比较复杂的时候,一般要添加正则化和dropout
#当数据集没有那么复杂时,无需添加正则化和dropout