训练模型时如何验证测试集?

时间:2019-11-06 04:55:55

标签: python tensorflow

我想在训练模型时将测试集验证功能添加到我的原始代码中。我调用了训练过程中计算精度的方法,并尝试将测试集输入模型。但是,根据我自己的理解,运行了我编写的代码后,运行结果表明,验证精度要比训练集的精度高。我猜可能是我错误地将测试集放入模型中进行了一部分训练。这是现有代码的结果: 历元:0 火车acc:0.09489036验证acc:0.125

时期:1 火车acc:0.14082506验证acc:0.140625

我尝试了很多方法,例如创建两个占位符来保存测试数据集和标签。但是我觉得解决这个问题的机会不多。

self.sess = tf.Session()

 self.x = tf.placeholder(tf.float32, shape=[None, self.img_size, 
                         self.img_size, 3], name="image")
 self.y_ = tf.placeholder(tf.float32, shape=[None, 100], name="classes")

 self._build_net(self.x)

 cross_entropy = tf.losses.softmax_cross_entropy(self.y_, self.predict, 
                                     reduction=tf.losses.Reduction.MEAN)

 l2 = tf.add_n([tf.nn.l2_loss(var) for var in tf.trainable_variables()])

 self.loss = cross_entropy + l2 * 0.0001
 self.pred = tf.argmax(self.predict, axis=1)
 self.accuracy = tf.reduce_mean(tf.cast(tf.equal(self.pred, tf.argmax(self.y_, 
                                 axis=1)), tf.float32))

 self.train_op = tf.train.MomentumOptimizer(self.learning_rate, 
                                            momentum=.9).minimize(self.loss)

 #problem is here (same with self.accuracy)   
 self.val =  tf.reduce_mean(tf.cast(tf.equal(self.pred, tf.argmax(self.y_, 
                            axis=1)), tf.float32))

 define _build_net(self, batch_images):
          ...
        CNN model
          ...

 def learn(self, x_batch, y_batch):
       _, loss, accuracy = self.sess.run([self.train_op, self.loss, 
                                         self.accuracy],feed_dict={self.x: 
                                           x_batch, self.y_: y_batch})
        return loss, accuracy

 #problem is here
 def validation(self, x_test_batch, y_test_batch):
      validation = self.sess.run(self.val, feed_dict={self.x: x_test_batch, 
                                 self.y_: y_test_batch})
        return validation

我想知道为什么我做错了,并希望获得正常的测试集输出。或任何可以在我的代码中验证的建议,以在培训过程中验证测试集。 非常感谢您的帮助

2 个答案:

答案 0 :(得分:0)

我重新添加了纪元训练,发现验证准确性在超过45个纪元后没有增加。然后输出变为正确。但是尚不清楚测试集在一开始就更好的原因。

答案 1 :(得分:0)

实际上,如果使用tensorflow keras库,则可以验证火车损失并更轻松地测试。例如:model.fit_generator(train_data,epochs = nb_epochs,steps_per_epoch = nb_train_steps,validation_data =(valid_data,valid_label),其中使用tf.keras.models

创建模型

由于您是从头开始构建模型,因此应该使用来自model.fit_generator参数的直觉:“ nb_epoch”,“ train_steps”,“ batch_size”

例如,为了在训练模型时验证测试集,您可以定义:

x_train, y_train, x_test, y_test = tf.placeholder()
batch = 100  
iteration = 100000  
no_epoch = int(iteration/(len(x_train)/batch))  
train_loader = zip(x_train, label)

count = 0 # count to number of epoch

for epoch in range(no_epoch):
        for (x, labels) in train_loader:
            ### your model ###
            y_pred = model(x)
            loss = error(y_pred, labels)
            loss.backward()
            optimizer.step()

            count += 1
        if count % 50 == 0: # for ex train for 50 epoch:
            ### validation here ###
        ### you can store training history loss after 400 , 500 epochs etc ###

if __name__ == '__main__':
    ### load data, prepare x_train_batch, y_train_batch, x_test_batch, y_test_batch###
    with tf.Session() as sess:
        sess.run(feed_dict={x_train: x_train_batch, y_train: y_train_batch, x_test: x_test_batch, y_test: y_test_batch})

我使用伪代码来直观地了解在训练时使用迭代,批处理,no_epoch来验证/验证测试/有效集,因此不要尝试运行它。实际上,那是我从Pytorch的代码实现,但是Tensorflow拥有相同的直觉。

关于火车精度和验证精度的差异,有可能在训练不充分时首先进行重量初始化比预测火车更好。训练足够长时间后,如果问题仍然存在,则可能是拟合不足(偏差,方差误差)

希望这会有所帮助!