数据分析师养成之路之keras:(Modelcheckpoint,交叉验证等实现篇)
鲁鲁酱1996 2018-07-23 14:40:27 4626 收藏 4
展开
1.数据集的划分和打乱:
主要学习一下,permutation的使用方法,代码简单,这里不多讲解
data=np.load(open('/home/LLwang/桌面/wang/bottle_train.npy','rb'))
train_labels=fold1train_generator.classes
y=utils.to_categorical(train_labels,2)
permutation1=np.random.permutation(int(len(data)*0.30))
test_data=data[permutation1,:,:]
test_label=y[permutation1]
permutation2=np.random.permutation(int(len(data)*0.70))
train_data=data[permutation2,:,:]
train_label=y[permutation2]
1
2
3
4
5
6
7
8
9
2.keras中的交叉验证:
from sklearn.model_selection import StratifiedKFold,train_test_split
# cross validation
# n-fold=5
skf = StratifiedKFold(n_splits=5)
for cnt,(train,test) in enumerate(skf.split(data,lic1)):
#注意,如何取数据!当然若是df型,df.iloc[train]取值
train_data=data[train,:,:]
test_data=data[test,:,:]
train_labels=lic1
y=utils.to_categorical(train_labels,2)
y_train=y[train]
y_test=y[test]
#只输出最好的
filepath="/home/mrewang/桌面/wang/weights.best.hdf5"
#每提高一次,输出一次
#filepath='weights-improvement-{epoch:02d}-{val_acc:.2f}.hdf5'
#为保存val_acc最大时模型的权重
mc=ModelCheckpoint(filepath,monitor='val_acc',verbose=1,save_best_only=True,mode='max')
callbacks_list=[mc]
model.fit(train_data,y_train,epochs=20, batch_size=32,validation_data=(test_data,y_test),callbacks=callbacks_list)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
3.load weight
model.load_weights('/home/LLwang/桌面/wang/weights.best.hdf5')
model.compile(optimizer='...',
loss='binary_crossentropy',metrics=['accuracy'])
scores=model.evaluate(test_data,test_label,verbose=0)
print('%s:%.2f%%'%(model.metrics_names[1],scores[1]*100))
print(model.predict(test_data))
————————————————
版权声明:本文为CSDN博主「鲁鲁酱1996」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lulujiang1996/java/article/details/81167362
在keras中使用交叉验证或者网格搜索踩的坑
qq_28935065 2019-05-26 01:53:35 1629 收藏
展开
在keras中提供了sklearn的API:from keras.wrappers.scikit_learn import KerasClassifier,这个是分类的,也有回归的,具体的使用方法
1.create_model。即创建自己的模型,在keras中自己根据需要搭模型,例如
def create_model(self):
"""
:return:
"""
max_squence_len = 16
max_token_num = 2874
embedding_dim = 80
input_layer=Input(shape=[max_squence_len,])
embedding_layer=Embedding(input_dim=max_token_num, output_dim=embedding_dim)(input_layer)
convs = []
filter_sizes = [2, 3, 4]
for fs in filter_sizes:
l_conv = Conv1D(filters=50, kernel_size=fs, activation="relu")(embedding_layer)
l_pool = MaxPooling1D(pool_size=2)(l_conv)
##pool_size:池化窗口的大小,如果在文中,表示每次选择几个词也就是每次选择几行
##strides:步长,在文本中表示一次移动多少行
##padding:取值为’val’或者’same’,当取’same’时,会在进行填充,当取‘val‘不会进行填充
l_pool = Flatten()(l_pool)
##Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡
convs.append(l_pool)
merge = concatenate(convs,
axis=1) ###将所有的卷积层都连接起来,除了使用concatenate以外,还可以使用add,两者的不同在于add未改变维度,而concatenate可以理解为维度的联合
out = Dropout(0.5)(merge) ##按照一定的概率将其暂时从网络中丢弃
output = Dense(32, activation='relu')(out) ##全链接层
output = Dense(units=31, activation='softmax')(output) ##全链接输出层
model = Model([input_layer], output)
adam = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0) ##优化器
model.compile(loss="categorical_crossentropy", optimizer=adam, metrics=['accuracy'])
return model
2.定义进行调参或者交叉验证的方法,以供其他方法进行调用
def adj_para(self,x_train, y_train):
estimator=KerasClassifier(build_fn=self.create_model)
batch_size = [10, 20, 30]
epochs = [10, 50]
param_grid = dict(batch_size=batch_size, nb_epoch=epochs)
grid=GridSearchCV(estimator=estimator,param_grid=param_grid,cv=5,scoring = 'accuracy')
grid_result=grid.fit(x_train,y_train)
print("best_score:", grid_result.best_score_)
print("best_para:", grid_result.best_params_)
注意:这两个方法的定义所存在的类中,类的构造方法 def __init__(self):中,不能存在类变量 ,即在类构造方法中不能实例化其他类,否则会报TypeError: cannot deepcopy this pattern object。具体还不知道什么原因,只知道这样做不会再报深复制的错误了。如果有哪位大神知道,还希望分享
具体实例
class A(object):
def __init__(self):
self.a="aa"
def create_model(self):
"""
create model function
:return:
"""
def adj_para(self,x_train, y_train):
"""调参方法或者交叉验证方法的定义"""
上面这种方式可以,但是下面的方式不可以
class A(object):
def __init__(self):
self.a="aa"
self.objectB=B()###实例化B
def create_model(self):
"""
create model function
:return:
"""
def adj_para(self,x_train, y_train):
"""调参方法或者交叉验证方法的定义"""
————————————————
版权声明:本文为CSDN博主「qq_28935065」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_28935065/java/article/details/90557676
keras入门 ---在预训练好网络模型上进行fine-tune
CIA_agent 2017-05-15 17:10:26 15466 收藏 4
展开
在深度学习的学习过程中,我们可能会用到一些已经训练好的模型,比如 Alex Net, google net, VGG net, ResNet等,那我们怎么对这些已经训练好的模型进行fine-tune来提高准确率呢?
在这篇博客中,我们使用已经训练好的VGG16模型来帮助我们进行这个分类任务,因为我们要分类的是猫,狗这类物体,而VGG net是在imageNet上训练的,而imageNet实际上已经包含了这2中物体。
我们的方法是这样的:
首先载入VGG16的权重
接下来在初始化好的VGG网络上添加我们预训练好的模型
最后将最后一个卷积块的层数冻结,然后以很低的学习率开始训练(我们只选择最后一个卷积块进行训练,是因为训练样本很少,而VGG模型层数很多,全部训练肯定不能训练好,会过拟合。 其次fine-tune时由于是在一个已经训练好的模型上进行的,故权值更新应该是一个小范围的,以免破坏预训练好的特征)
首先构造VGG16模型:
model = Sequential()
model.add(ZeroPadding2D((1, 1), input_shape=(3, img_width, img_height)))
model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
加载VGG16训练好的权重(我们只要全连接层以前的权重):
assert os.path.exists(weights_path), 'Model weights not found (see "weights_path" variable in script).'
f = h5py.File(weights_path)
for k in range(f.attrs['nb_layers']):
if k >= len(model.layers):
# we don't look at the last (fully-connected) layers in the savefile
break
g = f['layer_{}'.format(k)]
weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
model.layers[k].set_weights(weights)
f.close()
print('Model loaded.')
1
2
3
4
5
6
7
8
9
10
11
然后在VGG16结构基础上添加一个简单的分类器及预训练好的模型:
top_model = Sequential()
top_model.add(Flatten(input_shape=model.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(1, activation='sigmoid'))
top_model.load_weights(top_model_weights_path)
# add the model on top of the convolutional base
model.add(top_model)
1
2
3
4
5
6
7
8
把随后一个卷积块前的权重设置为不训练:
for layer in model.layers[:25]:
layer.trainable = False
model.compile(loss='binary_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
1
2
3
4
5
这样一个很简单fine-tune在50个epoch后就可以达到一个大概0.94的auc.
源代码和数据库在code and dataset.
参考文档https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html.
————————————————
版权声明:本文为CSDN博主「CIA_agent」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hnu2012/java/article/details/72179437