1. ホーム
  2. tensorflow

[解決済み] tf.keras.Inputで形状を理解する?

2022-02-16 01:43:24

質問

私はtensorflowとkerasを学んだばかりです。以下はコード例です。

# Create a symbolic input
input = tf.keras.Input(shape=(2,), dtype=tf.float32)

# Do a calculation using is
result = 2*input + 1

# the result doesn't have a value
result

calc = tf.keras.Model(inputs=input, outputs=result)
print(calc(np.array([1,2,3,4])).numpy())
print(calc(2).numpy())

ドキュメントにはshapeと書かれています。バッチサイズを含まない形状タプル(整数)。 例えば shape=(32,) は、入力が32次元ベクトルのバッチであることを示す。このタプルの要素は以下の通りである。 None ; None 要素は、形状が不明な次元を表す。

しかし、上記のコードでは、2つのprint行が両方とも機能しています。しかし、私にとっては、それらは 1D 次元と1スカラーです。では、どのように形状を理解するのでしょうか?

解き方は?

そのことは tf. keras.Input は、シンボリックテンソルやプレースホルダーを生成する。そしてそれは TF 演算を使用します。でご覧ください。 ソースコード :

  Note that even if eager execution is enabled,
  `Input` produces a symbolic tensor (i.e. a placeholder).
  This symbolic tensor can be used with other
  TensorFlow ops, as such:
  '''python
  x = Input(shape=(32,))
  y = tf.square(x)
  '''

だから、このプリントラインは両方とも機能するんだ。


さて、ここでいくつかのシナリオを考えてみましょう。あなたのコードでは shape = [n] ここで n > = 0 の場合、ランク 01 で、それぞれスケーラとベクトルです。しかし、ランク 2 または行列の場合 n とは等しくない。 x.shape[1] . 例えば

import tensorflow as tf 
import numpy as np 

# Create a symbolic input
input  = tf.keras.Input(shape=[0], dtype=tf.float32)
result = 2*input + 1 
calc   = tf.keras.Model(inputs=input, outputs=result)

print(calc(1).numpy())                     # scaler rank 0
print(calc(np.array([1,2,3,4])).numpy())   # vector rank 1
print(calc(np.array([[1,2,3,4]])).numpy()) # matrix rank 2 

3.0
[3. 5. 7. 9.]

ValueError: Input 0 is incompatible with layer model_2: 
expected shape=(None, 0), found shape=(1, 4)

この問題を解決するには、shapeパラメータに正確な特徴次元数を設定する必要があります。 4 .

# Create a symbolic input
input  = tf.keras.Input(shape=[4], dtype=tf.float32)
result = 2*input + 1 
calc   = tf.keras.Model(inputs=input, outputs=result)

print(calc(1).numpy())                     # scaler rank 0
print(calc(np.array([1,2,3,4])).numpy())   # vector rank 1
print(calc(np.array([[1,2,3,4]])).numpy()) # matrix rank 2 

3.0
[3. 5. 7. 9.]
[[3. 5. 7. 9.]]

ここで一つ興味深い事実があります、これを構築すると calc というモデルで shape = [1] をスカラーまたはベクトルと に続いて 2D の行列があっても文句は言われないでしょう。 2D の入力は、モデルが最初に構築されなかった場合のみエラーを発生させるからです。入力がある状態でモデルを起動することで、モデルの形状が設定されます。

# Create a symbolic input
input  = tf.keras.Input(shape=[1], dtype=tf.float32)
result = 2*input + 1 
calc   = tf.keras.Model(inputs=input, outputs=result)

print(calc(1).numpy())                     # scaler rank 0
print(calc(np.array([1,2,3,4])).numpy())   # vector rank 1
print(calc(np.array([[1,2,3,4]])).numpy()) # matrix rank 2 

3.0
[[3.]
 [5.]
 [7.]
 [9.]]
[[3. 5. 7. 9.]]


でも、学習可能なレイヤーでモデルを作ると、このような遊びはできなくなります。その場合は、学習可能なレイヤーを持つモデルと、学習可能なレイヤーを持つモデルの間の形状マッチングの問題を解決する必要があります。 shape と入力データを比較します。例えば

x = tf.keras.Input(shape=[4])
y = tf.keras.layers.Dense(10)(x)
model = tf.keras.Model(x, y)

print(model(np.array([[1,2,3,4]])).numpy()) # (1, 4)
print(model(np.array([1,2,3,4])).numpy())   # (4,)

[[ 1.4779348  -1.8168153  -0.93788755 -1.4927139  -0.23618054  2.4305463
  -1.6176091   0.6640817  -1.648994    3.5819988 ]]

ValueError: Input 0 of layer dense_1 is incompatible with the layer: 
: expected min_ndim=2, found ndim=1. Full shape received: (4,)