TensorFlow の基本: Tensor、形状、型、セッション、 Operaトー

テンソルとは何ですか?

Tensorflow の名前は、そのコア フレームワークである Tensor に直接由来しています。 Tensorflow では、すべての計算にテンソルが含まれます。 テンソルは、あらゆる種類のデータを表す n 次元のベクトルまたは行列です。 テンソル内のすべての値は、既知の (または部分的に既知の) 形状を持つ同一のデータ型を保持します。 データの形状は、行列または配列の次元です。

テンソルは、入力データまたは計算結果から生成されます。TensorFlow では、すべての操作はグラフ内で実行されます。グラフは、連続して実行される計算のセットです。各操作は op ノードと呼ばれ、互いに接続されています。

グラフには、オペレーションとノード間の接続の概要が表示されます。ただし、値は表示されません。ノードのエッジはテンソル、つまりオペレーションにデータを入力する方法です。

機械学習では、モデルに特徴ベクトルと呼ばれるオブジェクトのリストがフィードされます。特徴ベクトルは任意のデータ型にすることができます。特徴ベクトルは通常、テンソルを設定するための主な入力になります。これらの値はテンソルを介してオペレーション ノードに流れ込み、このオペレーション/計算の結果によって新しいテンソルが作成され、それが新しいオペレーションで使用されます。これらのオペレーションはすべてグラフで表示できます。

テンソルの表現

TensorFlow では、テンソルは n 次元の特徴ベクトル (つまり、配列) のコレクションです。 たとえば、2 から 3 までの値を持つ 1×6 行列がある場合、次のように書きます。

テンソルの表現
テンソルの表現

TensorFlow は、この行列を次のように表します。

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

1 から 8 までの値を持つ XNUMX 次元行列を作成すると、次のようになります。

テンソルの表現

TensorFlow は、この行列を次のように表します。

