简单分类任务的炼丹经验
对于一些复杂的分类任务,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具有最稳定且快速的表现。