Bagaimana cara melakukan batch product dalam Tensorflow?


10

Jawaban:


9

Tidak ada .dot_productmetode asli . Namun, produk titik antara dua vektor hanyalah elemen-bijaksana dikalikan, jadi contoh berikut berfungsi:

import tensorflow as tf

# Arbitrarity, we'll use placeholders and allow batch size to vary,
# but fix vector dimensions.
# You can change this as you see fit
a = tf.placeholder(tf.float32, shape=(None, 3))
b = tf.placeholder(tf.float32, shape=(None, 3))

c = tf.reduce_sum( tf.multiply( a, b ), 1, keep_dims=True )

with tf.Session() as session:
    print( c.eval(
        feed_dict={ a: [[1,2,3],[4,5,6]], b: [[2,3,4],[5,6,7]] }
    ) )

Outputnya adalah:

[[ 20.]
 [ 92.]]

Ini memecahkan masalah saya, terima kasih!
— HenrySky


1
Tampaknya tidak ada yang lebih disukai pengembang TF daripada mengubah API ...
— Emre


@sajedzarrinpour Terima kasih. Saya harap itu muncul beberapa waktu antara 2016 dan sekarang? Akan menyesuaikan jawaban saya dengan tepat
— Neil Slater

6

Pilihan lain yang patut dicoba adalah [tf.einsum][1]- ini pada dasarnya versi sederhana dari Notasi Einstein .

Mengikuti bersama dengan contoh Neil dan Dumkar:

import tensorflow as tf

a = tf.placeholder(tf.float32, shape=(None, 3))
b = tf.placeholder(tf.float32, shape=(None, 3))

c = tf.einsum('ij,ij->i', a, b)

with tf.Session() as session:
    print( c.eval(
        feed_dict={ a: [[1,2,3],[4,5,6]], b: [[2,3,4],[5,6,7]] }
    ) )

Argumen pertama einsumadalah persamaan yang mewakili sumbu yang akan dikalikan dan dijumlahkan. Aturan dasar untuk persamaan adalah:

  1. Input-tensor dijelaskan oleh string dimensi-label yang dipisahkan koma
  2. Label yang berulang menunjukkan bahwa dimensi yang sesuai akan dikalikan
  3. Output-tensor dijelaskan oleh string label dimensi lain yang mewakili input (atau produk) yang sesuai
  4. Label yang hilang dari string keluaran dijumlahkan

Dalam kasus kami, ij,ij->iberarti bahwa input kami akan menjadi 2 matriks dengan bentuk yang sama (i,j), dan output kami akan menjadi vektor bentuk (i,).

Setelah Anda menguasainya, Anda akan menemukan bahwa einsummenyamaratakan sejumlah besar operasi lain:

X = [[1, 2]]
Y = [[3, 4], [5, 6]]

einsum('ab->ba', X) == [[1],[2]]   # transpose
einsum('ab->a',  X) ==  [3]        # sum over last dimension
einsum('ab->',   X) ==   3         # sum over both dimensions

einsum('ab,bc->ac',  X, Y) == [[13,16]]          # matrix multiply
einsum('ab,bc->abc', X, Y) == [[[3,4],[10,12]]]  # multiply and broadcast

Sayangnya, einsummengambil hit kinerja yang lumayan besar jika dibandingkan dengan + mengalikan manual. Di mana kinerja sangat penting, saya pasti akan merekomendasikan tetap dengan solusi Neil.


3

Mengambil diagonal tf.tensordot juga melakukan apa yang Anda inginkan, jika Anda menetapkan sumbu ke misalnya

[[1], [1]]

Saya telah mengadaptasi contoh Neil Slater:

import tensorflow as tf

# Arbitrarity, we'll use placeholders and allow batch size to vary,
# but fix vector dimensions.
# You can change this as you see fit
a = tf.placeholder(tf.float32, shape=(None, 3))
b = tf.placeholder(tf.float32, shape=(None, 3))

c = tf.diag_part(tf.tensordot( a, b, axes=[[1],[1]]))

with tf.Session() as session:
    print( c.eval(
        feed_dict={ a: [[1,2,3],[4,5,6]], b: [[2,3,4],[5,6,7]] }
    ) )

yang sekarang juga memberi:

[ 20.  92.]

Ini mungkin suboptimal untuk matriks besar (lihat diskusi di sini )


1
Pawai kemajuan :-), saya tidak yakin versi API mana ini ditambahkan? Saya sarankan perluas jawaban Anda dengan contoh singkat (mungkin berdasarkan pada milik saya, tetapi harus lebih sederhana, karena tidak perlu reduce_sum)
— Neil Slater

Saya menambahkan contoh! Sebenarnya itu juga memberikan dot-produk off-diagonal jika Anda tidak menggunakan tf.diag_part, jadi jawaban Anda mungkin akan lebih cepat. Tidak begitu yakin di mana versi API tf.tensordot diperkenalkan, tetapi mungkin sudah lama sejak itu juga tersedia di numpy.
— dumkar

Tidakkah ini membutuhkan lebih banyak memori daripada elemen-bijak melipatgandakan dan menjumlahkan?
— kbrose
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.