[ [[1, 2],  
       [[3, 4],  
       [[5, 6],  
       [[7,8] ]

ご注意: テンソルはスカラーで表すことも、XNUMX 次元を超える形状を持つこともできます。 高次元レベルを視覚化するのはさらに複雑です。

テンソルの種類

TensorFlow では、すべての計算が XNUMX つ以上のテンソルを通過します。 tf.tensor は XNUMX つのプロパティを持つオブジェクトです。

  • ユニークなラベル(名前)
  • 寸法(形状)
  • データ型 (dtype)

TensorFlow で行う各操作には、テンソルの操作が含まれます。作成できる主なテンソルの種類は次の 4 つです。

  • tf.変数
  • tf.定数
  • tf.プレースホルダー
  • tf.SparseTensor

このチュートリアルでは、tf.constant と tf.Variable を作成する方法を学びます。

チュートリアルを進める前に、TensorFlow を使用して conda 環境をアクティブ化していることを確認してください。 この環境を hello-tf と名付けました。

MacOS ユーザーの場合:

source activate hello-tf

Windows ユーザー:

activate hello-tf

それが完了したら、tensorflow をインポートする準備が整います。

# Import tf
import tensorflow as tf

n 次元のテンソルを作成する

まず、XNUMX 次元のテンソル、つまりスカラーの作成から始めます。

テンソルを作成するには、以下の TensorFlow テンソル形状の例に示すように tf.constant() を使用できます。

tf.constant(value, dtype, name = "")
arguments

- `value`: Value of n dimension to define the tensor. Optional
- `dtype`: Define the type of data:    
    - `tf.string`: String variable    
    - `tf.float32`: Float variable    
    - `tf.int16`: Integer variable
- "name": Name of the tensor. Optional. By default, `Const_1:0`

次元0のテンソルを作成するには、次のコードを実行します。

## rank 0
# Default name
r1 = tf.constant(1, tf.int16) 
print(r1)			

出力

Tensor("Const:0", shape=(), dtype=int16)

n次元のテンソルを作成する

# Named my_scalar
r2 = tf.constant(1, tf.int16, name = "my_scalar") 
print(r2)

出力

Tensor("my_scalar:0", shape=(), dtype=int16)

各テンソルはテンソル名で表示されます。各テンソル オブジェクトは、一意のラベル (名前)、次元 (形状)、TensorFlow データ型 (dtype) などのテンソル属性で定義されます。

データのタイプを変更することで、XNUMX 進数値または文字列を使用してテンソルを定義できます。

# Decimal
r1_decimal = tf.constant(1.12345, tf.float32)
print(r1_decimal)
# String
r1_string = tf.constant("Guru99", tf.string)
print(r1_string)

出力

Tensor("Const_1:0", shape=(), dtype=float32)
Tensor("Const_2:0", shape=(), dtype=string)

次元 1 のテンソルは次のように作成できます。

## Rank 1r1_vector = tf.constant([1,3,5], tf.int16)
print(r1_vector)
r2_boolean = tf.constant([True, True, False], tf.bool)
print(r2_boolean)

出力

Tensor("Const_3:0", shape=(3,), dtype=int16)
Tensor("Const_4:0", shape=(3,), dtype=bool)

TensorFlow シェイプが 1 つの列のみで構成されていることがわかります。

2次元テンソル配列を作成するには、各行の後に括弧を閉じる必要があります。以下のKerasテンソル形状の例を確認してください。

## Rank 2
r2_matrix = tf.constant([ [1, 2],
                          [3, 4] ],tf.int16)
print(r2_matrix)

出力

Tensor("Const_5:0", shape=(2, 2), dtype=int16)

この行列には、値 2、2、1、2 が入った 3 行 4 列があります。

括弧を使用して別のレベルを追加することで、3 次元のマトリックスが構築されます。

## Rank 3
r3_matrix = tf.constant([ [[1, 2],
                           [3, 4], 
                           [5, 6]] ], tf.int16)
print(r3_matrix)

出力

Tensor("Const_6:0", shape=(1, 3, 2), dtype=int16)

マトリックスは写真 XNUMX のようになります。

テンソルの形状

tensor を出力すると、TensorFlow は形状を推測します。 ただし、TensorFlow 形状プロパティを使用してテンソルの形状を取得できます。

以下では、10 から 15 までの数字で満たされた行列を構築し、m_shape の形状を確認します。

# Shape of tensor
m_shape = tf.constant([ [10, 11],
                        [12, 13],
                        [14, 15] ]                      
                     ) 
m_shape.shape

出力

TensorShape([Dimension(3), Dimension(2)])

マトリックスには 3 行 2 列があります。

TensorFlow には、0 または 1 で満たされたベクトルまたは行列を作成する便利なコマンドがあります。たとえば、1 で満たされた特定の形状 10 を持つ 0 次元テンソルを作成したい場合は、以下のコードを実行できます。

# Create a vector of 0
print(tf.zeros(10))

出力

Tensor("zeros:0", shape=(10,), dtype=float32)

このプロパティは行列に対しても機能します。 ここでは、10 で満たされた 10×1 行列を作成します。

# Create a vector of 1
print(tf.ones([10, 10]))

出力

Tensor("ones:0", shape=(10, 10), dtype=float32)

与えられた行列の形状を使用して、3 のベクトルを作成できます。行列 m_shape は 2×3 次元です。次のコードを使用して、XNUMX で埋められた XNUMX 行のテンソルを作成できます。

# Create a vector of ones with the same number of rows as m_shape
print(tf.ones(m_shape.shape[0]))

出力

Tensor("ones_1:0", shape=(3,), dtype=float32)

値 1 を括弧に渡すと、行列 m_shape の列数に等しい XNUMX のベクトルを構築できます。

# Create a vector of ones with the same number of column as m_shape
print(tf.ones(m_shape.shape[1]))

出力

Tensor("ones_2:0", shape=(2,), dtype=float32)

最後に、3 だけを使用して行列 2×XNUMX を作成できます。

print(tf.ones(m_shape.shape))

出力

Tensor("ones_3:0", shape=(3, 2), dtype=float32)

データの種類

テンソルの XNUMX 番目のプロパティはデータのタイプです。 テンソルは一度に XNUMX 種類のデータのみを持つことができます。 テンソルは XNUMX 種類のデータのみを持つことができます。 dtype プロパティを使用して型を返すことができます。

print(m_shape.dtype)

出力

<dtype: 'int32'>

場合によっては、データの種類を変更したいことがあります。 TensorFlowではtf.castメソッドで可能です。

以下では、メソッド Cast を使用して浮動小数点テンソルを整数に変換します。

# Change type of data
type_float = tf.constant(3.123456789, tf.float32)
type_int = tf.cast(type_float, dtype=tf.int32)
print(type_float.dtype)
print(type_int.dtype)

出力

<dtype: 'float32'>
<dtype: 'int32'>

TensorFlow は、テンソルの作成中に引数が指定されていない場合、データのタイプを自動的に選択します。 TensorFlow は、最も可能性の高いデータのタイプを推測します。 たとえば、テキストを渡すと、それが文字列であると推測され、文字列に変換されます。

オペレータの作成

便利なTensorFlow演算子

TensorFlow を使用してテンソルを作成する方法はわかりました。次は、数学演算を実行する方法を学びましょう。

TensorFlow には基本的な操作がすべて含まれています。まずは簡単なものから始めましょう。TensorFlow メソッドを使用して、数値の二乗を計算します。テンソルの構築に必要な引数は 1 つだけなので、この操作は簡単です。

数値の XNUMX 乗は、x を浮動小数点数として tf.sqrt(x) で構築されます。

x = tf.constant([2.0], dtype = tf.float32)
print(tf.sqrt(x))

出力

Tensor("Sqrt:0", shape=(1,), dtype=float32)

ご注意: 出力は 2 の XNUMX 乗の結果ではなく、テンソル オブジェクトを返しました。この例では、テンソルの定義を出力しており、演算の実際の評価は出力していません。次のセクションでは、TensorFlow がどのように演算を実行するかを学習します。

以下は、よく使用される操作のリストです。考え方は同じです。各操作には、1 つ以上の引数が必要です。

  • tf.add(a, b)
  • tf.substract(a, b)
  • tf.multiply(a, b)
  • tf.div(a, b)
  • tf.pow(a, b)
  • tf.exp(a)
  • tf.sqrt(a)

# Add
tensor_a = tf.constant([[1,2]], dtype = tf.int32)
tensor_b = tf.constant([[3, 4]], dtype = tf.int32)

tensor_add = tf.add(tensor_a, tensor_b)print(tensor_add)

出力

Tensor("Add:0", shape=(1, 2), dtype=int32)

コードの説明

XNUMX つのテンソルを作成します。

  • 1 と 2 を持つ XNUMX つのテンソル
  • 3 と 4 を持つ XNUMX つのテンソル

両方のテンソルを合計します。

通知: 両方のテンソルが同じ形状である必要があるということです。 XNUMX つのテンソルに対して乗算を実行できます。

# Multiply
tensor_multiply = tf.multiply(tensor_a, tensor_b)
print(tensor_multiply)

出力

Tensor("Mul:0", shape=(1, 2), dtype=int32)

Variables

これまでのところ、定数テンソルのみを作成しました。 あまり役に立ちません。 データは常に異なる値で到着します。これを取得するには、Variable クラスを使用します。 これは値が常に変化するノードを表します。

変数を作成するには、 tf.get_variable() メソッドを使用できます。

tf.get_variable(name = "", values, dtype, initializer)
argument
- `name = ""`: Name of the variable
- `values`: Dimension of the tensor
- `dtype`: Type of data. Optional
- `initializer`: How to initialize the tensor. Optional
If initializer is specified, there is no need to include the `values` as the shape of `initializer` is used.

たとえば、以下のコードは XNUMX つのランダムな値を持つ XNUMX 次元変数を作成します。 デフォルトでは、TensorFlow はランダムな値を返します。 変数に var という名前を付けます

# Create a Variable
## Create 2 Randomized values
var = tf.get_variable("var", [1, 2])
print(var.shape)

出力

(1, 2)

1,2 番目の例では、XNUMX 行 XNUMX 列の変数を作成します。 変数の次元を作成するには [XNUMX] を使用する必要があります

このテンソルの初期値はゼロです。 たとえば、モデルをトレーニングするときは、特徴の重みを計算するための初期値が必要です。 以下では、これらの初期値をゼロに設定します。

var_init_1 = tf.get_variable("var_init_1", [1, 2], dtype=tf.int32,  initializer=tf.zeros_initializer)
print(var_init_1.shape)

出力

(1, 2)

定数テンソルの値を変数に渡すことができます。 メソッド tf.constant() を使用して定数テンソルを作成します。 このテンソルを使用して変数を初期化します。

変数の最初の値は 10、20、30、および 40 です。新しいテンソルの形状は 2×2 になります。

# Create a 2x2 matrixtensor_const = tf.constant([[10, 20],
[30, 40]])
# Initialize the first value of the tensor equals to tensor_const
var_init_2 = tf.get_variable("var_init_2", dtype=tf.int32,  initializer=tensor_const)
print(var_init_2.shape)

出力

(2, 2)

プレースホルダー

プレースホルダーには、テンソルを供給する目的があります。 プレースホルダーは、テンソル内で流れるデータを初期化するために使用されます。 プレースホルダーを指定するには、メソッド feed_dict を使用する必要があります。 プレースホルダーはセッション内でのみフィードされます。

次の例では、tf.placeholder メソッドを使用してプレースホルダーを作成する方法を示します。 次のセッションでは、プレースホルダーに実際のテンソル値を与える方法を学びます。

構文は次のとおりです。

tf.placeholder(dtype,shape=None,name=None )
arguments:
- `dtype`: Type of data
- `shape`: dimension of the placeholder. Optional. By default, shape of the data
- `name`: Name of the placeholder. Optional			
data_placeholder_a = tf.placeholder(tf.float32, name = "data_placeholder_a")
print(data_placeholder_a)

出力

Tensor("data_placeholder_a:0", dtype=float32)

セッションを開く

TensorFlow は 3 つの主要コンポーネントを中心に動作します。

  • グラフ
  • テンソル
  • セッションを開く
コンポーネント 説明
グラフ グラフは TensorFlow の基本です。すべての数学演算 (ops) はグラフ内で実行されます。グラフは、すべての演算が実行されるプロジェクトとして考えることができます。ノードはこれらの ops を表し、新しいテンソルを吸収したり作成したりできます。
テンソル テンソルは、操作間で進行するデータを表します。テンソルを初期化する方法については、前に説明しました。定数と変数の違いは、変数の初期値が時間の経過とともに変化するという点です。
セッションを開く セッションはグラフからの操作を実行します。テンソルの値をグラフに入力するには、セッションを開く必要があります。セッション内では、出力を作成するために演算子を実行する必要があります。

グラフとセッションは独立しています。セッションを実行して、後でさらに計算するために使用する値を取得できます。

以下の例では、次のことを行います。

  • XNUMX つのテンソルを作成する
  • 操作を作成する
  • セッションを開く
  • 結果を印刷する

ステップ1) XNUMX つのテンソル x と y を作成します

## Create, run  and evaluate a session
x = tf.constant([2])
y = tf.constant([4])

ステップ2) xとyを掛け合わせることで演算子を作成します

