J'essaie d'impulser cet article: http://ronan.collobert.com/pub/matos/2008_deep_icml.pdf Spécifiquement l'équation (3) de la section 2.
Je veux brièvement faire un calcul de distance par paire pour les fonctionnalités de chaque mini-lot et insérer cette perte dans la perte générale du réseau. Je n'ai que le Tesnor du lot (16 échantillons), le tenseur des étiquettes du lot et la fonction batch Tensor.
Après avoir cherché pendant un bon moment, je n'arrivais toujours pas à comprendre ce qui suit:
1) Comment diviser le lot pour les paires positives (c'est-à-dire la même étiquette) et négatives. Étant donné que le tenseur n'est pas itératif, je ne peux pas comprendre comment obtenir quel échantillon a quelle étiquette, puis diviser mon vecteur, ou obtenir quels indices du tenseur appartiennent à chaque classe.
2) Comment puis-je calculer la distance par paire pour certains des indices du tenseur de lot?
3) Je dois également définir une nouvelle fonction de distance pour les exemples négatifs
Dans l'ensemble, j'ai besoin d'obtenir quels indices appartiennent à quelle classe, faire un calcul de distace par paire positif pour toutes les paires positives. Et faites un autre calcul pour toutes les paires négatives. Ensuite, résumez le tout et ajoutez-le à la perte de réseau.
Toute aide (à l'un ou plusieurs des 3 problèmes) serait très appréciée.
1) Vous devriez faire l'échantillonnage par paire avant alimenter les données dans une session. Marquez chaque paire une étiquette booléenne, disons y = 1 pour la paire appariée, 0 sinon.
2) 3) Il suffit de calculer les deux termes pos/neg pour chaque paire, et de laisser l'étiquette 0-1 y pour choisir laquelle ajouter à la perte.
Créez d'abord des espaces réservés, y_ est pour les étiquettes booléennes.
dim = 64
x1_ = tf.placeholder('float32', shape=(None, dim))
x2_ = tf.placeholder('float32', shape=(None, dim))
y_ = tf.placeholder('uint8', shape=[None]) # uint8 for boolean
Ensuite, le tenseur de perte peut être créé par la fonction.
def loss(x1, x2, y):
# Euclidean distance between x1,x2
l2diff = tf.sqrt( tf.reduce_sum(tf.square(tf.sub(x1, x2)),
reduction_indices=1))
# you can try margin parameters
margin = tf.constant(1.)
labels = tf.to_float(y)
match_loss = tf.square(l2diff, 'match_term')
mismatch_loss = tf.maximum(0., tf.sub(margin, tf.square(l2diff)), 'mismatch_term')
# if label is 1, only match_loss will count, otherwise mismatch_loss
loss = tf.add(tf.mul(labels, match_loss), \
tf.mul((1 - labels), mismatch_loss), 'loss_add')
loss_mean = tf.reduce_mean(loss)
return loss_mean
loss_ = loss(x1_, x2_, y_)
Ensuite, alimentez vos données (générées aléatoirement par exemple):
batchsize = 4
x1 = np.random.Rand(batchsize, dim)
x2 = np.random.Rand(batchsize, dim)
y = np.array([0,1,1,0])
l = sess.run(loss_, feed_dict={x1_:x1, x2_:x2, y_:y})
Je pense que la façon la plus simple de le faire est d'échantillonner les paires hors ligne (c'est-à-dire en dehors du graphique TensorFlow).
Vous créez tf.placeholder
Pour un lot de paires avec leurs étiquettes (positives ou négatives, c'est-à-dire la même classe ou une classe différente), puis vous pouvez calculer dans TensorFlow la perte correspondante.
batch_size
Paires d'entrées et sortez les éléments batch_size
À gauche des paires de formes [batch_size, input_size]
. Vous affichez également les étiquettes des paires (positives ou négatives) de forme [batch_size,]
pairs_left = np.zeros((batch_size, input_size))
pairs_right = np.zeros((batch_size, input_size))
labels = np.zeros((batch_size, 1)) # ex: [[0.], [1.], [1.], [0.]] for batch_size=4
feed_dict
De sess.run()
pairs_left_node = tf.placeholder(tf.float32, [batch_size, input_size])
pairs_right_node = tf.placeholder(tf.float32, [batch_size, input_size])
labels_node = tf.placeholder(tf.float32, [batch_size, 1])
W = ... # shape [input_size, feature_size]
output_left = tf.matmul(pairs_left_node, W) # shape [batch_size, feature_size]
output_right = tf.matmul(pairs_right_node, W) # shape [batch_size, feature_size]
l2_loss_pairs = tf.reduce_sum(tf.square(output_left - output_right), 1)
positive_loss = l2_loss_pairs
negative_loss = tf.nn.relu(margin - l2_loss_pairs)
final_loss = tf.mul(labels_node, positive_loss) + tf.mul(1. - labels_node, negative_loss)
Et c'est tout ! Vous pouvez désormais optimiser cette perte, avec un bon échantillonnage hors ligne.