作者:chen_h
微訊號 & QQ:862251340
微信公眾號:coderpai
我的部落格:請點選這裡
計劃現將 tensorflow 中的 Python API 做一個學習,這樣方便以後的學習。
原文連結
該章介紹有關張量轉換的API
資料型別投射
Tensorflow提供了很多的資料型別投射操作,你能將資料型別投射到一個你想要的資料型別上去。
tf.string_to_number(string_tensor, out_type = None, name = None)
解釋:這個函式是將一個string
的Tensor
轉換成一個數字型別的Tensor
。但是要注意一點,如果你想轉換的數字型別是tf.float32
,那麼這個string
去掉引號之後,裡面的值必須是一個合法的浮點數,否則不能轉換。如果你想轉換的數字型別是tf.int32
,那麼這個string
去掉引號之後,裡面的值必須是一個合法的浮點數或者整型,否則不能轉換。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant(`123`)
print sess.run(data)
d = tf.string_to_number(data)
print sess.run(d)複製程式碼
輸入引數:
* string_tensor
: 一個string
型別的Tensor
。
* out_type
: 一個可選的資料型別tf.DType
,預設的是tf.float32
,但我們也可以選擇tf.int32
或者tf.float32
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別是out_type
,資料維度和string_tensor
相同。
tf.to_double(x, name = `ToDouble`)
解釋:這個函式是將一個Tensor
的資料型別轉換成float64
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant(123)
print sess.run(data)
d = tf.to_double(data)
print sess.run(d)複製程式碼
輸入引數:
* x
: 一個Tensor
或者是SparseTensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
或者SparseTensor
,資料型別是float64
,資料維度和x
相同。
提示:
* 錯誤: 如果x
是不能被轉換成float64
型別的,那麼將報錯。
tf.to_float(x, name = `ToFloat`)
解釋:這個函式是將一個Tensor
的資料型別轉換成float32
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant(123)
print sess.run(data)
d = tf.to_float(data)
print sess.run(d)複製程式碼
輸入引數:
* x
: 一個Tensor
或者是SparseTensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
或者SparseTensor
,資料型別是float32
,資料維度和x
相同。
提示:
* 錯誤: 如果x
是不能被轉換成float32
型別的,那麼將報錯。
tf.to_bfloat16(x, name = `ToBFloat16`)
解釋:這個函式是將一個Tensor
的資料型別轉換成bfloat16
。
譯者注:這個API
的作用不是很理解,但我測試了一下,輸入的x
必須是浮點型的,別的型別都不行。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([x for x in range(20)], tf.float32)
print sess.run(data)
d = tf.to_bfloat16(data)
print sess.run(d)複製程式碼
輸入引數:
* x
: 一個Tensor
或者是SparseTensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
或者SparseTensor
,資料型別是bfloat16
,資料維度和x
相同。
提示:
* 錯誤: 如果x
是不能被轉換成bfloat16
型別的,那麼將報錯。
tf.to_int32(x, name = `ToInt32`)
解釋:這個函式是將一個Tensor
的資料型別轉換成int32
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([x for x in range(20)], tf.float32)
print sess.run(data)
d = tf.to_int32(data)
print sess.run(d)複製程式碼
輸入引數:
* x
: 一個Tensor
或者是SparseTensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
或者SparseTensor
,資料型別是int32
,資料維度和x
相同。
提示:
* 錯誤: 如果x
是不能被轉換成int32
型別的,那麼將報錯。
tf.to_int64(x, name = `ToInt64`)
解釋:這個函式是將一個Tensor
的資料型別轉換成int64
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([x for x in range(20)], tf.float32)
print sess.run(data)
d = tf.to_int64(data)
print sess.run(d)複製程式碼
輸入引數:
* x
: 一個Tensor
或者是SparseTensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
或者SparseTensor
,資料型別是int64
,資料維度和x
相同。
提示:
* 錯誤: 如果x
是不能被轉換成int64
型別的,那麼將報錯。
tf.cast(x, dtype, name = None)
解釋:這個函式是將一個Tensor
或者SparseTensor
的資料型別轉換成dtype
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([x for x in range(20)], tf.float32)
print sess.run(data)
d = tf.cast(data, tf.int32)
print sess.run(d)複製程式碼
輸入引數:
* x
: 一個Tensor
或者是SparseTensor
。
* dtype
: 目標資料型別。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
或者SparseTensor
,資料維度和x
相同。
提示:
* 錯誤: 如果x
是不能被轉換成dtype
型別的,那麼將報錯。
資料維度轉換
Tensorflow提供了很多的資料維度轉換操作,你能改變資料的維度,將它變成你需要的維度。
tf.shape(input, name = None)
解釋:這個函式是返回input
的資料維度,返回的Tensor
資料維度是一維的。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])
print sess.run(data)
d = tf.shape(data)
print sess.run(d)複製程式碼
輸入引數:
* input
: 一個Tensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別是int32
。
tf.size(input, name = None)
解釋:這個函式是返回input
中一共有多少個元素。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])
print sess.run(data)
d = tf.size(data)
print sess.run(d)複製程式碼
輸入引數:
* input
: 一個Tensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別是int32
。
tf.rank(input, name = None)
解釋:這個函式是返回Tensor
的秩。
注意:Tensor
的秩和矩陣的秩是不一樣的,Tensor
的秩指的是元素維度索引的數目,這個概念也被成為order
, degree
或者ndims
。比如,一個Tensor
的維度是[1, 28, 28, 1]
,那麼它的秩就是4
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])
print sess.run(data)
d = tf.rank(data)
print sess.run(tf.shape(data))
print sess.run(d)複製程式碼
輸入引數:
* input
: 一個Tensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別是int32
。
tf.reshape(tensor, shape, name = None)
解釋:這個函式的作用是對tensor
的維度進行重新組合。給定一個tensor
,這個函式會返回資料維度是shape
的一個新的tensor
,但是tensor
裡面的元素不變。
如果shape
是一個特殊值[-1]
,那麼tensor
將會變成一個扁平的一維tensor
。
如果shape
是一個一維或者更高的tensor
,那麼輸入的tensor
將按照這個shape
進行重新組合,但是重新組合的tensor
和原來的tensor
的元素是必須相同的。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])
print sess.run(data)
print sess.run(tf.shape(data))
d = tf.reshape(data, [-1])
print sess.run(d)
d = tf.reshape(data, [3, 4])
print sess.run(d)複製程式碼
輸入引數:
* tensor
: 一個Tensor
。
* shape
: 一個Tensor
,資料型別是int32
,定義輸出資料的維度。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和輸入資料相同。
tf.squeeze(input, squeeze_dims = None, name = None)
解釋:這個函式的作用是將input
中維度是1
的那一維去掉。但是如果你不想把維度是1
的全部去掉,那麼你可以使用squeeze_dims
引數,來指定需要去掉的位置。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([[1, 2, 1], [3, 1, 1]])
print sess.run(tf.shape(data))
d_1 = tf.expand_dims(data, 0)
d_1 = tf.expand_dims(d_1, 2)
d_1 = tf.expand_dims(d_1, -1)
d_1 = tf.expand_dims(d_1, -1)
print sess.run(tf.shape(d_1))
d_2 = d_1
print sess.run(tf.shape(tf.squeeze(d_1)))
print sess.run(tf.shape(tf.squeeze(d_2, [2, 4])))
# `t` is a tensor of shape [1, 2, 1, 3, 1, 1]
# shape(squeeze(t)) ==> [2, 3]
# `t` is a tensor of shape [1, 2, 1, 3, 1, 1]
# shape(squeeze(t, [2, 4])) ==> [1, 2, 3, 1]
複製程式碼
輸入引數:
* input
: 一個Tensor
。
* squeeze_dims
: (可選)一個序列,索引從0
開始,只移除該列表中對應位的tensor
。預設下,是一個空序列[]
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和輸入資料相同。
tf.expand_dims(input, dim, name = None)
解釋:這個函式的作用是向input
中插入維度是1
的張量。
我們可以指定插入的位置dim
,dim
的索引從0
開始,dim
的值也可以是負數,從尾部開始插入,符合 python 的語法。
這個操作是非常有用的。舉個例子,如果你有一張圖片,資料維度是[height, width, channels]
,你想要加入“批量”這個資訊,那麼你可以這樣操作expand_dims(images, 0)
,那麼該圖片的維度就變成了[1, height, width, channels]
。
這個操作要求: -1-input.dims() <= dim <= input.dims()
這個操作是squeeze()
函式的相反操作,可以一起靈活運用。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([[1, 2, 1], [3, 1, 1]])
print sess.run(tf.shape(data))
d_1 = tf.expand_dims(data, 0)
print sess.run(tf.shape(d_1))
d_1 = tf.expand_dims(d_1, 2)
print sess.run(tf.shape(d_1))
d_1 = tf.expand_dims(d_1, -1)
print sess.run(tf.shape(d_1))複製程式碼
輸入引數:
* input
: 一個Tensor
。
* dim
: 一個Tensor
,資料型別是int32
,標量。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和輸入資料相同,資料和input
相同,但是維度增加了一維。
資料抽取和結合
Tensorflow提供了很多的資料抽取和結合的方法。
tf.slice(input_, begin, size, name = None)
解釋:這個函式的作用是從輸入資料input
中提取出一塊切片,切片的尺寸是size
,切片的開始位置是begin
。切片的尺寸size
表示輸出tensor
的資料維度,其中size[i]
表示在第i
維度上面的元素個數。開始位置begin
表示切片相對於輸入資料input_
的每一個偏移量,比如資料input_
是
,
[[[1, 1, 1], [2, 2, 2]],
[[33, 3, 3], [4, 4, 4]],
[[5, 5, 5], [6, 6, 6]]]begin
為[1, 0, 0]
,那麼資料的開始位置是33。因為,第一維偏移了1,其餘幾位都沒有偏移,所以開始位置是33。
操作滿足: size[i] = input.dim_size(i) - begin[i]
0 <= begin[i] <= begin[i] + size[i] <= Di for i in [0, n]
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
input = tf.constant([[[1, 1, 1], [2, 2, 2]],
[[3, 3, 3], [4, 4, 4]],
[[5, 5, 5], [6, 6, 6]]])
data = tf.slice(input, [1, 0, 0], [1, 1, 3])
print sess.run(data)
data = tf.slice(input, [1, 0, 0], [1, 2, 3])
print sess.run(data)
data = tf.slice(input, [1, 0, 0], [2, 1, 3])
print sess.run(data)
data = tf.slice(input, [1, 0, 0], [2, 2, 2])
print sess.run(data)複製程式碼
輸入引數:
* input_
: 一個Tensor
。
* begin
: 一個Tensor
,資料型別是int32
或者int64
。
* size
: 一個Tensor
,資料型別是int32
或者int64
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和input_
相同。
tf.split(split_dim, num_split, value, name = `split`)
解釋:這個函式的作用是,沿著split_dim
維度將value
切成num_split
塊。要求,num_split
必須被value.shape[split_dim]
整除,即value.shape[split_dim] % num_split == 0
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
input = tf.random_normal([5,30])
print sess.run(tf.shape(input))[0] / 5
split0, split1, split2, split3, split4 = tf.split(0, 5, input)
print sess.run(tf.shape(split0))複製程式碼
輸入引數:
* split_dim
: 一個0維的Tensor
,資料型別是int32
,該引數的作用是確定沿著哪個維度進行切割,引數範圍 [0, rank(value))
。
* num_split
: 一個0維的Tensor
,資料型別是int32
,切割的塊數量。
* value
: 一個需要切割的Tensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 從value
中切割的num_split
個Tensor
。
tf.tile(input, multiples, name = None)
解釋:這個函式的作用是通過給定的tensor
去構造一個新的tensor
。所使用的方法是將input
複製multiples
次,輸出的tensor
的第i
維有input.dims(i) * multiples[i]
個元素,input
中的元素被複制multiples[i]
次。比如,input = [a b c d], multiples = [2]
,那麼tile(input, multiples) = [a b c d a b c d]
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
data = tf.constant([[1, 2, 3, 4], [9, 8, 7, 6]])
d = tf.tile(data, [2,3])
print sess.run(d)複製程式碼
輸入引數:
* input_
: 一個Tensor
,資料維度是一維或者更高維度。
* multiples
: 一個Tensor
,資料型別是int32
,資料維度是一維,長度必須和input
的維度一樣。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和input
相同。
tf.pad(input, paddings, name = None)
解釋:這個函式的作用是向input
中按照paddings
的格式填充0
。paddings
是一個整型的Tensor
,資料維度是[n, 2]
,其中n
是input
的秩。對於input
的中的每一維D
,paddings[D, 0]
表示增加多少個0
在input
之前,paddings[D, 1]
表示增加多少個0
在input
之後。舉個例子,假設paddings = [[1, 1], [2, 2]]
和input
的資料維度是[2,2]
,那麼最後填充完之後的資料維度如下:
也就是說,最後的資料維度變成了[4,6]
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
t = tf.constant([[[3,3,],[2,2]]])
print sess.run(tf.shape(t))
paddings = tf.constant([[3,3],[1,1],[2,2]])
print sess.run(tf.pad(t, paddings)).shape複製程式碼
輸入引數:
* input
: 一個Tensor
。
* paddings
: 一個Tensor
,資料型別是int32
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和input
相同。
tf.concat(concat_dim, value, name = `concat`)
解釋:這個函式的作用是沿著concat_dim
維度,去重新串聯value
,組成一個新的tensor
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
sess = tf.Session()
t1 = tf.constant([[1, 2, 3], [4, 5, 6]])
t2 = tf.constant([[7, 8, 9], [10, 11, 12]])
d1 = tf.concat(0, [t1, t2])
d2 = tf.concat(1, [t1, t2])
print sess.run(d1)
print sess.run(tf.shape(d1))
print sess.run(d2)
print sess.run(tf.shape(d2))
# output
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
# tips
從直觀上來看,我們取的concat_dim的那一維的元素個數肯定會增加。比如,上述例子中的d1的第0維增加了,而且d1.shape[0] = t1.shape[0]+t2.shape[0]。複製程式碼
輸入引數:
* concat_dim
: 一個零維度的Tensor
,資料型別是int32
。
* values
: 一個Tensor
列表,或者一個單獨的Tensor
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個重新串聯之後的Tensor
。
tf.pack(values, name = `pack`)
解釋:這個函式的作用是將秩為R
的tensor
打包成一個秩為R+1
的tensor
。具體的公式可以表示為:
tf.pack([x, y, z]) = np.asqrray([x, y, z])複製程式碼
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
x = tf.constant([1,2,3])
y = tf.constant([4,5,6])
z = tf.constant([7,8,9])
p = tf.pack([x,y,z])
sess = tf.Session()
print sess.run(tf.shape(p))
print sess.run(p)
複製程式碼
輸入引數:
* values
: 一個Tensor
的列表,每個Tensor
必須有相同的資料型別和資料維度。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* output
: 一個打包的Tensor
,資料型別和values
相同。
tf.unpack(value, num = None, name = `unpack`)
解釋:這個函式的作用是將秩為R+1
的tensor
解壓成一些秩為R
的tensor
。其中,num
表示要解壓出來的tensor
的個數。如果,num
沒有被指定,那麼num = value.shape[0]
。如果,value.shape[0]
無法得到,那麼系統將丟擲異常ValueError
。具體的公式可以表示為:
tf.unpack(x, n) = list(x)複製程式碼
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
x = tf.constant([1,2,3])
y = tf.constant([4,5,6])
z = tf.constant([7,8,9])
p = tf.pack([x,y,z])
sess = tf.Session()
print sess.run(tf.shape(p))
pp = tf.unpack(p,3)
print sess.run(pp)
複製程式碼
輸入引數:
* value
: 一個秩大於0
的Tensor
。
* num
: 一個整型,value
的第一維度的值。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 從value
中解壓出來的一個Tensor
陣列。
異常:
* ValueError
: 如果num
沒有被正確指定,那麼將丟擲異常。
tf.reverse_sequence(input, seq_lengths, seq_dim, name = None)
解釋:將input
中的值沿著第seq_dim
維度進行翻轉。
這個操作先將input
沿著第0
維度切分,然後對於每個切片,將切片長度為seq_lengths[i]
的值,沿著第seq_dim
維度進行翻轉。
向量seq_lengths
中的值必須滿足seq_lengths[i] < input.dims[seq_dim]
,並且其長度必須是input_dims(0)
。
對於每個切片i
的輸出,我們將第seq_dim
維度的前seq_lengths[i]
的資料進行翻轉。
比如:
# Given this:
seq_dim = 1
input.dims = (4, 10, ...)
seq_lengths = [7, 2, 3, 5]
# 因為input的第0維度是4,所以先將input切分成4個切片;
# 因為seq_dim是1,所以我們按著第1維度進行翻轉。
# 因為seq_lengths[0] = 7,所以我們第一個切片只翻轉前7個值,該切片的後面的值保持不變。
# 因為seq_lengths[1] = 2,所以我們第一個切片只翻轉前2個值,該切片的後面的值保持不變。
# 因為seq_lengths[2] = 3,所以我們第一個切片只翻轉前3個值,該切片的後面的值保持不變。
# 因為seq_lengths[3] = 5,所以我們第一個切片只翻轉前5個值,該切片的後面的值保持不變。
output[0, 0:7, :, ...] = input[0, 7:0:-1, :, ...]
output[1, 0:2, :, ...] = input[1, 2:0:-1, :, ...]
output[2, 0:3, :, ...] = input[2, 3:0:-1, :, ...]
output[3, 0:5, :, ...] = input[3, 5:0:-1, :, ...]
output[0, 7:, :, ...] = input[0, 7:, :, ...]
output[1, 2:, :, ...] = input[1, 2:, :, ...]
output[2, 3:, :, ...] = input[2, 3:, :, ...]
output[3, 2:, :, ...] = input[3, 2:, :, ...]複製程式碼
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
sess = tf.Session()
input = tf.constant([[1, 2, 3, 4], [3, 4, 5, 6]], tf.int64)
seq_lengths = tf.constant([3, 2], tf.int64)
seq_dim = 1
output = tf.reverse_sequence(input, seq_lengths, seq_dim)
print sess.run(output)
sess.close()
# output
[[3 2 1 4]
[4 3 5 6]]複製程式碼
輸入引數:
* input
: 一個Tensor
,需要反轉的資料。
* seq_lengths
: 一個Tensor
,資料型別是int64
,資料長度是input.dims(0)
,並且max(seq_lengths) < input.dims(seq_dim)
。
* seq_dim
: 一個int
,確定需要翻轉的維度。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和input
相同,資料維度和input
相同。
tf.reverse(tensor, dims, name = None)
解釋:將指定維度中的資料進行翻轉。
給定一個tensor
和一個bool
型別的dims
,dims
中的值為False
或者True
。如果dims[i] == True
,那麼就將tensor
中這一維的資料進行翻轉。
tensor
最多隻能有8
個維度,並且tensor
的秩必須和dims
的長度相同,即rank(tensor) == size(dims)
。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
sess = tf.Session()
input_data = tf.constant([[
[
[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]
],
[
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]
]
]])
print `input_data shape : `, sess.run(tf.shape(input_data))
dims = tf.constant([False, False, False, True])
print sess.run(tf.reverse(input_data, dims))
print "=========================="
dims = tf.constant([False, True, False, False])
print sess.run(tf.reverse(input_data, dims))
print "=========================="
dims = tf.constant([False, False, True, False])
print sess.run(tf.reverse(input_data, dims))
sess.close()複製程式碼
輸入引數:
* tensor
: 一個Tensor
,資料型別必須是以下之一:uint8
,int8
,int32
,bool
,float32
或者float64
,資料維度不超過8
維。
* dims
: 一個Tensor
,資料型別是bool
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和tensor
相同,資料維度和tensor
相同。
tf.transpose(a, perm = None, name = `transpose`)
解釋:將a
進行轉置,並且根據perm
引數重新排列輸出維度。
輸出資料tensor
的第i
維將根據perm[i]
指定。比如,如果perm
沒有給定,那麼預設是perm = [n-1, n-2, ..., 0]
,其中rank(a) = n
。預設情況下,對於二維輸入資料,其實就是常規的矩陣轉置操作。
比如:
input_data.dims = (1, 4, 3)
perm = [1, 2, 0]
# 因為 output_data.dims[0] = input_data.dims[ perm[0] ]
# 因為 output_data.dims[1] = input_data.dims[ perm[1] ]
# 因為 output_data.dims[2] = input_data.dims[ perm[2] ]
# 所以得到 output_data.dims = (4, 3, 1)
output_data.dims = (4, 3, 1)複製程式碼
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
sess = tf.Session()
input_data = tf.constant([[1,2,3],[4,5,6]])
print sess.run(tf.transpose(input_data))
print sess.run(input_data)
print sess.run(tf.transpose(input_data, perm=[1,0]))
input_data = tf.constant([[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]])
print `input_data shape: `, sess.run(tf.shape(input_data))
output_data = tf.transpose(input_data, perm=[1, 2, 0])
print `output_data shape: `, sess.run(tf.shape(output_data))
print sess.run(output_data)
sess.close()複製程式碼
輸入引數:
* a
: 一個Tensor
。
* perm
: 一個對於a
的維度的重排列組合。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個經過翻轉的Tensor
。
tf.gather(params, indices, name = None)
解釋:根據indices
索引,從params
中取對應索引的值,然後返回。
indices
必須是一個整型的tensor
,資料維度是常量或者一維。最後輸出的資料維度是indices.shape + params.shape[1:]
。
比如:
# Scalar indices
output[:, ..., :] = params[indices, :, ... :]
# Vector indices
output[i, :, ..., :] = params[indices[i], :, ... :]
# Higher rank indices
output[i, ..., j, :, ... :] = params[indices[i, ..., j], :, ..., :]複製程式碼
如果indices
是一個從0
到params.shape[0]
的排列,即len(indices) = params.shape[0]
,那麼這個操作將把params
進行重排列。
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
sess = tf.Session()
params = tf.constant([6, 3, 4, 1, 5, 9, 10])
indices = tf.constant([2, 0, 2, 5])
output = tf.gather(params, indices)
print sess.run(output)
sess.close()複製程式碼
輸入引數:
* params
: 一個Tensor
。
* indices
: 一個Tensor
,資料型別必須是int32
或者int64
。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和params
相同。
tf.dynamic_partition(data, partitions, num_partitions, name = None)
解釋:根據從partitions
中取得的索引,將data
分割成num_partitions
份。
我們先從partitions.ndim
中取出一個元祖js
,那麼切片data[js, ...]
將成為輸出資料outputs[partitions[js]]
的一部分。我們將js
按照字典序排列,即js
裡面的值為(0, 0, ..., 1, 1, ..., 2, 2, ..., ..., num_partitions - 1, num_partitions - 1, ...)
。我們將partitions[js] = i
的值放入outputs[i]
。outputs[i]
中的第一維對應於partitions.values == i
的位置。更多細節如下:
outputs[i].shape = [sum(partitions == i)] + data.shape[partitions.ndim:]
outputs[i] = pack([data[js, ...] for js if partitions[js] == i])複製程式碼
data.shape must start with partitions.shape
這句話不是很明白,說說自己的理解。 data.shape(0)
必須和partitions.shape(0)
相同,即data.shape[0] == partitions.shape[0]
。
比如:
# Scalar partitions
partitions = 1
num_partitions = 2
data = [10, 20]
outputs[0] = [] # Empty with shape [0, 2]
outputs[1] = [[10, 20]]
# Vector partitions
partitions = [0, 0, 1, 1, 0]
num_partitions = 2
data = [10, 20, 30, 40, 50]
outputs[0] = [10, 20, 50]
outputs[1] = [30, 40]複製程式碼
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
sess = tf.Session()
params = tf.constant([6, 3, 4, 1, 5, 9, 10])
indices = tf.constant([2, 0, 2, 5])
output = tf.gather(params, indices)
print sess.run(output)
sess.close()複製程式碼
輸入引數:
* data
: 一個Tensor
。
* partitions
: 一個Tensor
,資料型別必須是int32
。任意資料維度,但其中的值必須是在範圍[0, num_partitions)
。
* num_partitions
: 一個int
,其值必須不小於1
。輸出的切片個數。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個陣列Tensor
,資料型別和data
相同。
tf.dynamic_stitch(indices, data, name = None)
解釋:這是一個交錯合併的操作,我們根據indices
中的值,將data
交錯合併,並且返回一個合併之後的tensor
。
如下構建一個合併的tensor
:
merged[indices[m][i, ..., j], ...] = data[m][i, ..., j, ...]複製程式碼
其中,m
是一個從0
開始的索引。如果indices[m]
是一個標量或者向量,那麼我們可以得到更加具體的如下推導:
# Scalar indices
merged[indices[m], ...] = data[m][...]
# Vector indices
merged[indices[m][i], ...] = data[m][i, ...]複製程式碼
從上式的推導,我們也可以看出最終合併的資料是按照索引從小到大排序的。那麼會產生兩個問題:1)假設如果一個索引同時存在indices[m][i]
和indices[n][j]
中,其中(m, i) < (n, j)
。那麼,data[n][j]
將作為最後被合併的值。2)假設索引越界了,那麼缺失的位上面的值將被隨機值給填補。
比如:
indices[0] = 6
indices[1] = [4, 1]
indices[2] = [[5, 2], [0, 3]]
data[0] = [61, 62]
data[1] = [[41, 42], [11, 12]]
data[2] = [[[51, 52], [21, 22]], [[1, 2], [31, 32]]]
merged = [[1, 2], [11, 12], [21, 22], [31, 32], [41, 42],
[51, 52], [61, 62]]複製程式碼
使用例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
sess = tf.Session()
indices = [6, [4, 1], [[5, 2], [0, 3]]]
data = [[61, 62], [[41, 42], [11, 12]], [[[51, 52], [21, 22]], [[1, 2], [31, 32]]]]
output = tf.dynamic_stitch(indices, data)
print sess.run(output)
# 缺少了第6,第7的位置,索引最後合併的資料中,這兩個位置的值會被用隨機數代替
indices = [8, [4, 1], [[5, 2], [0, 3]]]
output = tf.dynamic_stitch(indices, data)
# 第一個2被覆蓋了,最後合併的資料是第二個2所指的位置
indices = [6, [4, 1], [[5, 2], [2, 3]]]
output = tf.dynamic_stitch(indices, data)
print sess.run(output)
print sess.run(output)
sess.close()複製程式碼
輸入引數:
* indices
: 一個列表,至少包含兩Tensor
,資料型別是int32
。
* data
: 一個列表,裡面Tensor
的個數和indices
相同,並且擁有相同的資料型別。
* name
:(可選)為這個操作取一個名字。
輸出引數:
* 一個Tensor
,資料型別和data
相同。
CoderPai 是一個專注於演算法實戰的平臺,從基礎的演算法到人工智慧演算法都有設計。如果你對演算法實戰感興趣,請快快關注我們吧。加入AI實戰微信群,AI實戰QQ群,ACM演算法微信群,ACM演算法QQ群。詳情請關注 “CoderPai” 微訊號(coderpai) 。