web-dev-qa-db-ja.com

InvalidArgumentError:入力#0(ゼロベース)は浮動小数点テンソルであることが期待されていましたが、二重テンソルであるため、MatMulを計算できません[Op:MatMul]

TensorFlowのEagerモードはどのように機能するのですか?次のように単純な回帰を構築しようとしています:

import tensorflow as tf

tfe = tf.contrib.eager
tf.enable_eager_execution()

import numpy as np


def make_model():
    net = tf.keras.Sequential()
    net.add(tf.keras.layers.Dense(4, activation='relu'))
    net.add(tf.keras.layers.Dense(1))
    return net

def compute_loss(pred, actual):
    return tf.reduce_mean(tf.square(tf.subtract(pred, actual)))

def compute_gradient(model, pred, actual):
    """compute gradients with given noise and input"""
    with tf.GradientTape() as tape:
        loss = compute_loss(pred, actual)
    grads = tape.gradient(loss, model.variables)
    return grads, loss

def apply_gradients(optimizer, grads, model_vars):
    optimizer.apply_gradients(Zip(grads, model_vars))

model = make_model()
optimizer = tf.train.AdamOptimizer(1e-4)

x = np.linspace(0,1,1000)
y = x+np.random.normal(0,0.3,1000)
y = y.astype('float32')
train_dataset = tf.data.Dataset.from_tensor_slices((y.reshape(-1,1)))

epochs = 2# 10
batch_size = 25
itr = y.shape[0] // batch_size
for Epoch in range(epochs):
    for data in tf.contrib.eager.Iterator(train_dataset.batch(25)):
        preds = model(data)
        grads, loss = compute_gradient(model, preds, data)
        print(grads)
        apply_gradients(optimizer, grads, model.variables)
#         with tf.GradientTape() as tape:
#             loss = tf.sqrt(tf.reduce_mean(tf.square(tf.subtract(preds, data))))
#         grads = tape.gradient(loss, model.variables)
#         print(grads)
#         optimizer.apply_gradients(Zip(grads, model.variables),global_step=None)

Gradient output: [None, None, None, None, None, None]エラーは次のとおりです。

----------------------------------------------------------------------
ValueError                           Traceback (most recent call last)
<ipython-input-3-a589b9123c80> in <module>
     35         grads, loss = compute_gradient(model, preds, data)
     36         print(grads)
---> 37         apply_gradients(optimizer, grads, model.variables)
     38 #         with tf.GradientTape() as tape:
     39 #             loss = tf.sqrt(tf.reduce_mean(tf.square(tf.subtract(preds, data))))

<ipython-input-3-a589b9123c80> in apply_gradients(optimizer, grads, model_vars)
     17 
     18 def apply_gradients(optimizer, grads, model_vars):
---> 19     optimizer.apply_gradients(Zip(grads, model_vars))
     20 
     21 model = make_model()

~/anaconda3/lib/python3.6/site-packages/tensorflow/python/training/optimizer.py in apply_gradients(self, grads_and_vars, global_step, name)
    589     if not var_list:
    590       raise ValueError("No gradients provided for any variable: %s." %
--> 591                        ([str(v) for _, v, _ in converted_grads_and_vars],))
    592     with ops.init_scope():
    593       self._create_slots(var_list)

ValueError: No gradients provided for any variable:

編集する

コードを更新しました。今、問題は勾配計算にあり、それはゼロを返します。ゼロ以外の損失値を確認しました。

9
Ankish Bansal

パート1:問題は確かに入力のデータ型です。デフォルトでは、kerasモデルはfloat32を想定していますが、float64を渡しています。モデルのdtypeを変更するか、入力をfloat32に変更できます。

モデルを変更するには:

_def make_model():
    net = tf.keras.Sequential()
    net.add(tf.keras.layers.Dense(4, activation='relu', dtype='float32'))
    net.add(tf.keras.layers.Dense(4, activation='relu'))
    net.add(tf.keras.layers.Dense(1))
    return net
_

入力を変更するには:y = y.astype('float32')

パート2:モデルを計算する関数(つまり、model(data))をtf.GradientTape()で呼び出す必要があります。たとえば、_compute_loss_メソッドを次のように置き換えることができます。

_def compute_loss(model, x, y):
    pred = model(x)
    return tf.reduce_mean(tf.square(tf.subtract(pred, y)))
_
12
Anna Krogager