在实现Deep Learning with Python这本书5.4节CNN可视化的第二块时,原始代码求梯度直接调用backend中gradients函数,但这在TensorFlow2.0之后好像不适用,改为使用tf.GradientTape(),但结果却出现下面的错误
Attempt to convert a value (None) with an unsupported type (<class 'NoneType'>) to a Tensor.
原始书中代码如下:
def generate_pattern(layer_name, filter_index, size=150):
# Build a loss function that maximizes the activation
# of the nth filter of the layer considered.
layer_output = model.get_layer(layer_name).output
loss = K.mean(layer_output[:, :, :, filter_index])
# Compute the gradient of the input picture wrt this loss
grads = K.gradients(loss, model.input)[0]
# Normalization trick: we normalize the gradient
grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
# This function returns the loss and grads given the input picture
iterate = K.function([model.input], [loss, grads])
# We start from a gray image with some noise
input_img_data = np.random.random((1, size, size, 3)) * 20 + 128.
# Run gradient ascent for 40 steps
step = 1.
for i in range(40):
loss_value, grads_value = iterate([input_img_data])
input_img_data += grads_value * step
img = input_img_data[0]
return deprocess_image(img)
我修改后的代码如下:
def generate_pattern(layer_name, filter_index, size=299):
# Build a loss function that maximizes the activation
# of the nth filter of the layer considered.
# Compute the gradient of the input picture wrt this loss
with tf.GradientTape() as gtape:
gtape.watch(model.input[0])
layer_output = model.get_layer(layer_name).output
loss = K.mean(layer_output[:, :, :, filter_index])
print(model.input[0])
print(loss)
grads = gtape.gradient(loss, model.input[0])
print(grads)
# grads = K.gradients(loss, model.input)[0]
# Normalization trick: we normalize the gradient
gradsnorm = K.sqrt(K.mean(K.square(grads))) + 1e-5
grads = grads / gradsnorm
# This function returns the loss and grads given the input picture
iterate = K.function([model.input], [loss, grads])
# We start from a gray image with some noise
input_img_data = np.random.random((1, size, size, 3)) * 20 + 128.
# Run gradient ascent for 40 steps
step = 1.
for i in range(40):
loss_value, grads_value = iterate([input_img_data])
input_img_data += grads_value * step
img = input_img_data[0]
return deprocess_image(img)
报错如下:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-45-ccb22f34a88a> in <module>
----> 1 plt.imshow(generate_pattern('block3_conv1', 0))
2 plt.show()
<ipython-input-44-2266a77687f2> in generate_pattern(layer_name, filter_index, size)
35 # grads = K.gradients(loss, model.input)[0]
36 # Normalization trick: we normalize the gradient
---> 37 gradsnorm = K.sqrt(K.mean(K.square(grads))) + 1e-5
38 grads = grads / gradsnorm
39
D:\Program Files\Python38\lib\site-packages\tensorflow\python\util\dispatch.py in wrapper(*args, **kwargs)
199 """Call target, and fall back on dispatchers if there is a TypeError."""
200 try:
--> 201 return target(*args, **kwargs)
202 except (TypeError, ValueError):
203 # Note: convert_to_eager_tensor currently raises a ValueError, not a
D:\Program Files\Python38\lib\site-packages\tensorflow\python\keras\backend.py in square(x)
2339 A tensor.
2340 """
-> 2341 return math_ops.square(x)
2342
2343
D:\Program Files\Python38\lib\site-packages\tensorflow\python\ops\gen_math_ops.py in square(x, name)
10306 pass
10307 try:
> 10308 return square_eager_fallback(
10309 x, name=name, ctx=_ctx)
10310 except _core._SymbolicException:
D:\Program Files\Python38\lib\site-packages\tensorflow\python\ops\gen_math_ops.py in square_eager_fallback(x, name, ctx)
10341
10342 def square_eager_fallback(x, name, ctx):
> 10343 _attr_T, (x,) = _execute.args_to_matching_eager([x], ctx)
10344 _inputs_flat = [x]
10345 _attrs = ("T", _attr_T)
D:\Program Files\Python38\lib\site-packages\tensorflow\python\eager\execute.py in args_to_matching_eager(l, ctx, default_dtype)
260 for t in l:
261 ret.append(
--> 262 ops.convert_to_tensor(
263 t, dtype, preferred_dtype=default_dtype, ctx=ctx))
264 if dtype is None:
D:\Program Files\Python38\lib\site-packages\tensorflow\python\framework\ops.py in convert_to_tensor(value, dtype, name, as_ref, preferred_dtype, dtype_hint, ctx, accepted_result_types)
1497
1498 if ret is None:
-> 1499 ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
1500
1501 if ret is NotImplemented:
D:\Program Files\Python38\lib\site-packages\tensorflow\python\framework\constant_op.py in _constant_tensor_conversion_function(v, dtype, name, as_ref)
336 as_ref=False):
337 _ = as_ref
--> 338 return constant(v, dtype=dtype, name=name)
339
340
D:\Program Files\Python38\lib\site-packages\tensorflow\python\framework\constant_op.py in constant(value, dtype, shape, name)
261 ValueError: if called on a symbolic tensor.
262 """
--> 263 return _constant_impl(value, dtype, shape, name, verify_shape=False,
264 allow_broadcast=True)
265
D:\Program Files\Python38\lib\site-packages\tensorflow\python\framework\constant_op.py in _constant_impl(value, dtype, shape, name, verify_shape, allow_broadcast)
273 with trace.Trace("tf.constant"):
274 return _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
--> 275 return _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
276
277 g = ops.get_default_graph()
D:\Program Files\Python38\lib\site-packages\tensorflow\python\framework\constant_op.py in _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
298 def _constant_eager_impl(ctx, value, dtype, shape, verify_shape):
299 """Implementation of eager constant."""
--> 300 t = convert_to_eager_tensor(value, ctx, dtype)
301 if shape is None:
302 return t
D:\Program Files\Python38\lib\site-packages\tensorflow\python\framework\constant_op.py in convert_to_eager_tensor(value, ctx, dtype)
96 dtype = dtypes.as_dtype(dtype).as_datatype_enum
97 ctx.ensure_initialized()
---> 98 return ops.EagerTensor(value, ctx.device_name, dtype)
99
100
ValueError: Attempt to convert a value (None) with an unsupported type (<class 'NoneType'>) to a Tensor.
我怀疑原因就是这一行本来应该类型是Tensor结果却为none,但为啥会变成none以及如何修改我就不知道了
grads = gtape.gradient(loss, model.input[0])