文章目录
动机
你是否有过这种感觉:
- 想通过
sklearn
里面集成的方法对keras
构造的模型进行网格搜索或者是和决策树、随机森林的模型做对比和融合,但是苦于他们的类型不一致,没办法进行共同的操作。
如果你也是这样感觉的,那么这篇文章会带你打破 keras
构建的神经网络模型和 sklearn
中继承的传统机器学习模型的壁垒,让他们更加紧密地关联
重要的 API
from keras.wrappers.scikit_learn import *
keras.wrappers.scikit_learn
就是一个专门和 sklearn 做兼容的库- 里面包含的最重要的内容:
KerasClassifier(build_fn)
KerasRegressor(build_fn)
如何使用
在这里只演示第一种 KerasClassifier(build_fn)
如何与 sklearn
进行兼容的, KerasRegressor(build_fn)
也差不多
build_fn
这个参数是一个函数,这个函数要描述你通过keras
构造网络的过程,包括了网络的编译过程,即下面的例子:
def make_model():
inputs = Input((1024,))
# x = Dense(512,activation="relu")(inputs)
# x = BatchNormalization()(x)
# x = Dropout(0.1)(x)
x = Dense(256,activation="relu")(inputs)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(128,activation="relu")(x)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(64,activation="relu")(x)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(32,activation="relu")(x)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(3,activation="softmax")(x)
model = Model(inputs,x)
model.compile(optimizer=Adam(0.001),loss=keras.losses.categorical_crossentropy,metrics=["accuracy"])
return model
model_classifier = KerasClassifier(build_fn = make_model)
model_classifier.fit(x_train,y_train,epochs=500,validation_data=(x_test,y_test))
- 注意如何
compile
的一定要写在这个函数里面; - 这是因为
sklearn
的所有estimator
(决策树,随机森林等)都只用fit, predict, score
接口,因此我们必须在fit
接口实现之前把该做的事情都做完
举一反三
- 如果你已经有这个网络的模型了,该如何加载并且用于后面的预测呢。那么就可以如下操作:当然还是把加载模型的工作定义在函数里面咯:
def make_model():
inputs = Input((1024,))
# x = Dense(512,activation="relu")(inputs)
# x = BatchNormalization()(x)
# x = Dropout(0.1)(x)
x = Dense(256,activation="relu")(inputs)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(128,activation="relu")(x)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(64,activation="relu")(x)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(32,activation="relu")(x)
x = BatchNormalization()(x)
x = Dropout(0.3)(x)
x = Dense(3,activation="softmax")(x)
model = Model(inputs,x)
model.load_weights("../../数据/medical_data/model/model.229.h5")
model.compile(optimizer=Adam(0.001),loss=keras.losses.categorical_crossentropy,metrics=["accuracy"])
return model
model_classifier = KerasClassifier(build_fn = make_model)
model_classifier.fit(x_train,y_train,epochs=0,validation_data=(x_test,y_test))
- 注意这里的
fit
中的epochs = 0
这是因为;sklearn
中的模型必须要经过fit
这一步才能进行下面的predict
和score
步骤,因此必须要fit
,但是又不能epoch>=1
因为如果这样的话,我们加载进来的参数的就会因为迭代而更新,就改变了,所以我们采取epochs=0
来完成这个部分。
如何把 KerasClassifier 当作一个 estimator
什么是 estimator
例1
- 在
sklearn
中所有用于回归和分类操作的算法,都是estimator
,比如 决策分类树、决策回归树、随机森林分类器,这些都是estimator
;一个最直观的例子就是一个随机森林分类器中可以通过n
个决策分类树进行bagging
得到最佳结果,它的参数如下:
- 这里的每个
estimator
就是建立 随机森林所需要的分类器的对象,即:每一棵不同的决策树
例2
- 当采用交叉验证进行模型的精度测试的时候,这个
estimator
就是也是一个意思,比如 决策分类树、决策回归树、随机森林分类器
神经网络模型作为 estimator
- 铺垫了这么多,当然不是废话,为了把神经网络变成一个
estimator
,我们采用了KerasClassifier
,KerasRegressor
;让我们看看怎么用 - 用法就简单多了,无非也就变成了
fit,predict,score
这么几个统一的接口了;
训练
- 上面已经说过了,这里面可以设置的参数和
estimator.fit()
略有不同,因为底层还是按照神经网络的方式进行训练的,因此可以指定:
model_classifier.fit(x_train,y_train,epochs=0,validation_data=(x_test,y_test))
测试
- 神经网络自己的接口应该是
model.evaluate()
- 但是因为转换成了
estimator
所以当然也要使用estimator
的接口啦
model_classifier.score(x_test,y_test)
predict()
- 这个其实适合原来神经网络的
predict
有很大的不同;原本model.predict(x_test)
得到的应该是一个预测的矩阵;矩阵的每一行应该是对每一个样本的n
个不同类的分类概率(在分类任务中);但是在这里因为变成了estimator
,所以predict()
的结果是一个一维的数组,每个值代表每个样本最终分类的类别。
model_classifier.predict(x_test)
大功告成
- 从此之后你就可以拿着这个
model_classifier
作为一个estimator
去使用sklearn
所有方便的评估方法啦~