La documentation déclare:
Remarque: si le tenseur
inputs
a un rang supérieur à 2, alors il est
aplati avant la matrice initiale multiplié parw
.
Cependant, ce qui suit renvoie un tenseur de forme shape=(2, 2, 2, 400)
, comme si l'entrée n'avait pas été aplatie
tf.layers.dense(tf.placeholder(tf.float32, (2,2,2,2)), 400)
Oups, désolé, je ne voulais pas me retirer. En enquêtant en interne, j'essayais d'ajouter la personne que je pense responsable.
Donc, après enquête, on m'a dit qu'il se comportait comme tensordot, et donc le comportement et la documentation actuelle sont tous les deux corrects - et l'ingénieur à qui j'ai parlé a dit qu'ils pensaient que nous pourrions utiliser un langage plus précis mais que ce ne serait pas le cas. t aider nécessairement car le langage actuel est clair et sans ambiguïté dans son contexte. (Voir tensordot: https://docs.scipy.org/doc/numpy/reference/generated/numpy.tensordot.html)
Si vous voulez essayer de faire une pull request vous-même pour faire une reformulation, ce serait bienvenu, mais je ferme ce bogue pour le moment car nous n'allons rien faire en interne.
Ah merci, la connexion tensordot le rend plus clair.
Il semble que tf.dense
se comporte en contractant le dernier indice du tenseur d'entrée avec le premier indice du tenseur de poids. Le mot "aplatir" était déroutant, je ne sais pas ce que cela signifie ici
Exemple de jouet que j'ai créé pour moi-même pour traduire tf.dense en np.tensordot équivalent
tf.reset_default_graph()
x0 = np.ones((3, 3, 3))
w0 = np.arange(6).reshape((3, 2))
x = tf.constant(x0)
y = tf.layers.dense(x, 2)
var_dict = {v.op.name: v for v in tf.global_variables()}
assert(var_dict["dense/kernel"].get_shape() == (3, 2))
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
sess.run(tf.assign(var_dict["dense/kernel"], w0))
sess.run(tf.assign(var_dict["dense/bias"], np.zeros((2,))))
expected_y0 = np.tensordot(x0,w0,axes=[(2,),(0,)])
y0 = sess.run(y)
np.testing.assert_allclose(y0, expected_y0)
Commentaire le plus utile
Ah merci, la connexion tensordot le rend plus clair.
Il semble que
tf.dense
se comporte en contractant le dernier indice du tenseur d'entrée avec le premier indice du tenseur de poids. Le mot "aplatir" était déroutant, je ne sais pas ce que cela signifie iciExemple de jouet que j'ai créé pour moi-même pour traduire tf.dense en np.tensordot équivalent