我想形象化CNN中给定的特征地图所学习到的模式(在本例中,我使用vgg16)。为此,我创建了一个随机图像,通过网络输入到所需的卷积层,选择特征映射并找到与输入相关的梯度。其想法是以这样一种方式改变输入,以最大限度地激活所需的功能映射。使用tensorflow 2.0,我有一个GradientTape,它跟踪函数,然后计算梯度,但是梯度不返回,为什么它不能计算梯度?
import tensorflow as tf
import matplotlib.pyplot as plt
import time
import numpy as np
from tensorflow.keras.applications import vgg16
class maxFeatureMap():
def __init__(self, model):
self.model = model
self.optimizer = tf.keras.optimizers.Adam()
def getNumLayers(self, layer_name):
for layer in self.model.layers:
if layer.name == layer_name:
weights = layer.get_weights()
num = weights[1].shape[0]
return ("There are {} feature maps in {}".format(num, layer_name))
def getGradient(self, layer, feature_map):
pic = vgg16.preprocess_input(np.random.uniform(size=(1,96,96,3))) ## Creates values between 0 and 1
pic = tf.convert_to_tensor(pic)
model = tf.keras.Model(inputs=self.model.inputs,
outputs=self.model.layers[layer].output)
with tf.GradientTape() as tape:
## predicts the output of the model and only chooses the feature_map indicated
predictions = model.predict(pic, steps=1)[0][:,:,feature_map]
loss = tf.reduce_mean(predictions)
print(loss)
gradients = tape.gradient(loss, pic[0])
print(gradients)
self.optimizer.apply_gradients(zip(gradients, pic))
model = vgg16.VGG16(weights='imagenet', include_top=False)
x = maxFeatureMap(model)
x.getGradient(1, 24)发布于 2019-07-06 19:42:28
这是GradientTape的一个常见缺陷;磁带只跟踪设置为“监视”的张量,默认情况下磁带只监视可训练的变量(即用trainable=True创建的tf.Variable对象)。要查看pic张量,您应该在磁带上下文中添加tape.watch(pic)作为第一行。
而且,我不确定索引(pic[0])是否能工作,所以您可能想删除它--因为pic在第一个维度中只有一个条目,所以无论如何都不会有什么关系。
此外,您不能使用model.predict,因为这返回一个numpy数组,该数组基本上“破坏”计算图链,这样梯度就不会被反向传播。您应该简单地将模型用作可调用的,即predictions = model(pic)。
https://stackoverflow.com/questions/56916313
复制相似问题