abdulfatir / prototypical-networks-tensorflow

Tensorflow implementation of NIPS 2017 Paper "Prototypical Networks for Few-shot Learning"
132 stars 44 forks source link

I have a problem about different class querry. #4

Open wjwka opened 6 years ago

wjwka commented 6 years ago

Hi, I'm studying your code, and I notice that during the test process, the proto net is very good at recognizing a new class(which is just learned) from all the classes in training set. However, when I need it to recognize the just learned class from other unseen classes, it performs very badly.

print('Testing NEGATIVE...')
avg_acc = 0.
for epi in range(n_test_episodes):
    epi_classes = np.random.permutation(n_test_classes)[:n_test_way+1]

    wrong = epi_classes[-1] ### I changed here, to generate a third new class for test querry, it's totally unseen before

    support = np.zeros([n_test_way, n_test_shot, im_height, im_width], dtype=np.float32)
    query = np.zeros([n_test_way, n_test_query, im_height, im_width], dtype=np.float32)
    for i, epi_cls in enumerate(epi_classes[:-1]):
        selected = np.random.permutation(n_examples)[:n_test_shot + n_test_query]
        support[i] = test_dataset[epi_cls, selected[:n_test_shot]]
        query[i] = np.concatenate((test_dataset[wrong,  selected[n_test_shot:-10]], test_dataset[epi_cls,selected[-10:]]))
    support = np.expand_dims(support, axis=-1)
    query = np.expand_dims(query, axis=-1)
    labels = np.tile(np.arange(n_test_way)[:, np.newaxis], (1, n_test_query)).astype(np.uint8)
    ls, ac = sess.run([ce_loss, acc], feed_dict={x: support, q: query, y:labels})
    avg_acc += ac
    if (epi+1) % 50 == 0:
        print('[test episode {}/{}] => loss: {:.5f}, acc: {:.5f}'.format(epi+1, n_test_episodes, ls, ac))
avg_acc /= n_test_episodes
print('Average Test Accuracy: {:.5f}'.format(avg_acc))

The performance is :

Testing NEGATIVE... Average Test Accuracy: 0.54737


Please correct me if I understand it wrong. Looking forward to your reply, and thank you for your help in advance.

wjwka commented 6 years ago

Sorry I forgot the hyperparameters that I used:

TRAINING INFORMATION

n_epochs = 50 n_episodes = 100 n_way = 40 n_shot = 5 n_query = 95 h_dim = 16 z_dim = 32

n_examples = 100 im_width, im_height, channels = 48,48,1

Test information

n_test_episodes = 1 n_test_way = 2 n_test_shot = 5 n_test_query = 100-n_test_shot

I do get 1.00 accuracy using your origin testing code, queries chosen from the same supporting class. But, I think the result is understandable since it is just the way it was trained...?

In this case, do you maybe have any idea of how to solve a few shot learning problem with more than one new unseen classes? :)

jiesonshan commented 5 years ago

when test, test_support and test_query are the same number of classes, if not, you should modify emb_query ( tf.reshape(q, [ num_query_class * num_queries, im_height, im_width, channels]) )

NanYoMy commented 5 years ago

maybe the feature of the test dataset is totally different from the training set. I had try my dataset it performed well