## Create operator
multiply = tf.multiply(x, y)

ステップ3) セッションを開きます。 すべての計算はセッション内で行われます。 完了したら、セッションを閉じる必要があります。

## Create a session to run the code
sess = tf.Session()result_1 = sess.run(multiply)
print(result_1)
sess.close()

出力

[8]

コードの説明

  • tf.Session(): セッションを開きます。すべての操作はセッション内で行われます。
  • run(multiply): 手順 2 で作成した操作を実行します。
  • print(result_1): 最後に、結果を印刷できます。
  • close(): セッションを閉じる

結果は、x と y の乗算である 8 を示します。

セッションを作成するもう XNUMX つの方法は、ブロック内で作成することです。 利点は、セッションが自動的に閉じられることです。

with tf.Session() as sess:    
result_2 = multiply.eval()
print(result_2)

出力

[8]

セッションのコンテキストでは、eval() メソッドを使用して操作を実行できます。これは run() と同等です。これにより、コードが読みやすくなります。

セッションを作成して、これまでに作成したテンソル内の値を確認できます。

## Check the tensors created before
sess = tf.Session()
print(sess.run(r1))
print(sess.run(r2_matrix))
print(sess.run(r3_matrix))

出力

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

テンソルを作成した後でも、変数はデフォルトでは空です。 変数を使用する場合は、変数を初期化する必要があります。 変数の値を初期化するには、オブジェクト tf.global_variables_initializer() を呼び出す必要があります。 このオブジェクトはすべての変数を明示的に初期化します。 これは、モデルをトレーニングする前に役立ちます。

