Wil*_*ill 8 python gradient-descent conv-neural-network tensorflow
我想可视化 CNN 中给定特征图所学的模式(在本例中,我使用的是 vgg16)。为此,我创建了一个随机图像,通过网络馈送到所需的卷积层,选择特征图并找到相对于输入的梯度。这个想法是以这样一种方式改变输入,以最大化所需特征图的激活。使用 tensorflow 2.0 我有一个 GradientTape 跟随函数然后计算梯度,但是梯度返回 None,为什么它无法计算梯度?
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)
Run Code Online (Sandbox Code Playgroud)
xdu*_*ch0 15
这是一个常见的陷阱GradientTape;磁带只跟踪设置为“监视”的张量,默认情况下磁带将只监视可训练变量(意思tf.Variable是用 创建的对象trainable=True)。要查看pic张量,您应该添加tape.watch(pic)为磁带上下文中的第一行。
另外,我不确定索引 ( pic[0]) 是否有效,因此您可能想要删除它——因为pic在第一维中只有一个条目,无论如何都无关紧要。
此外,您不能使用,model.predict因为这会返回一个 numpy 数组,它基本上“破坏”了计算图链,因此梯度不会被反向传播。您应该简单地将模型用作可调用对象,即predictions = model(pic).
| 归档时间: |
|
| 查看次数: |
5244 次 |
| 最近记录: |