Skip to main content
 首页 » 编程设计

python之Tensorflow 2.0 不计算梯度

2024年08月13日33虾米哥

我想可视化 CNN 中给定特征图所学习的模式(在本例中我使用的是 vgg16)。为此,我创建了一个随机图像,通过网络提供给所需的卷积层,选择特征图并找到与输入有关的梯度。这个想法是以最大化激活所需特征图的方式改变输入。使用tensorflow 2.0我有一个GradientTape跟随函数然后计算梯度,但是梯度返回None,为什么它无法计算梯度?<​​/p>

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) 

请您参考如下方法:

这是 GradientTape 的一个常见陷阱;磁带仅跟踪设置为“监视”的张量,默认情况下磁带将仅监视可训练变量(即使用 trainable=True 创建的 tf.Variable 对象)。要观看 pic 张量,您应该将 tape.watch(pic) 添加为磁带上下文中的第一行。

另外,我不确定索引 (pic[0]) 是否有效,所以您可能想删除它——因为 pic 只有一个进入第一个维度应该无关紧要。

此外,您不能使用 model.predict,因为这会返回一个 numpy 数组,它基本上会“破坏”计算图链,因此梯度不会被反向传播。您应该简单地将模型用作可调用对象,即 predictions = model(pic)。