我有一個張量操作的想法,它通過迭代并不難實作,批量大小為 1。但是我想盡可能地并行化它。
我有兩個形狀為 (n, 5) 的張量,稱為 X 和 Y。X 實際上應該表示 5 個形狀為 (n, 1): (x_1, ..., x_n) 的一維張量。Y 同上。
我想計算一個形狀為 (n, 25) 的張量,其中每一列代表張量操作 f(x_i, y_j) 的輸出,其中 f 對于所有 1 <= i, j <= 5 都是固定的。操作 f具有輸出形狀 (n, 1),就像 x_i 和 y_i。
我覺得有必要澄清 f 本質上是一個完全連接的層,從形狀為 (1, 10) 的串聯 [...x_i, ...y_i] 張量到形狀為 (1,5) 的輸出層.
同樣,很容易看到如何通過迭代和切片手動執行此操作。但是,這可能非常緩慢。分批執行此操作,其中張量 X、Y 現在具有形狀 (n, 5, batch_size) 也是可取的,特別是對于小批量梯度下降。
在這里很難說清楚我為什么想要創建這個網路。我覺得它適合我的“逐項表格資料”領域,并且與完全連接的網路相比,顯著減少了每次操作的權重數量。
這可以使用張量流嗎?當然不只是使用 keras。下面是每個 AloneTogether 請求的 numpy 示例
import numpy as np
features = 16
batch_size = 256
X_batch = np.random.random((features, 5, batch_size))
Y_batch = np.random.random((features, 5, batch_size))
# one tensor operation to reduce weights in this custom 'layer'
f = np.random.random((features, 2 * features))
for b in range(batch_size):
X = X_batch[:, :, b]
Y = Y_batch[:, :, b]
for i in range(5):
x_i = X[:, i:i 1]
for j in range(5):
y_j = Y[:, j:j 1]
x_i_y_j = np.concatenate([x_i, y_j], axis=0)
# f(x_i, y_j)
# implemented by a fully-connected layer
f_i_j = np.matmul(f, x_i_y_j)
uj5u.com熱心網友回復:
您需要的所有操作(連接和矩陣乘法)都可以批處理。這里的困難部分是,您希望將 X 中所有專案的特征與 Y 中所有專案的特征(所有組合)連接起來。我推薦的解決方案是將 X 的尺寸[batch, features, 5, 1]擴展到 ,將 Y 的尺寸擴展到[batch, features, 1, 5]
比tf.repeat()兩個張量,使它們的形狀變為[batch, features, 5, 5]。現在您可以連接 X 和 Y。您將擁有一個 shape 的張量[batch, 2*features, 5, 5]。請注意,以這種方式構建所有組合。下一步是矩陣乘法。tf.matmul()也可以做批量矩陣乘法,但我在這里使用tf.einsum()是因為我想更多地控制哪些維度被視為批量。完整代碼:
import tensorflow as tf
import numpy as np
batch_size=3
features=6
items=5
x = np.random.uniform(size=[batch_size,features,items])
y = np.random.uniform(size=[batch_size,features,items])
f = np.random.uniform(size=[2*features,features])
x_reps= tf.repeat(x[:,:,:,tf.newaxis], items, axis=3)
y_reps= tf.repeat(y[:,:,tf.newaxis,:], items, axis=2)
xy_conc = tf.concat([x_reps,y_reps], axis=1)
f_i_j = tf.einsum("bfij, fg->bgij", xy_conc,f)
f_i_j = tf.reshape(f_i_j , [batch_size,features,items*items])
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/452263.html