先ほど作成した変数の値を確認できます。 テンソルを評価するには run を使用する必要があることに注意してください

sess.run(tf.global_variables_initializer())
print(sess.run(var))
print(sess.run(var_init_1))
print(sess.run(var_init_2))

出力

[[-0.05356491  0.75867283]]
[[0 0]]
[[10 20] 
 [30 40]]

前に作成したプレースホルダーを使用して、実際の値をフィードすることができます。 データを feed_dict メソッドに渡す必要があります。

たとえば、プレースホルダー data_placeholder_a の 2 のべき乗を取得します。

import numpy as np
power_a = tf.pow(data_placeholder_a, 2)
with tf.Session() as sess:  
data = np.random.rand(1, 10)  
print(sess.run(power_a, feed_dict={data_placeholder_a: data}))  # Will succeed.

コードの説明

  • numpy を np としてインポート: インポート numpyライブラリ データを作成する
  • tf.pow(data_placeholder_a, 2): ops を作成します。
  • np.random.rand(1, 10): データのランダムな配列を作成します。
  • feed_dict={data_placeholder_a: data}: プレースホルダーにデータをフィードします

出力

[[0.05478134 0.27213147 0.8803037  0.0398424  0.21172127 0.01444725  0.02584014 0.3763949  0.66022706 0.7565559 ]]

