首页 > 解决方案 > 如何修复我在验证步骤中使用的代码?

问题描述

当我训练一个 Resnet 时,洗牌验证集的准确性不等于未洗牌版本的准确性。训练集以同样的方式洗牌。

我尝试每次都使用一个样本来为网络提供数据,并在验证集中获得相同的准确性。但是,当我每次使用一批样本时,比如 256,结果是不相等的。

培训过程

count = 1 
while 1:
    
    #get training_data
    if (count - 1) % 5200 == 0:
        train_set,train_label = get_traindata(eng, 70)
        
    tset,tlabel = train_set,train_label
    tset_num = tset.shape[0]
    
    #split and train
    num_batches = tset_num // batch_size
    order = np.random.choice(tset_num, num_batches * batch_size,replace = False)
    train_data_subset = tset[order,:]
    train_labels_subset = tlabel[order]

    for step in range(num_batches):
           
        offset = step * validation_size
        feed_dict = {
                    x: train_data_subset[offset:offset+batch_size,:],
                    y: train_labels_subset[offset:offset+batch_size],
                    }
        _, tloss, tacc,gd = sess.run([train_op,loss, accuracy,grad_norm], 
                                     feed_dict=feed_dict)
        if (count-1) % 200 == 0:
            
            
            #get validationset
            if (count-1) % 1400 == 0:
                vset,vlabel = get_validata(eng, 20)
                vnum_batches = vset.shape[0] // validation_size
                order = np.random.choice(vset.shape[0], vnum_batches * validation_size,replace = False)  #shuffled
                va_data_subset = vset[order,:]
                va_labels_subset = vlabel[order]
            
            loss_list = []
            error_list = []
            loss_list_s = []
            error_list_s = []
            for stepv in range(vnum_batches):
               offsetv = stepv * validation_size
               feed_dict_shuffle = {
                    x: va_data_subset[offsetv:offsetv+validation_size,:],
                    y: va_labels_subset[offsetv:offsetv+validation_size],
                    }
               vloss_s, vacc_s = sess.run([loss, accuracy], feed_dict=feed_dict_shuffle)
               loss_list_s.append(vloss_s)
               error_list_s.append(vacc_s)
               feed_dict = {
                    x: vset[offsetv:offsetv+validation_size,:],
                    y: vlabel[offsetv:offsetv+validation_size],
                    }
               vloss, vacc = sess.run([loss, accuracy], feed_dict=feed_dict)
               loss_list.append(vloss)
               error_list.append(vacc)
            #the performance in the shuffled vali-set
            vloss_s = np.mean(loss_list_s)
            vacc_s = np.mean(error_list_s)
            #the performance in the unshuffled vali-set
            vloss = np.mean(loss_list)
            vacc = np.mean(error_list)

理论上,验证集的顺序不会影响结果。

标签: pythonvalidationtensorflowresnet

解决方案


我假设您正在使用 dropout 或批量标准化。在任何一种情况下,您都需要在推理期间将 bool tensorflow 变量提供给训练参数。由于订单似乎会影响结果,我将假设批量标准化:
https ://www.tensorflow.org/api_docs/python/tf/layers/batch_normalization 。
feed training=False 带有 tensorflow 占位符


推荐阅读