2015-12-09 50 views
9

Tensorflow có một chức năng gọi là batch_matmul nhân với các tensors chiều cao hơn. Nhưng tôi có một thời gian khó hiểu nó hoạt động như thế nào, có lẽ một phần vì tôi đang gặp khó khăn trong việc hình dung nó.Làm thế nào để tensorflow batch_matmul hoạt động?

enter image description here

Những gì tôi muốn làm là nhân một ma trận của từng lát một tensor 3D, nhưng tôi không hoàn toàn hiểu những gì hình dạng của tensor a là. Liệu z là chiều kích bên trong nhất? Điều nào sau đây là đúng?

enter image description here

tôi sẽ nhất thích đầu tiên là đúng - đó là trực quan nhất đối với tôi và dễ dàng để nhìn thấy trong .eval() đầu ra. Nhưng tôi nghi ngờ điều thứ hai là chính xác.

Tensorflow nói rằng batch_matmul thực hiện:

out[..., :, :] = matrix(x[..., :, :]) * matrix(y[..., :, :]) 

Điều đó có nghĩa gì? Điều đó có nghĩa là gì trong bối cảnh ví dụ của tôi? Cái gì đang được nhân với cái gì? Và tại sao tôi không nhận được 3D tensor theo cách tôi mong đợi?

+0

