0

我正在尝试实现卷积神经网络来识别脸部。问题是我想要在10节课上进行训练,并且能够在测试时间预测10节以上的课程(例如20节课)。预测脸部识别中的未知脸部

我怎么能这样做,而不影响旧文件识别的测试准确率?因为我得到的测试精度很低,有时为0.


这是我的代码。

batch_size = 16 
patch_size = 5 
depth = 16 
num_hidden = 128 
num_labels = 12 
num_channels = 1 

def reformat(dataset, labels): 
    dataset = dataset.reshape(
    (-1, IMAGE_SIZE_H, IMAGE_SIZE_W, num_channels)).astype(np.float32) 


    labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32) 

def accuracy(predictions, labels): 

    return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1)) 
     /predictions.shape[0]) 


graph = tf.Graph() 

with graph.as_default(): 

    # Input data. 

    tf_train_dataset = tf.placeholder(
    tf.float32, shape=(batch_size, IMAGE_SIZE_H, IMAGE_SIZE_W, num_channels)) 
    print("tf_train_dataset",tf_train_dataset) 
    tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels)) 
    tf_valid_dataset = tf.constant(valid_dataset) 
    tf_test_dataset = tf.constant(test_dataset) 

    layer1_weights = tf.Variable(tf.truncated_normal(
     [patch_size, patch_size, num_channels, depth], stddev=0.1)) 
    layer1_biases = tf.Variable(tf.zeros([depth])) 

    layer2_weights = tf.Variable(tf.truncated_normal(
     [patch_size, patch_size, depth, depth], stddev=0.1)) 
    layer2_biases = tf.Variable(tf.constant(1.0, shape=[depth])) 

    layer3_weights = tf.Variable(tf.truncated_normal(
     [IMAGE_SIZE_H // 16 * IMAGE_SIZE_W // 16 * depth, num_hidden], stddev=0.1)) 
    layer3_biases = tf.Variable(tf.constant(1.0, shape=[num_hidden])) 

    layer4_weights = tf.Variable(tf.truncated_normal(
     [num_hidden, num_labels], stddev=0.1)) 

    layer4_biases = tf.Variable(tf.constant(1.0, shape=[num_labels])) 

    conv_1 = tf.nn.conv2d(data, layer1_weights, [1, 2, 2, 1], padding='SAME') 
    hidden_1 = tf.nn.relu(conv_1 + layer1_biases) 
    pool_1 = tf.nn.max_pool(hidden_1,ksize = [1,2,2,1], strides= [1,2,2,1],padding ='SAME') 
    conv_2 = tf.nn.conv2d(pool_1, layer2_weights, [1, 2, 2, 1], padding='SAME') 
    hidden_2 = tf.nn.relu(conv_2 + layer2_biases) 
    pool_2 = tf.nn.max_pool(hidden_2,ksize = [1,2,2,1], strides= [1,2,2,1],padding ='SAME') 

    shape = pool_2.get_shape().as_list() 
    reshape = tf.reshape(pool_2, [shape[0], shape[1] * shape[2] * shape[3]]) 
    hidden_3 = tf.nn.relu(tf.matmul(reshape, layer3_weights) + layer3_biases) 
    return tf.matmul(hidden_3, layer4_weights) + layer4_biases 

    # Training computation. 

logits = model(tf_train_dataset) 
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits,tf_train_labels)) 


    # Optimizer. 

optimizer = tf.train.GradientDescentOptimizer(0.001).minimize(loss) 

    # Predictions for the training, validation, and test data. 

train_prediction = tf.nn.softmax(logits) 
valid_prediction = tf.nn.softmax(model(tf_valid_dataset)) 
test_prediction = tf.nn.softmax(model(tf_test_dataset)) 

num_steps = 201 

with tf.Session(graph=graph) as session: 

    tf.initialize_all_variables().run() 
    print('Initialized') 
    for step in range(num_steps): 
     offset = (step * batch_size) % (train_labels.shape[0] - batch_size) 
     batch_data = train_dataset[offset:(offset + batch_size), :, :, :] 
     batch_labels = train_labels[offset:(offset + batch_size), :] 
     feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels} 
     _, l, predictions = session.run(
     [optimizer, loss, train_prediction ], feed_dict=feed_dict) 
     if (step % 50 == 0): 
     print('Minibatch loss at step %d: %f' % (step, l)) 
     print('Minibatch accuracy: %.1f%%' % accuracy(predictions, batch_labels) 
     print('Validation accuracy: %.1f%%' % accuracy(
      valid_prediction.eval(), valid_labels)) 
    print('Test accuracy: %.1f%%' % accuracy(test_prediction.eval(), test_labels[:,0:9])) 
+0

更改测试数据不会影响训练网络,旧测试数据的准确性应该稳定。 –

+0

你怎么能预测在火车组里没有的班级? –

+0

是的,我知道如果我删除未训练的图像,它给了我一个很高的准确性,但我的项目是创建新的类,如果在训练数据集中不可用 – mido

回答

1

这是不可能的培养上一定数量的类(10所认同你)有交叉熵模型,并与不同类别(例如,用10点新的10个训练身份,对于一个测试共20个)。

您需要无论如何摆脱(大小[num_hidden, 10]的)最后SOFTMAX层的使用尺寸[num_hidden, 20]未经训练的 SOFTMAX层。

问题是这个新图层将被随机初始化,并且会产生非常糟糕的结果。


一般的解决方法来处理未知类在深度学习是构建每个输入数据(面部)的非常好的表示成(的大小num_hidden)的特征空间。这种技术被称为representation learning

想象一下,你有一个很好的特征空间,你的模型发送面孔。理论上,一个身份的所有面孔将被发送到一个干净的集群中的同一个位置。然后,您将能够运行k-means来获取身份集群或任何算法,其中包含,其中k是测试身份的数量(k=20)。


有很多种方法可以获得良好的嵌入。您可以在softmax之前获得最后一个隐藏层,甚至可以获得已经训练过的模型的最后一个隐藏层(VGGFace具有非常好的结果并可以免费获得)。

VGGFace论文中另一个有趣的想法是使用三重损失来微调嵌入。

+0

谢谢@Olivier Moindrot,可能你是对的,我已经看到链接[VGGFace],但matlab中的内容文件,我不熟悉它,我可以通过使用tensorflow使用VGG-Face CNN描述符吗? – mido