1. ホーム
  2. tensorflow

テンソルフロー学習ノート(II): テンソル変換

2022-02-16 20:08:13
<パス

マトリクス演算

#For 2-D
#All of the reduce_... # for the whole matrix if you don't add axis
tf.reduce_sum(a, 1) #for axis1
tf.reduce_mean(a,0) # for each column mean


第2引数はaxisで、0であれば r e s [ i ] = ∑ j a [ j , i ] res[i] = \sum_{j} a[j,i]. <スパン <スパン r e s [ i ] = <スパン <スパン <スパン <スパン <スパン <スパン <スパン <スパン j <スパン a <スパン [ j , i ] すなわち、( r e s [ i ] = ∑ a [ : , i ] res[i] = \sum a[:,i]. <スパン <スパン r e s [ i ] = <スパン a <スパン [ : <スパン <スパン , i ] )、それが1であれば r e s [ i ] = ∑ j a [ i , j ] res[i] = \sum_{j} a[i,j]. <スパン <スパン r e s [ i ] = <スパン <スパン <スパン <スパン <スパン <スパン <スパン <スパン j <スパン a <スパン [ i , j ]
注:返されるのはすべて行ベクトル、(軸は数個に等しく、その次元の操作、すなわち、その次元に沿って操作し、他の次元は保持されます)。

# about concat, can be used for dimensionality reduction 3D->2D , 2D->1D
tf.concat(concat_dim, data)
#arr = np.zeros([2,3,4,5,6])
In [6]: arr2.shape
Out[6]: (2, 3, 4, 5)
In [7]: np.concatenate(arr2, 0).shape
Out[7]: (6, 4, 5) :(2*3, 4, 5)
In [9]: np.concatenate(arr2, 1).shape
Out[9]: (3, 8, 5) :(3, 2*4, 5)
#tf.concat()
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
# Concat t1, t2 with axis 0 is equivalent to concatenating the Tensor with shape=[2, 2, 3] into
#In the newly generated Tensor tensor[:2,:] represents the previous t1
#tensor[2:,:] is the previous t2
tf.concat(0, [t1, t2]) ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

# Concat t1, t2 with axis 1 is equivalent to concatenating the Tensor with shape=[2, 2, 3] into
#tensor[:,:3] represents the previous t1 in the newly generated Tensor
#tensor[:,3:] is the previous t2
tf.concat(1, [t1, t2]) ==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]


concat はリスト内のベクトルを連結すること,axis は他の次元の構造を維持したまま,その次元のデータを連結することを意味します.

#squeeze drop dimension 1's down
tf.squeeze(arr, [])
Drop the dimension 1's
arr = tf.Variable(tf.truncated_normal([3,4,1,6,1], stddev=0.1))
arr2 = tf.squeeze(arr, [2,4])
arr3 = tf.squeeze(arr) # drop the dimension so it is 1

#split
tf.split(split_dim, num_split, value, name='split')
# 'value' is a tensor with shape [5, 30]
# Split 'value' into 3 tensors along dimension 1
split0, split1, split2 = tf.split(1, 3, value)
tf.shape(split0) ==> [5, 10]

#embedding
mat = np.array([1,2,3,4,5,6,7,8,9]).reshape((3,-1))
ids = [[1,2], [0,1]]
res = tf.nn.embedding_lookup(mat, ids)
res.eval()
array([[4, 5, 6],
        [7, 8, 9]],

       [[1, 2, 3],
        [4, 5, 6]]])

# Extend dimensionality, this function is often used if you want to use the broadcast feature
# 't' is a tensor of shape [2]
# expand one dimension at a time
shape(tf.expand_dims(t, 0)) ==> [1, 2]
shape(tf.expand_dims(t, 1)) ==> [2, 1]
shape(tf.expand_dims(t, -1)) ==> [2, 1]
# 't2' is a tensor of shape [2, 3, 5]
shape(tf.expand_dims(t2, 0)) ==> [1, 2, 3, 5]
shape(tf.expand_dims(t2, 2)) ==> [2, 3, 1, 5]
shape(tf.expand_dims(t2, 3)) ==> [2, 3, 5, 1]



tf.slice(input_, begin, size, name=None)


tf.slice()

import tensorflow as tf
import numpy as np
sess = tf.InteractiveSession()
a = np.array([[1,2,3,4,5],[4,5,6,7,8],[9,10,11,12,13]])
tf.slice(a,[1,2],[-1,2]).eval()

#array([[ 6, 7],
# [11, 12]])


まずは例題から

begin

tf.slice()を理解する最良の方法は、戻り値を見ることです。今、入力の形状が[a1, a2, a3]であるとします。 size は[b1, b2, b3]です。 tf.slice() が [s1, s2, s3] ならば input[b1:b1+s1, b2:b2+s2, b3:b3+s3] の値を返します。 input[b1:b1+s1,... , bi: ,...] .
もし s i = - 1 s_i = -1 <スパン <スパン s <スパン <スパン <スパン <スパン <スパン <スパン i <スパン <スパン = <スパン <スパン - - <スパン 1 とすると、返り値は

tf.stack(values, axis=0, name='stack')

注意:input[1:2]はinput[2]を取得しません。

tf.stack()

Tensor

R次元のリストを置く R+1 に積み重ねる。 Tensor 次元 At this point res[i,:,:,::] is the i-th tensor in the original list .
形状(A,B,C)のテンソルの長さNのリストが与えられる;
if axis == 0 ならば, 出力テンソルは (N, A, B, C) の形状を持つ.

At this point res[:,i,:,:] is the i-th tensor in the original list


