2016-10-27 47 views
7

Hai phần của câu hỏi này:Làm thế nào để gán giá trị cho một tập con của một tensor trong tensorflow?

(1) Cách tốt nhất để cập nhật một tập con của một tensor trong tensorflow là gì? Tôi đã nhìn thấy một số câu hỏi liên quan:

Adjust Single Value within Tensor -- TensorFlowHow to update a subset of 2D tensor in Tensorflow?

và Tôi biết rằng đối tượng Biến có thể được gán sử dụng Variable.assign() (và/hoặc scatter_update, vv), nhưng nó có vẻ rất lạ với tôi rằng tensorflow không có cách trực quan hơn để cập nhật một phần của đối tượng Tensor. Tôi đã tìm kiếm thông qua các tài liệu api tensorflow và stackoverflow trong một thời gian và không thể tìm ra một giải pháp đơn giản hơn so với những gì được trình bày trong các liên kết ở trên. Điều này có vẻ đặc biệt kỳ quặc, đặc biệt là Theano có một phiên bản tương đương với Tensor.set_subtensor(). Tôi có thiếu một cái gì đó hoặc là không có cách nào đơn giản để làm điều này thông qua api tensorflow vào thời điểm này?

(2) Nếu có cách đơn giản hơn, nó có khả thi không?

Cảm ơn!

+0

Có đủ để bạn khởi tạo giá trị tensor với mảng không? Sau đó, tôi giới thiệu cách. – Jin

+4

Trong các phiên bản gần đây của Tensorflow, bạn có thể cập nhật các biến bằng cách sử dụng lát cắt giống như numpy, như sau: 'v [2: 4] .assign ([1, 2])', trong đó 'v' là' Biến '. Câu trả lời đó có đáp ứng được câu hỏi của bạn không? –

+0

Cảm ơn cả hai, đánh giá cao những suy nghĩ/ý kiến. Thật không may không phải là những gì tôi đang tìm kiếm mặc dù ... biến Cập nhật bằng cách sử dụng cắt giống như gumpy sẽ được chính xác nó, ngoại trừ đó chỉ áp dụng cho "biến" nhưng không phải là "Tensors". Tôi đã thiết kế lại mô hình của tôi để tránh nhu cầu rõ ràng cho op này, bc có vẻ như thực tế là các đối tượng Tensor hoàn toàn không thay đổi trong tf (không giống như các đối tượng biến). Cảm ơn một lần nữa cho những suy nghĩ mặc dù! – joeliven

Trả lời

0

Tôi cho rằng tính bất biến của Tensors là cần thiết để xây dựng biểu đồ tính toán; bạn không thể có một bản cập nhật Tensor một số giá trị của nó mà không trở thành một Tensor khác hoặc sẽ không có gì để đưa vào biểu đồ trước nó. The same issue comes up in Autograd.

Có thể thực hiện điều này (nhưng xấu xí) bằng cách sử dụng mặt nạ boolean (biến chúng thành các biến và sử dụng assign hoặc thậm chí xác định chúng trước khi bị sần). Điều đó có thể khác biệt, nhưng trong thực tế tôi muốn tránh phải cập nhật các subtensors.

Nếu bạn thực sự phải, và tôi thực sự hy vọng có một cách tốt hơn để làm điều này, nhưng đây là một cách để làm điều đó trong 1D sử dụng tf.dynamic_stitchtf.setdiff1d:

def set_subtensor1d(a, b, slice_a, slice_b): 
    # a[slice_a] = b[slice_b] 
    a_range = tf.range(a.shape[0]) 
    _, a_from = tf.setdiff1d(a_range, a_range[slice_a]) 
    a_to = a_from 
    b_from, b_to = tf.range(b.shape[0])[slice_b], a_range[slice_a]  
    return tf.dynamic_stitch([a_to, b_to], 
        [tf.gather(a, a_from),tf.gather(b, b_from)]) 

Đối với kích thước cao hơn này có thể được khái quát hóa bởi lạm dụng reshape (nơi nd_slice could be implemented like this nhưng có lẽ là một cách tốt hơn):

def set_subtensornd(a, b, slice_tuple_a, slice_tuple_b): 
    # a[*slice_tuple_a] = b[*slice_tuple_b] 
    a_range = tf.range(tf.reduce_prod(tf.shape(a))) 
    a_idxed = tf.reshape(a_range, tf.shape(a)) 
    a_dropped = tf.reshape(nd_slice(a_idxed, slice_tuple_a), [-1]) 
    _, a_from = tf.setdiff1d(a_range, a_dropped) 
    a_to = a_from 
    b_range = tf.range(tf.reduce_prod(tf.shape(b))) 
    b_idxed = tf.reshape(b_range, tf.shape(b)) 
    b_from = tf.reshape(nd_slice(b_idxed, slice_tuple_b), [-1]) 
    b_to = a_dropped 
    a_flat, b_flat = tf.reshape(a, [-1]), tf.reshape(b, [-1]) 
    stitched = tf.dynamic_stitch([a_to, b_to], 
        [tf.gather(a_flat, a_from),tf.gather(b_flat, b_from)]) 
    return tf.reshape(stitched, tf.shape(a)) 

tôi không có ý tưởng như thế nào chậm này sẽ được. Tôi đoán khá chậm. Và, tôi đã không thử nghiệm nó nhiều hơn ngoài việc chạy nó trên một vài tensors.

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