Tensorflow 准确率99%,分类不正确-三重网络

Tensorflow 准确率99%,分类不正确-三重网络,tensorflow,conv-neural-network,Tensorflow,Conv Neural Network,我正在尝试训练一个三重网络,如图中所述 我通过计算正距离(锚定-正)小于负距离(锚定-负)的三元组,然后除以批次中的三元组总数来计算验证集的准确性 我得到了很好的结果:99%的准确率。但是,当我使用模型嵌入对图像进行分类时(我拍摄一幅未知图像,并使用欧几里德距离将其与一些标记图像进行比较),最多只有20%的结果是正确的 我做错了什么? 下面您可以找到我的详细实现 三重态世代 在生成三联体之前,我已经使用dlib对齐并裁剪了训练集和测试集(CASIA和LFW),因此每个人脸的主要元素(眼睛、眼睛

我正在尝试训练一个三重网络,如图中所述

我通过计算正距离(锚定-正)小于负距离(锚定-负)的三元组,然后除以批次中的三元组总数来计算验证集的准确性

我得到了很好的结果:99%的准确率。但是,当我使用模型嵌入对图像进行分类时(我拍摄一幅未知图像,并使用欧几里德距离将其与一些标记图像进行比较),最多只有20%的结果是正确的

我做错了什么?

下面您可以找到我的详细实现


三重态世代

在生成三联体之前,我已经使用dlib对齐并裁剪了训练集和测试集(CASIA和LFW),因此每个人脸的主要元素(眼睛、眼睛、嘴唇)的位置几乎相同

为了生成三胞胎,我随机选择了一个包含40个或更多图像的CASIA文件夹,然后我选择了40个锚,每个锚都有相应的正面图像(随机选择,但与锚不同)。然后,我为每一个锚点正对随机选择一个负数


三重态损耗

这是我的三重态损失函数:

def triplet_loss(d_pos, d_neg):

    print("d_pos "+str(d_pos))
    print("d_neg "+str(d_neg))

    margin = 0.2

    loss = tf.reduce_mean(tf.maximum(0., margin + d_pos - d_neg))


    return loss
这是我的正距离(锚定和正之间)和负距离(锚定和负之间)

变量成本是我在每一步计算的损失

    d_pos_triplet = tf.reduce_sum(tf.square(model1 - model2), 1)
    d_neg_triplet = tf.reduce_sum(tf.square(model1 - model3), 1)

    d_pos_triplet_acc = tf.sqrt(d_pos_triplet + 1e-10)
    d_neg_triplet_acc = tf.sqrt(d_neg_triplet + 1e-10)

    d_pos_triplet_test = tf.reduce_sum(tf.square(model1_test - model2_test), 1)
    d_neg_triplet_test = tf.reduce_sum(tf.square(model1_test - model3_test), 1)

    d_pos_triplet_acc_test = tf.sqrt(d_pos_triplet_test + 1e-10)
    d_neg_triplet_acc_test = tf.sqrt(d_neg_triplet_test + 1e-10)


    cost = triplet_loss(d_pos_triplet, d_neg_triplet)
    cost_test = triplet_loss(d_pos_triplet_test, d_neg_triplet_test)
然后,我一个接一个地进行嵌入并测试丢失是否为正——因为0丢失意味着网络无法学习(如facenet文章中所述,我必须选择半硬三元组)

以独立于框架的方式创建模型:

conv 3x3 (1, 64)
conv 3x3 (64,64)
max_pooling
conv 3x3 (64, 128)
conv 3x3 (128, 128)
max_pooling
conv 3x3 (128, 256)
conv 3x3 (256, 256)
conv 3x3 (256, 256)
max_pooling
conv 3x3 (256, 512)
conv 3x3 (512, 512)
conv 1x1 (512, 512)
max_pooling
conv 3x3 (256, 512)
conv 3x3 (512, 512)
conv 1x1 (512, 512)
max_pooling
fully_connected(128)
fully_connected(128)
output(128)

您的L2规范化是功能方面的,而它应该是示例方面的。

谢谢您的回答!你能提供更多的细节吗?你所说的范例智慧是什么意思?谢谢大家!@HelloLili你知道Examplar wise是什么意思吗?@AbhijitBalaji没有,但我知道我做错了什么:output=tf.nn.l2_normalize(output,0)应该是output=tf.nn.l2_normalize(output,axis=1)@HelloLili我想这就是他的意思。当L2将wrt规格化为轴=0(批处理轴)时,即为批量规格化,当沿轴=1规格化时(每个训练示例的嵌入(因为在L2规格之前有一个密集层)),则规格化为示例规格化。有道理吗?@AbhijitBalaji是的,这就是我想要的解释!谢谢
input1,input2, input3, anchor_folder_helper, anchor_photo_helper, positive_photo_helper = training.next_batch_casia(s,e) #generate complet random

            s = i * batch_size
            e = (i+1) *batch_size

        input1,input2, input3, anchor_folder_helper, anchor_photo_helper, positive_photo_helper = training.next_batch_casia(s,e) #generate complet random


        lly = 0; 

        '''counter which helps me generate the same number of triplets each batch'''

        while lly < len(input1):

            input_lly1 = input1[lly:lly+1]
            input_lly2 = input2[lly:lly+1]
            input_lly3 = input3[lly:lly+1]

            loss_value = sess.run([cost], feed_dict={x_anchor:input_lly1, x_positive:input_lly2, x_negative:input_lly3})



            while(loss_value[0]<=0):
                ''' While the generated triplet has loss 0 (which means dpos - dneg + margin < 0) I keep generating triplets. I stop when I manage to generate a semi-hard triplet. '''
                input_lly1,input_lly2, input_lly3, anchor_folder_helper, anchor_photo_helper, positive_photo_helper = training.cauta_hard_negative(anchor_folder_helper, anchor_photo_helper, positive_photo_helper)
                loss_value = sess.run([cost], feed_dict={x_anchor:input_lly1, x_positive:input_lly2, x_negative:input_lly3})

                if (loss_value[0] > 0):
                    _, loss_value, distance1_acc, distance2_acc, m1_acc, m2_acc, m3_acc  = sess.run([accum_ops, cost, d_pos_triplet_acc, d_neg_triplet_acc, model1, model2, model3], feed_dict={x_anchor:input_lly1, x_positive:input_lly2, x_negative:input_lly3})
                 tr_acc = compute_accuracy(distance1_acc, distance2_acc)

                 if math.isnan(tr_acc) and epoch != 0:
                    print('tr_acc %0.2f' % tr_acc)
                    pdb.set_trace()
                    avg_loss += loss_value
                    avg_acc +=tr_acc*100

                    contor_i = contor_i + 1

                    lly = lly + 1
def siamese_convnet(x):

    w_conv1_1 = tf.get_variable(name='w_conv1_1', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 1, 64])
    w_conv1_2 = tf.get_variable(name='w_conv1_2', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 64, 64])

    w_conv2_1 = tf.get_variable(name='w_conv2_1', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 64, 128])
    w_conv2_2 = tf.get_variable(name='w_conv2_2', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 128, 128])

    w_conv3_1 = tf.get_variable(name='w_conv3_1', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 128, 256])
    w_conv3_2 = tf.get_variable(name='w_conv3_2', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 256, 256])
    w_conv3_3 = tf.get_variable(name='w_conv3_3', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 256, 256])

    w_conv4_1 = tf.get_variable(name='w_conv4_1', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 256, 512])
    w_conv4_2 = tf.get_variable(name='w_conv4_2', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 512, 512])
    w_conv4_3 = tf.get_variable(name='w_conv4_3', initializer=tf.contrib.layers.xavier_initializer(), shape=[1, 1, 512, 512])

    w_conv5_1 = tf.get_variable(name='w_conv5_1', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 512, 512])
    w_conv5_2 = tf.get_variable(name='w_conv5_2', initializer=tf.contrib.layers.xavier_initializer(), shape=[3, 3, 512, 512])
    w_conv5_3 = tf.get_variable(name='w_conv5_3', initializer=tf.contrib.layers.xavier_initializer(), shape=[1, 1, 512, 512])

    w_fc_1 = tf.get_variable(name='w_fc_1', initializer=tf.contrib.layers.xavier_initializer(), shape=[5*5*512, 2048])
    w_fc_2 = tf.get_variable(name='w_fc_2', initializer=tf.contrib.layers.xavier_initializer(), shape=[2048, 1024])

    w_out = tf.get_variable(name='w_out', initializer=tf.contrib.layers.xavier_initializer(), shape=[1024, 128])

    bias_conv1_1 = tf.get_variable(name='bias_conv1_1', initializer=tf.constant(0.01, shape=[64]))
    bias_conv1_2 = tf.get_variable(name='bias_conv1_2', initializer=tf.constant(0.01, shape=[64]))

    bias_conv2_1 = tf.get_variable(name='bias_conv2_1', initializer=tf.constant(0.01, shape=[128]))
    bias_conv2_2 = tf.get_variable(name='bias_conv2_2', initializer=tf.constant(0.01, shape=[128]))

    bias_conv3_1 = tf.get_variable(name='bias_conv3_1', initializer=tf.constant(0.01, shape=[256]))
    bias_conv3_2 = tf.get_variable(name='bias_conv3_2', initializer=tf.constant(0.01, shape=[256]))
    bias_conv3_3 = tf.get_variable(name='bias_conv3_3', initializer=tf.constant(0.01, shape=[256]))

    bias_conv4_1 = tf.get_variable(name='bias_conv4_1', initializer=tf.constant(0.01, shape=[512]))
    bias_conv4_2 = tf.get_variable(name='bias_conv4_2', initializer=tf.constant(0.01, shape=[512]))
    bias_conv4_3 = tf.get_variable(name='bias_conv4_3', initializer=tf.constant(0.01, shape=[512]))

    bias_conv5_1 = tf.get_variable(name='bias_conv5_1', initializer=tf.constant(0.01, shape=[512]))
    bias_conv5_2 = tf.get_variable(name='bias_conv5_2', initializer=tf.constant(0.01, shape=[512]))
    bias_conv5_3 = tf.get_variable(name='bias_conv5_3', initializer=tf.constant(0.01, shape=[512]))

    bias_fc_1 = tf.get_variable(name='bias_fc_1', initializer=tf.constant(0.01, shape=[2048]))
    bias_fc_2 = tf.get_variable(name='bias_fc_2', initializer=tf.constant(0.01, shape=[1024]))

    out = tf.get_variable(name='out', initializer=tf.constant(0.01, shape=[128]))

    x = tf.reshape(x , [-1, 160, 160, 1]);

    conv1_1 = tf.nn.relu(conv2d(x, w_conv1_1) + bias_conv1_1);
    conv1_2= tf.nn.relu(conv2d(conv1_1, w_conv1_2) + bias_conv1_2);

    max_pool1 = max_pool(conv1_2);

    conv2_1 = tf.nn.relu( conv2d(max_pool1, w_conv2_1) + bias_conv2_1 );
    conv2_2 = tf.nn.relu( conv2d(conv2_1, w_conv2_2) + bias_conv2_2 );

    max_pool2 = max_pool(conv2_2)

    conv3_1 = tf.nn.relu( conv2d(max_pool2, w_conv3_1) + bias_conv3_1 );
    conv3_2 = tf.nn.relu( conv2d(conv3_1, w_conv3_2) + bias_conv3_2 );
    conv3_3 = tf.nn.relu( conv2d(conv3_2, w_conv3_3) + bias_conv3_3 );

    max_pool3 = max_pool(conv3_3)

    conv4_1 = tf.nn.relu( conv2d(max_pool3, w_conv4_1) + bias_conv4_1 );
    conv4_2 = tf.nn.relu( conv2d(conv4_1, w_conv4_2) + bias_conv4_2 );
    conv4_3 = tf.nn.relu( conv2d(conv4_2, w_conv4_3) + bias_conv4_3 );

    max_pool4 = max_pool(conv4_3)

    conv5_1 = tf.nn.relu( conv2d(max_pool4, w_conv5_1) + bias_conv5_1 );
    conv5_2 = tf.nn.relu( conv2d(conv5_1, w_conv5_2) + bias_conv5_2 );
    conv5_3 = tf.nn.relu( conv2d(conv5_2, w_conv5_3) + bias_conv5_3 );

    max_pool5 = max_pool(conv5_3)

    fc_helper = tf.reshape(max_pool5, [-1, 5*5*512]);
    fc_1 = tf.nn.relu( tf.matmul(fc_helper, w_fc_1) + bias_fc_1 );

    fc_2 = tf.nn.relu( tf.matmul(fc_1, w_fc_2) + bias_fc_2 );

    output = tf.matmul(fc_2, w_out) + out
    #output = tf.nn.l2_normalize(output, 0) THIS IS COMMENTED


    return output
conv 3x3 (1, 64)
conv 3x3 (64,64)
max_pooling
conv 3x3 (64, 128)
conv 3x3 (128, 128)
max_pooling
conv 3x3 (128, 256)
conv 3x3 (256, 256)
conv 3x3 (256, 256)
max_pooling
conv 3x3 (256, 512)
conv 3x3 (512, 512)
conv 1x1 (512, 512)
max_pooling
conv 3x3 (256, 512)
conv 3x3 (512, 512)
conv 1x1 (512, 512)
max_pooling
fully_connected(128)
fully_connected(128)
output(128)