0

tf モデルの重みについて勾配を計算したいのですが、一方向のみです。

import tensorflow as tf

model = tf.keras.Sequential([
  tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss=tf.keras.losses.BinaryCrossentropy(from_logits=False))

features = tf.random.normal((1000,10))
labels = tf.random.normal((1000,))

model.fit(features, labels, batch_size=32, epochs=1)

x_star = model.layers[0].weights #the layer has kernel and bias
v = tf.random.normal((10,1)) #direction of the gradient

def directional_loss(model, x, y, t):
    model.layers[0].set_weights([x_star[0] + t*v, x_star[1]])
    y_ = model(x)
    return model.loss(y_true=y, y_pred=y_)

def directional_grad(model, inputs, targets, t):
    with tf.GradientTape() as tape:
        loss_value = directional_loss(model, inputs, targets, t)
    return loss_value, tape.gradient(loss_value, t)

t=0.
loss_value, grads = directional_grad(model, features, labels, t)

ただし、次のエラーが返されます。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in directional_grad
  File "C:\Users\pierr\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\backprop.py", line 1070, in gradient
    if not backprop_util.IsTrainable(t):
  File "C:\Users\pierr\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\eager\backprop_util.py", line 58, in IsTrainable
    dtype = dtypes.as_dtype(dtype)
  File "C:\Users\pierr\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\framework\dtypes.py", line 725, in as_dtype
    raise TypeError(f"Cannot convert value {type_value!r} to a TensorFlow DType.")
TypeError: Cannot convert value 0.0 to a TensorFlow DType.

model.layers[0].set_weights操作が「微分可能」ではないからだと思います。

どうすれば修正できますか?あるいは、TensorFlow では、重みを直接指定してレイヤーの出力を計算できy = layer(x, weights=w)ますか?

4

1 に答える 1