. もし axis == 1 ならば、出力テンソルは (A, N, B, C) の形状を持つ。

# 'x' is [1, 4]
# 'y' is [2, 5]
# 'z' is [3, 6]
stack([x, y, z]) => [[1, 4], [2, 5], [3, 6]] # Pack along first dim.
stack([x, y, z], axis=1) => [[1, 2, 3], [4, 5, 6]]

tf.pad(tensor, paddings, mode="CONSTANT", name=None)

tensor

などなど。

shape

tf.pad

tensor

  • Dn paddings : 任意 [Dn, 2] Tensor 次元
    Padding
    
  • : tensor padding[D,0]+tensor.dim_size(D)+padding[D,1] mode , CONSTANT 0 となります。
    REFLECT
    
  • : SYMMETRIC を示します。 tf.gather(params, indices, validate_indices=None, name=None) indices must be an integer tensor of any dimension (usually 0-D or 1-D). Produces an output tensor with shape indices.shape + params.shape[1:] # Scalar indices, will downscale output[:, ... , :] = params[indices, :, ... :] # Vector indices output[i, :, ... , :] = params[indices[i], :, ... :] # Higher rank indices, will raise the dimension output[i, ... , j, :, ... :] = params[indices[i, ... , j], :, ... , :] """ indices = [2, 0, 3] param[2] --> output[0] param[0] --> output[1] param[3] --> output[2] indices = [[1, 2], [2, 3]] param[1] --> output[0, 0] param[2] --> output[0, 1] param[2] --> output[1, 0] param[3] --> output[1, 1] """ tf.gather_nd( params, indices, name=None, batch_dims=0 ) indices = [[1, 2], [2, 3]] param[1, 2] --> output[0] param[2, 3] --> output[1]. # Note the difference between the comparison and tf.gather indices = [[1, 2]], [[2, 3]] param[1, 2] --> output[0, 0] param[2, 3] --> output[1, 0]. # Note the difference between the comparison and tf.gather scatter_nd( indices, updates, shape, name=None ) """ shape: the shape of the final result updates: the data source indices: where the corresponding unknown data of the data source is placed in the result """ # The documentation is so full of nonsense that it can be summarized into two equations # res[*indice[i,j,... ,z], ...] = updates[i,j,... ,z,...] # len([i,j,... ,z]) = indice.rank-1. [i,j,... ,z] denotes the original unknown. *indice[i,j,... ,z] denotes the target position! # here rank means several dimensions, a = [1,2,3], a.rank=1, b = [[1,2], [2,3], [3,4]], b.rank=2 """ indices = [ [1, 2, 3], [2, 3, 4] ] means updates[0] --> res[1, 2, 3] updates[1] --> res[2, 3, 4] indices = [[[1, 2, 3], [7, 8, 9]], [[2, 3, 4], [9, 10, 11]] ] Meaning: updates[0, 0] --> res[1, 2, 3] updates[0, 1] --> res[7, 8, 9] updates[1, 0] --> res[2, 3, 4] updates[1, 1] --> res[9, 10, 11] """ , REFLECT は反射パディングを示す。 SYMMETRIC は対称的なパディングを示す。

tf.gather()

tf.gather(params, indices, validate_indices=None, name=None)


indices must be an integer tensor of any dimension (usually 0-D or 1-D). Produces an output tensor with shape indices.shape + params.shape[1:]

# Scalar indices, will downscale
output[:, ... , :] = params[indices, :, ... :]

# Vector indices
output[i, :, ... , :] = params[indices[i], :, ... :]

# Higher rank indices, will raise the dimension
output[i, ... , j, :, ... :] = params[indices[i, ... , j], :, ... , :]
"""
indices = [2, 0, 3]
param[2] --> output[0]
param[0] --> output[1]
param[3] --> output[2]

indices = [[1, 2], [2, 3]]
param[1] --> output[0, 0]
param[2] --> output[0, 1]
param[2] --> output[1, 0]
param[3] --> output[1, 1]
"""



tf.gather_nd

tf.gather_nd(
    params, indices, name=None, batch_dims=0
)
indices = [[1, 2], [2, 3]]
param[1, 2] --> output[0]
param[2, 3] --> output[1]. # Note the difference between the comparison and tf.gather

indices = [[1, 2]], 
			[[2, 3]]
param[1, 2] --> output[0, 0]
param[2, 3] --> output[1, 0]. # Note the difference between the comparison and tf.gather


tf.scatter_nd

scatter_nd(
    indices,
    updates,
    shape,
    name=None
)
"""
shape: the shape of the final result
updates: the data source
indices: where the corresponding unknown data of the data source is placed in the result
"""
# The documentation is so full of nonsense that it can be summarized into two equations
# res[*indice[i,j,... ,z], ...] = updates[i,j,... ,z,...]
# len([i,j,... ,z]) = indice.rank-1. [i,j,... ,z] denotes the original unknown. *indice[i,j,... ,z] denotes the target position!
# here rank means several dimensions, a = [1,2,3], a.rank=1, b = [[1,2], [2,3], [3,4]], b.rank=2
"""
indices = [ [1, 2, 3],
			[2, 3, 4]	
		  ]
means 
	updates[0] --> res[1, 2, 3] 
	updates[1] --> res[2, 3, 4]

indices = [[[1, 2, 3], [7, 8, 9]],
			[[2, 3, 4], [9, 10, 11]]
		]
Meaning:
	updates[0, 0] --> res[1, 2, 3]
	updates[0, 1] --> res[7, 8, 9]
	updates[1, 0] --> res[2, 3, 4]
	updates[1, 1] --> res[9, 10, 11]
"""