我正在针对图像分类问题训练2个不同的CNN(自定义和转移学习)。 我为两个模型使用相同的生成器。 数据集包含5个类别的5000个样本,但不平衡。
这是我正在使用的自定义模型。
def __init__(self, transfer_learning = False, lambda_reg = 0.001, drop_out_rate = 0.1):
if(transfer_learning == False):
self.model = Sequential();
self.model.add(Conv2D(32, (3,3), input_shape = (224,224,3), activation = "relu"))
self.model.add(MaxPooling2D(pool_size = (2,2)))
self.model.add(Conv2D(64, (1,1), activation = "relu"))
self.model.add(MaxPooling2D(pool_size = (2,2)))
self.model.add(Conv2D(128, (3,3), activation = "relu"))
self.model.add(MaxPooling2D(pool_size = (2,2)))
self.model.add(Conv2D(128, (1,1), activation = "relu"))
self.model.add(MaxPooling2D(pool_size = (2,2)))
self.model.add(Flatten())
self.model.add(Dense(512))
self.model.add(Dropout(drop_out_rate))
self.model.add(Dense(256))
self.model.add(Dropout(drop_out_rate))
self.model.add(Dense(5, activation = "softmax"))
所以我无法理解steps_per_epoch
和batch_size
之间的关系。
batch_size
是生成器发送的样本数。
但是,steps_per_epoch
是完成一个训练纪元的batch_size
的数目吗?
如果是这样,则应为:steps_per_epoch = total_samples/batch_size
?
无论我尝试使用什么值,我总是遇到相同的问题(在两个模型上),val_acc
似乎达到了局部最优。
答案 0 :(得分:0)
首先,steps_per_epoch = total_samples/batch_size
总体上是正确的。
这是tensowflow编写的示例代码,如下所示:
for epoch in range(training_epochs):
avg_cost = 0
total_batch = int(mnist.train.num_examples / batch_size)
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
feed_dict = {X: batch_xs, Y: batch_ys}
c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
avg_cost += c / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning Finished!')
顺便说一句,尽管它与您的问题并不完全相关。有一些优化器,例如Stochastic Gradient Descent
和Adam
,因为学习大量数据集会花费很长时间。
它不会每次都学习所有数据。关于这方面的文章很多。在这里,我只剩下其中的one。
而且,对于您的val_acc
,您的模型似乎有很多卷积层。
您减少了卷积层的过滤器和最大缓冲量,但是,我认为这太多了。过得怎样?比以前好吗?
答案 1 :(得分:0)
您在这里混合了两个问题。一种是如何确定batch_size与steps_per_epoch;另一个是为什么val_acc似乎达到局部最优并且不会继续提高的原因。
(1)对于此问题-batch_size与steps_per_epoch
首先应该采取策略,使batch_size最大化,以达到内存允许的大小,尤其是在使用GPU(4〜11GB)时。通常,batch_size = 32或64应该没问题,但是在某些情况下,您必须减少到8、4甚至1。如果没有足够的内存来分配,训练代码将引发异常,因此您知道何时进行分配。停止增加batch_size。
一旦设置了batch_size,就可以通过Math.ceil(total_samples / batch_size)计算step_per_epoch。但是有时候,当使用数据扩充时,您可能希望将其设置大几倍。
(2)第二个问题-val_acc达到局部最优,将不会继续改进
这是深度学习的关键,不是吗?它使DL同时令人兴奋和困难。 batch_size,steps_per_epoch和时期数在这里没有多大帮助。模型和超参数(例如学习率,损失函数,优化函数等)控制模型的运行方式。
一些简单的技巧是尝试不同的学习率,不同的优化功能。如果您发现模型过度拟合(val_acc越多,历时越短),则尽可能增加样本大小总是有帮助的。数据扩充在某种程度上有所帮助。