简单分类任务的炼丹经验

对于一些复杂的分类任务,adam(Nadam)往往具有很好的效果。但是对于一些简单的分类任务却并非如此。

简单分类任务的炼丹经验简单分类任务的炼丹经验

两张图是在别处盗的,从图中可以看出adadelta具有最快的收敛速度,在鞍区停留时间最短。对于简单分类任务,有时为了防止过拟合,往往使用很少的参数。这时正确的初始化方法配合收敛速度最快的adadelta是最好的选择。

例如一个简单的线性二分类问题(keras2.0下):

import matplotlib.pyplot as plt
import numpy as np
from keras.layers import Dense,Input
from keras.models import save_model,Model
import keras as k
import random as rd

t1x=(np.linspace(1,10000,10000)+0.0).reshape((10000,1))
t2x=(np.arange(1,10001,1)+0.0).reshape((10000,1))


t1y=(t1x*(3+1.5*rd.random())+np.random.rand(10000).reshape((10000,1))).reshape((10000,1))
t2y=(t2x*(5+1.5*rd.random())+np.random.rand(10000).reshape((10000,1))).reshape((10000,1))

data1=np.concatenate((t1x,t1y),axis=1)
data2=np.concatenate((t2x,t2y),axis=1)
data=np.concatenate((data1,data2),axis=0)
print(data.shape)

label=np.array([0.0]*10000+[1.0]*10000).reshape(20000,1)

def loss_f(x,y):
    return -k.losses.binary_crossentropy(x,y)



input=Input((2,))
'''actually,the initializers impact'''
l=Dense(1,activation='sigmoid',kernel_initializer=k.initializers.zeros())(input)
#l=Dense(1,activation='sigmoid',kernel_initializer=k.initializers.ones())(input)
#l=Dense(1,activation='sigmoid')(input)
m=Model(inputs=input,outputs=l,name='my_net')
'''adaelta has the quickest velocity when in the slot'''
m.compile(optimizer=k.optimizers.adadelta(0.05),loss=k.losses.mse,metrics=['accuracy'])


m.fit(data,label,epochs=25,batch_size=256,shuffle=True)
w=m.layers[1].get_weights()[0]
b=m.layers[1].get_weights()[1]
print(w)
print(b)

test=np.array([22.3,66.9]).reshape(1,2)
test2=np.array([10.2,50]).reshape(1,2)
a=m.predict(test)
b=m.predict(test2)
print(a,b)

y=[0]*10000
for x in range(10000):
    y[x]=(0.5-b-w[0]*x)/w[1]

f=plt.figure()
f.add_subplot(111)
plt.scatter(t1x,t1y,cmap='red')
plt.scatter(t2x,t2y,cmap='blue',marker='x')
plt.scatter(np.linspace(1,10000,10000),y,cmap='green',marker='v')
plt.show()

利用adadelta配合zeros可以迅速的收敛到很好的结果。

13056/20000 [==================>...........] - ETA: 0s - loss: 0.0036 - acc: 0.9999
18432/20000 [==========================>...] - ETA: 0s - loss: 0.0036 - acc: 0.9999
20000/20000 [==============================] - 0s 9us/step - loss: 0.0036 - acc: 1.0000
[[-0.017548 ]
 [ 0.0040411]]
[-0.0127339]

[[ 0.4666236]] [[ 0.50258291]]

生成的图像可以直观的看出分类效果:

简单分类任务的炼丹经验

相对的,初始化方法为默认时,效果一般。初始化方法为ones时,效果极差。初始化方法均为zeros时,adadelta具有最稳定且快速的表现。