グラフ

TensorFlow は、操作をレンダリングするための独創的なアプローチに依存しています。すべての計算は、データフロー スキームで表されます。データフロー グラフは、個々の操作間のデータの依存関係を確認するために開発されました。数式またはアルゴリズムは、一連の連続した操作で構成されています。グラフは、計算がどのように調整されているかを視覚化する便利な方法です。

グラフは次のことを示しています エッジノードは操作の表現、つまり計算の単位です。エッジはテンソルであり、新しいテンソルを生成したり、入力データを消費したりできます。個々の操作間の依存関係によって異なります。

グラフの構造は、操作 (つまりノード) とそれらの操作がどのようにフィードされるかを接続します。グラフには操作の出力は表示されず、個々の操作間の接続を視覚化するためにのみ役立つことに注意してください。

例を見てみましょう。

次の関数を評価したいとします。

グラフ

TensorFlow は関数を実行するためのグラフを作成します。 グラフは次のようになります。

TensorFlow グラフの例

TensorFlow グラフの例

テンソルが最終目的地に到達するまでにたどるパスを簡単に確認できます。

たとえば、操作 add は、 および の前には実行できないことがわかります。グラフは、次のようになることを説明しています。

  1. 計算して:
  2. 1)を足し合わせます
  3. 2に追加)
  4. 3) を追加します
x = tf.get_variable("x", dtype=tf.int32,  initializer=tf.constant([5]))
z = tf.get_variable("z", dtype=tf.int32,  initializer=tf.constant([6]))
c = tf.constant([5], name =	"constant")square = tf.constant([2], name =	"square")
f = tf.multiply(x, z) + tf.pow(x, square) + z + c

コードの説明

  • x: x という変数を定数値 5 で初期化します。
  • z: z という変数を定数値 6 で初期化します。
  • c: c という定数テンソルを定数値 5 で初期化します。
  • square: square という定数テンソルを定数値 2 で初期化します。
  • f: 演算子を構築する

この例では、変数の値を固定することを選択します。 また、関数 f の定数パラメーターである c という定数テンソルも作成しました。 固定値 5 をとります。グラフでは、このパラメーターが定数と呼ばれるテンソルにあることがわかります。

また、演算子 tf.pow() の累乗の定数テンソルも作成しました。これは必須ではありません。グラフでテンソルの名前を確認できるようにするために作成しました。これは square と呼ばれる円です。

グラフから、テンソルで何が起こるか、そしてどのようにして 66 の出力を返すことができるかを理解できます。

以下のコードはセッション内の関数を評価します。

init = tf.global_variables_initializer() # prepare to initialize all variables
with tf.Session() as sess:    
	init.run() # Initialize x and y    
    function_result = f.eval()
print(function_result)

出力

[66]

まとめ

TensorFlow 回避策:

  • グラフ: 演算とテンソルを含む計算環境
  • テンソル:グラフ内に流れるデータ(または値)を表します。 グラフの端です
  • セッションズ: 操作の実行を許可する

定数テンソルを作成する

定数 オブジェクト
D0 tf.constant(1, tf.int16)
D1 tf.constant([1,3,5], tf.int16)
D2 tf.constant([ [1, 2], [3, 4] ],tf.int16)
D3 tf.constant([ [[1, 2],[3, 4], [5, 6]] ], tf.int16)

オペレーターを作成する

オペレーターを作成する オブジェクト
a + b tf.add(a, b)
a * b tf.multiply(a, b)

可変テンソルを作成する

変数を作成する オブジェクト
ランダム化された値 tf.get_variable(“var”, [1, 2])
初期化された最初の値 tf.get_variable(“var_init_2”, dtype=tf.int32, イニシャライザ=[ [1, 2], [3, 4] ])

セッションを開く

セッションを開く オブジェクト
セッションを作成する tf.セッション()
セッションを実行する tf.Session.run()
テンソルを評価する 変数名.eval()
セッションを閉じる sess.close()
ブロックごとのセッション tf.Session() を sess として使用: