скажем, у меня есть два тензора:
a=Tensor("zeros_3:0", shape=(2, 4, 5), dtype=float32)
b=Tensor("ones_3:0", shape=(2, 3, 5), dtype=float32)
как я могу объединить каждый элемент по оси 2, чтобы получить новую форму тензора (2,3,4,10)
, используя вложенную карту map_fn или другие функции tf?
вот моя версия для цикла
concat_list = []
for i in range(a.get_shape()[1]):
for j in range(b.get_shape()[1]):
concat_list.append(tf.concat([a[:, i, :], b[:, j, :]], axis=1))
есть аналогичный вопрос, использующий «новую единицу измерения», но я не знаю, как использовать tf.concat
с «новой единицей измерения».
Вы можете использовать tf.tile
и tf.expand_dims
с tf.concat
. Пример:
import tensorflow as tf
a = tf.random_normal(shape=(2,4,5),dtype=tf.float32)
b = tf.random_normal(shape=(2,3,5),dtype=tf.float32)
# your code
concat_list = []
for i in range(a.get_shape()[1]):
for j in range(b.get_shape()[1]):
concat_list.append(tf.concat([a[:, i, :], b[:, j, :]], axis=1))
# Application method
A = tf.tile(tf.expand_dims(a,axis=1),[1,b.shape[1],1,1])
B = tf.tile(tf.expand_dims(b,axis=2),[1,1,a.shape[1],1])
result = tf.concat([A,B],axis=-1)
with tf.Session() as sess:
concat_list_val,result_val = sess.run([concat_list,result])
print(concat_list_val[-1])
print(result_val.shape)
print(result_val[:,-1,-1,:])
# your result
[[ 1.0459949 1.5562199 -0.04387079 0.17898582 -1.9795663 0.988437
-0.40415847 0.8865694 -1.4764767 -0.8417388 ]
[-0.3542176 -0.3281141 0.01491702 0.91899025 -1.0651684 0.12315683
0.6555444 -0.80451876 -1.3260773 0.33680603]]
# Application result shape
(2, 3, 4, 10)
# Application result
[[ 1.0459949 1.5562199 -0.04387079 0.17898582 -1.9795663 0.988437
-0.40415847 0.8865694 -1.4764767 -0.8417388 ]
[-0.3542176 -0.3281141 0.01491702 0.91899025 -1.0651684 0.12315683
0.6555444 -0.80451876 -1.3260773 0.33680603]]
Представление
Вы можете использовать следующий код для сравнения скорости.
import datetime
...
with tf.Session() as sess:
start = datetime.datetime.now()
print('#' * 60)
for i in range(10000):
result_val = sess.run(result)
end = datetime.datetime.now()
print('cost time(seconds) : %.2f' % ((end - start).total_seconds()))
start = datetime.datetime.now()
print('#' * 60)
for i in range(10000):
concat_list_val = sess.run(concat_list)
end = datetime.datetime.now()
print('cost time(seconds) : %.2f' % ((end - start).total_seconds()))
Метод векторизации 10000 итераций занимает 1.48s
, а цикл 10000 итераций занимает 5.76s
, когда a.shape=(2,4,5)
и b.shape=(2,3,5)
в моей памяти графического процессора 8 ГБ. Но метод векторизации занимает 3.28s
, а время цикла равно 317.23s
, когда a.shape=(20,40,5)
и b.shape=(20,40,5)
.
Метод векторизации будет значительно быстрее, чем цикл tf.map_fn()
и Python.
@shizi Я добавил это в ответ.
Спасибо за ваш ответ! И еще один вопрос: Какова производительность (или эффективность) кода вашего приложения? Потому что мой код оооочень медленный на реальных данных. Спасибо еще раз!