https://blog.csdn.net/timcanby/article/details/103620371
上一篇文章我们介绍了怎么用keras写一个最简单的数字分类网络,但是可能有同学会说我怎么在不同地方看到的大家跑模型的方法都不太一样,这里笔者稍微做一个总结。
这期我们使用的结构依旧是leNet,意思就是,
model = Sequential()
model.add(Conv2D(6, kernel_size=(5, 5), strides=(1, 1), padding='same', activation='tanh', input_shape=input_shape))
model.add(AveragePooling2D((2, 2), strides=(2, 2)))
model.add(Conv2D(16, kernel_size=(5, 5), strides=(1, 1), padding='valid', activation='tanh'))
model.add(AveragePooling2D((2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(120, activation='tanh'))
model.add(Dense(84, activation='tanh'))
model.add(Dense(classNumber, activation='softmax'))
model.compile(
loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy']
)
这一个模块我们暂时忽略不计。
上一篇我们用来启动训练模型的语句是:
model.fit(x=X_train,y=Y_train, epochs=epochs, batch_size=batch_size, validation_data=(X_test, Y_test), verbose=1)
所以这里就先从挖掘着一种方法开始分析 。
首先看它的返回值:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'epoch', 'history', 'model', 'on_batch_begin', 'on_batch_end', 'on_epoch_begin', 'on_epoch_end', 'on_train_begin', 'on_train_end', 'params', 'set_model', 'set_params', 'validation_data']
个人觉得用得到的就是后面这几个 'history', 'params', 可能会被经常用到
那我们先分别看看他们是什么:
参数名 | 类型 | 作用(内容) |
history | <class 'dict'> | {'val_loss': [0.22190144285559654], 'val_acc': [0.9407999992370606], 'loss': [0.6347628879050414], 'acc': [0.8359166634579499]}(这个有几个epoch就会有几个对应的数据项) |
params | <class 'dict'> | 'batch_size': 1000, 'epochs': 2, 'steps': None, 'samples': 60000, 'verbose': 1, 'do_validation': True, 'metrics': ['loss', 'acc', 'val_loss', 'val_acc'](这个是你模型的设定) |
从上表可以看出这是一种你站在工厂外面等流水线工作完了给你个结果包的训练方法 ,这个结果包里面记载了他们一切的工作流程以及你的设置,然后用这个结果包你可以很容易使用作图工具把整个过程可视化。如果想在训练图中随时监视结果和状态的童鞋可以考虑以下的训练方法:
keras里面有train_on_batch()这个函数
train_on_batch(x, y, sample_weight=None, class_weight=None)
可以一批一批的手动train你的数据,也就是说需要你自己写一个根据batchSize划分你数据的函数,然后一批一批的喂这个函数来训练你的模型。它的返回有两个[loss,acc],每喂一个batch进去就会弹出那个batch的这两个数值。这样训练可以有个好处,就是在训练途中可以去改变赋予(改变sample_weight)损失函数的权重。class_weight是去调整Imbalanced Datasets 的一个参数。(比如你的数据每个类的数据个数是不一样的时候那就不均衡)这个东西主要看你的数据比较少的那一类,是否对你的最终需求的结果有很大的影响,https://towardsdatascience.com/handling-imbalanced-datasets-in-deep-learning-f48407a0e758 (附上浅显易懂的参考文献)对于最初级的使用方法就是比如我们想看这个训练过程动态的训练并且显示在matplotlib上。或者想要隔一几个epoch评价一把数据,或者想中途存一把模型。比如说 ,每个多少选accuracy最高的权重保存。
所以我们在前面得写一个一批一批取数据的函数:
def loadData(X,Y,batch_size):
return [X[x:x + batch_size] for x in range(0, len(X), batch_size)],[Y[y:y + batch_size] for y in range(0, len(Y), batch_size)]
我的话,是准备一批把数据和标签一起切了,然后训练数据和测试数据分开来抽,所以我写了以上这个函数,当然还可以写更简单,这里笔者偷懒了。所以设置一个batch是1000的话:
(inputs, targets) = loadData(X_train, Y_train, 1000)
这样inputs,和targets就取到了分割好的训练数据。
接下来就是按照epoch的总数来循环每一次训练啦
for i in range(1, epoch):
(inputs,targets)=loadData(X_train,Y_train,1000)
for N_iter in range(0,np.shape(inputs)[0]):
loss=model.train_on_batch(inputs[N_iter],targets[N_iter])
range(0,np.shape(inputs)[0])是按照batch大小划分后的数据的长度用N_iter从0开始去取每一个epoch,然后丢给model.train_on_batch一批一批的训练。
然后你可以设置一个几epoch评价一道的数值,写在外面 然后写我们的评价函数和保存权重的部分:
先在外部声明一个
evaluate_every =
比如说一共刷300epoch然后100就刷一遍训练数据,这个时候保存最高accuracy的权重:
if i % evaluate_every == 100:
print("evaluating")
(inputs_test, targets_test) = loadData(X_test, Y_test, 1000)
for N_iter in range(0, np.shape(inputs_test)[0]):
val_acc = model.evaluate(x=inputs_test[N_iter], y=targets_test[N_iter])
print(val_acc)
if val_acc[1] >= best:
print("saving")
model.save('weight.h5')
best=val_acc
取测试数据的方法和取训练数据一样
然后evaluate评价函数返回的第二个参数是accuracy所以我们设置一个best来对比最高的精度,然后存最高的权重。
今天更新的全部代码就到这里 :贴一个可以动态看训练的代码例子:https://github.com/timcanby/Kares__StudyNotes/blob/master/20191223.py
转载标出处,抱走源码给小星星是好少年(笔芯)