[tf.batch_matmul không còn có sẵn] (http://stackoverflow.com/a/ 43819275/1090562) –

Trả lời

18

Bạn có thể tưởng tượng nó như đang thực hiện một phép chiếu trên mỗi ví dụ huấn luyện trong lô.

Ví dụ, nếu quý vị có hai tensors với kích thước như sau:

a.shape = [100,2,5] 
b.shape = [100,5,2] 

và bạn làm một batch.matmul (a, b), đầu ra của bạn sẽ có hình dạng [100,2,2] .

100 là kích thước lô của bạn, hai thứ nguyên còn lại là kích thước của dữ liệu của bạn.

+0

Tôi cảm thấy như bạn chỉ trả lời một phần câu hỏi. Cụ thể, tại sao thứ nguyên đầu tiên của b trong ví dụ của bạn phải là 100? nếu tôi có một tensor a, đó là một loạt các ví dụ, và tôi muốn áp dụng các hoạt động sampe trên mỗi người trong số họ, tức là tôi muốn nhân mỗi người bằng b, đó là [5, 2]. Là cách duy nhất để hoàn thành điều này với một tf.tile? Và nếu không, đầu ra của batch_matmul được xác định như thế nào? –

+1

@AlexLenail: Tôi có cùng một câu hỏi chính xác - Tôi muốn nhân một tensor 3D với băng tải 2D mà không cần ốp lát rõ ràng của dây dẫn 2D. Bạn có tìm thấy câu trả lời không? – ahmadh

+0

Sử dụng cơ chế phát sóng được hỗ trợ bởi matmul –

-1

Nó chỉ đơn giản là như tách trên kích thước đầu tiên tương ứng, nhân và concat chúng trở lại. Nếu bạn muốn làm 3D bằng 2D, bạn có thể định hình lại, nhân và định hình lại nó. I E. [100, 2, 5] -> [200, 5] -> [200, 2] -> [100, 2, 2]

3

Bây giờ bạn có thể làm điều đó bằng tf.einsum, bắt đầu từ Tensorflow 0,11. 0rc0.

Thí dụ,

M1 = tf.Variable(tf.random_normal([2,3,4])) 
M2 = tf.Variable(tf.random_normal([5,4])) 
N = tf.einsum('ijk,lk->ijl',M1,M2)  

Nó sẽ nhân ma trận M2 với mỗi khung (3 khung hình) trong mỗi đợt (2 lô) trong M1.

Đầu ra là:

[array([[[ 0.80474716, -1.38590837, -0.3379252 , -1.24965811], 
     [ 2.57852983, 0.05492432, 0.23039417, -0.74263287], 
     [-2.42627382, 1.70774114, 1.19503212, 0.43006262]], 

     [[-1.04652011, -0.32753903, -1.26430523, 0.8810069 ], 
     [-0.48935518, 0.12831448, -1.30816901, -0.01271309], 
     [ 2.33260512, -1.22395933, -0.92082584, 0.48991606]]], dtype=float32), 
array([[ 1.71076882, 0.79229093, -0.58058828, -0.23246667], 
     [ 0.20446332, 1.30742455, -0.07969904, 0.9247328 ], 
     [-0.32047141, 0.66072595, -1.12330854, 0.80426538], 
     [-0.02781649, -0.29672042, 2.17819595, -0.73862702], 
     [-0.99663496, 1.3840003 , -1.39621222, 0.77119476]], dtype=float32), 
array([[[ 0.76539308, 2.77609682, -1.79906654, 0.57580602, -3.21205115], 
     [ 4.49365759, -0.10607499, -1.64613271, 0.96234947, -3.38823152], 
     [-3.59156275, 2.03910899, 0.90939498, 1.84612727, 3.44476724]], 

     [[-1.52062428, 0.27325237, 2.24773455, -3.27834225, 3.03435063], 
     [ 0.02695178, 0.16020992, 1.70085776, -2.8645196 , 2.48197317], 
     [ 3.44154787, -0.59687197, -0.12784094, -2.06931567, -2.35522676]]], dtype=float32)] 

Tôi đã xác minh, số học đúng.

+0

Chỉ là một nghi ngờ nhỏ, là 'tf.einsum()' nhanh hay chậm so với các phương thức khác như 'batch_matmul(), matmul()'? Tôi muốn thực hiện một sản phẩm tensordot trong tensorflow nhưng chỉ phương thức 'einsum()' dường như hỗ trợ nó và phần còn lại của các phương thức cần một số định dạng lại và định hình lại các thủ tục vì vậy tôi muốn biết liệu nó có hiệu quả để sử dụng 'einsum() hay không ' – pikachuchameleon

-1

Câu trả lời cho câu trả lời cụ thể này là sử dụng hàm tf.scan.

Nếu a = [5,3,2] #dimension 5 lô, với 3x2 mat trong từng lô
và b = [2,3] # một ma trận liên tục được nhân với mỗi mẫu

sau đó cho def fn (a, x): trả lại tf.matmul (x, b)

initializer = tf.Variable (tf.RANDOM_NUMBER (3,3))

h = tf.scan (fn, kết quả đầu ra, initializer)

h này sẽ lưu trữ tất cả các kết quả đầu ra.

11

Trước hết, tf.batch_matmul()removed và không còn khả dụng nữa. Bây giờ bạn cho rằng sử dụng tf.matmul():

Các đầu vào phải là ma trận (hoặc tensors cấp bậc> 2, đại diện lô ma trận), với kích thước phù hợp với bên trong, có thể sau khi chuyển vị.

Vì vậy, chúng ta hãy giả sử bạn có đoạn mã sau:

import tensorflow as tf 
batch_size, n, m, k = 10, 3, 5, 2 
A = tf.Variable(tf.random_normal(shape=(batch_size, n, m))) 
B = tf.Variable(tf.random_normal(shape=(batch_size, m, k))) 
tf.matmul(A, B) 

Bây giờ bạn sẽ nhận được một tensor của hình (batch_size, n, k). Đây là những gì đang diễn ra ở đây. Giả sử bạn có batch_size ma trận nxmbatch_size ma trận mxk. Bây giờ cho mỗi cặp bạn tính nxm X mxk, cung cấp cho bạn ma trận nxk. Bạn sẽ có batch_size trong số họ.

Chú ý rằng một cái gì đó như thế này cũng là hợp lệ:

A = tf.Variable(tf.random_normal(shape=(a, b, n, m))) 
B = tf.Variable(tf.random_normal(shape=(a, b, m, k))) 
tf.matmul(A, B) 

và sẽ cung cấp cho bạn một hình dạng (a, b, n, k)

Các vấn đề liên quan