目录
一、学习目标
- 掌握Keras进行训练的方法
- 掌握各种优化器和损失函数的特点
二、学习内容
对cifar10数据库(10类),做如下实验:
- 对比各种优化器的结果:分别选择SGD、Adam、RMSprop等优化器进行求解模型,设置合适的参数,包括学习率。
- 对比各种损失的结果:分类交叉熵损失、稀疏分类交叉熵损失、均方误差损失、KL散度损失等。
三、学习过程
使用不同优化器和损失函数的对比:
优化器 | 损失函数 | 学习率 | 准确率 |
SGD | categorical_crossentropy | 0.1 | 0.3728 |
SGD | categorical_crossentropy | 0.01 | 0.4666 |
SGD | categorical_crossentropy | 0.001 | 0.3951 |
SGD | sparse_categorical_crossentropy | 0.01 | 0.4636 |
SGD | mean_squared_error | 0.01 | 0.3601 |
SGD | kullback_leibler_divergence | 0.01 | 0.4644 |
Adam | categorical_crossentropy | 0.1 | 0.1000 |
Adam | categorical_crossentropy | 0.01 | 0.1845 |
RMSprop | categorical_crossentropy | 0.1 | 0.1000 |
RMSprop | categorical_crossentropy | 0.01 | 0.2298 |
调试过程:
1.学习率为0.1,优化器为随机梯度下降函数SGD,使用分类交叉熵损失函数的效果:
学习率为0.01,优化器为随机梯度下降函数SGD,使用分类交叉熵损失函数的效果:
学习率为0.01,优化器为随机梯度下降函数SGD,使用分类交叉熵损失函数,batch_size改为16的效果:
学习率为0.001,优化器为随机梯度下降函数SGD,使用分类交叉熵损失函数的效果:
学习率为0.1,优化器为Adam,使用分类交叉熵损失函数的效果:
学习率为0.01,优化器为Adam,使用分类交叉熵损失函数的效果:
学习率为0.1,优化器为RMSprop,使用分类交叉熵损失函数的效果:
学习率为0.01,优化器为RMSprop,使用分类交叉熵损失函数的效果:
2. 学习率为0.01,优化器为随机梯度下降函数SGD,使用稀疏分类交叉熵损失函数的效果:
学习率为0.01,优化器为随机梯度下降函数SGD,使用均方误差损失函数的效果:
学习率为0.01,优化器为随机梯度下降函数SGD,使用KL散度损失函数的效果:
四、源码
# In[1]:
#加载cifar10数据集
from tensorflow.keras import datasets
(x_train, y_train), (x_test, y_test) = datasets.cifar10.load_data()
#把值转换成0和1
x_train,x_test = x_train/255.0, x_test/255.0
#将标签转换成独热编码
from tensorflow.keras import utils
#使用稀疏交叉熵损失函数时要把下面两行代码注释掉
y_train = utils.to_categorical(y_train,num_classes=10)
y_test = utils.to_categorical(y_test,num_classes=10)
# In[2]:自定义的损失函数(并没有调用)
import keras as K
# 均方误差损失,相应的类为tf.keras.losses.MeanSquaredError(),以下类似
def mean_squared_error(y_true, y_pred):
return K.mean(K.square(y_pred - y_true), axis=-1)
# 绝对值均方误差损失
def mean_absolute_error(y_true, y_pred):
return K.mean(K.abs(y_pred - y_true), axis=-1)
# 绝对误差比例损失
def mean_absolute_percentage_error(y_true, y_pred):
diff = K.abs((y_true - y_pred) / K.clip(K.abs(y_true),
K.epsilon(),
None))
return 100. * K.mean(diff, axis=-1)
# 对数误差平方损失
def mean_squared_logarithmic_error(y_true, y_pred):
first_log = K.log(K.clip(y_pred, K.epsilon(), None) + 1.)
second_log = K.log(K.clip(y_true, K.epsilon(), None) + 1.)
return K.mean(K.square(first_log - second_log), axis=-1)
# 铰链损失
def hinge(y_true, y_pred):
return K.mean(K.maximum(1. - y_true * y_pred, 0.), axis=-1)
# 平方铰链损失
def squared_hinge(y_true, y_pred):
return K.mean(K.square(K.maximum(1. - y_true * y_pred, 0.)), axis=-1)
# 分类铰链损失
def categorical_hinge(y_true, y_pred):
pos = K.sum(y_true * y_pred, axis=-1)
neg = K.max((1. - y_true) * y_pred, axis=-1)
return K.maximum(0., neg - pos + 1.)
# KL散度损失
def kullback_leibler_divergence(y_true, y_pred):
y_true = K.clip(y_true, K.epsilon(), 1)
y_pred = K.clip(y_pred, K.epsilon(), 1)
return K.sum(y_true * K.log(y_true / y_pred), axis=-1)
# 钓鱼损失
def poisson(y_true, y_pred):
return K.mean(y_pred - y_true * K.log(y_pred + K.epsilon()), axis=-1)
# 余弦逼近损失
def cosine_proximity(y_true, y_pred):
y_true = K.l2_normalize(y_true, axis=-1)
y_pred = K.l2_normalize(y_pred, axis=-1)
return -K.sum(y_true * y_pred, axis=-1)
# In[2]:构建函数
from tensorflow.keras import Sequential,layers,losses
model = Sequential()
model.add(layers.Reshape((32*32*3,),input_shape=(32,32,3)))
model.add(layers.Dense(512))
model.add(layers.Activation('relu')) #中间层的激活函数
model.add(layers.Dense(10,activation='softmax')) #最后一层的激活函数不变
loss_fn = losses.SparseCategoricalCrossentropy() #稀疏交叉熵函数
model.summary()
# In[3]:训练
# 优化器为随机梯度下降SGD,损失函数为交叉熵损失categorical_crossentropy,性能评估用识别率accuracy
from tensorflow.keras import optimizers
#分别设置识别率为0.1、0.01、0.001(默认识别率为0.01)
optimizer = optimizers.SGD(0.01)
#optimizer = optimizers.Adam(lr=0.01)
#optimizer = optimizers.RMSprop(lr=0.01)
#optimizer = optimizers.RMSprop(lr=0.001,rho =0.9, epsilon=None,decay=0.0)
#optimizer = optimizers.Adagrad(lr=0.01,epsilon=None, decay=0.0)
#optimizer = optimizers.Adadelta(lr=1.0,rho=0.95, epsilon=None, decay=0.0)
#optimizer = optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999,epsilon=None, decay=0.0)
#optimizer = optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999,epsilon=None, schedule_decay=0.004)
#调用内置的各种损失函数
#分类交叉熵损失
model.compile(optimizer,loss='categorical_crossentropy', metrics=['accuracy'])
#均方误差损失
#model.compile(optimizer,loss='mean_squared_error', metrics=['accuracy'])
#model.compile(optimizer,loss='mean_absolute_error', metrics=['accuracy'])
#model.compile(optimizer,loss='mean_absolute_percentage_error', metrics=['accuracy'])
#model.compile(optimizer,loss='mean_squared_logarithmic_error', metrics=['accuracy'])
#model.compile(optimizer,loss='hinge', metrics=['accuracy'])
#model.compile(optimizer,loss='squared_hinge', metrics=['accuracy'])
#model.compile(optimizer,loss='categorical_hinge', metrics=['accuracy'])
#KL散度损失
#model.compile(optimizer,loss='kullback_leibler_divergence', metrics=['accuracy'])
#model.compile(optimizer,loss='poisson', metrics=['accuracy'])
#Sparse Categorical Cross entropy(稀疏交叉熵函数)
#model.compile(optimizer,loss='sparse_categorical_crossentropy', metrics=['accuracy'])
#稀疏交叉熵函数只能用非独热编码
#model.compile(optimizer,loss=loss_fn, metrics=['accuracy'])
# 训练模型
model.fit(x_train, y_train,
validation_data=(x_test, y_test),
batch_size=32, #设置成2的整数幂
epochs=6)
# In[4]:
print('\nTesting ------------------- ')
# model.load_weights('mymodel.h5')
loss, accuracy = model.evaluate(x_test, y_test)
print('Test loss:',loss)
print('Test accuracy',accuracy)
五、学习产出
- 在调用稀疏交叉熵损失函数时折腾了我一小会儿,经过查询资料后才发现稀疏交叉熵损失函数要求target为非独热编码,它在函数内部进行onehot编码实现。