Python 3.x TF 2.0错误:在使用梯度带进行培训期间,变量不存在梯度

Python 3.x TF 2.0错误:在使用梯度带进行培训期间,变量不存在梯度,python-3.x,tensorflow,tensorflow2.0,Python 3.x,Tensorflow,Tensorflow2.0,我试图使用TF2.0中的batchnormalization层创建一个类,但它给了我一个错误,即变量不存在梯度。我试图直接使用batchnormalization,但它也给了我同样的错误。似乎它没有训练与batchnormalization步骤相关的变量 我尝试使用model.trainable_变量而不是model.variables,但也不起作用 来自未来导入绝对导入 来自未来进口部 来自未来导入打印功能 导入tensorflow作为tf 从tensorflow进口keras 从tensor

我试图使用TF2.0中的batchnormalization层创建一个类,但它给了我一个错误,即变量不存在梯度。我试图直接使用batchnormalization,但它也给了我同样的错误。似乎它没有训练与batchnormalization步骤相关的变量

我尝试使用model.trainable_变量而不是model.variables,但也不起作用

来自未来导入绝对导入
来自未来进口部
来自未来导入打印功能
导入tensorflow作为tf
从tensorflow进口keras
从tensorflow.keras.utils导入到
将numpy作为np导入
将matplotlib.pyplot作为plt导入
导入操作系统
从scipy导入ndimage
学习率=0.001
培训时间=15
批量大小=100
tf.random.set_seed(777)
cur_dir=os.getcwd()
ckpt_dir_name='检查点'
model_dir_name=‘minst_cnn_best’
checkpoint\u dir=os.path.join(cur\u dir、ckpt\u dir\u name、model\u dir\u name)
makedirs(检查点目录,exist\u ok=True)
checkpoint\u prefix=os.path.join(checkpoint\u dir,model\u dir\u name)
mnist=tf.keras.datasets.mnist
(列车图像,列车标签),(测试图像,测试标签)=mnist.load\u data()
train\u images=train\u images.astype(np.float32)/255。
test_images=test_images.astype(np.float32)/255。
打印(训练图像.shape,测试图像.shape)
序列图像=np。展开序列图像,轴=-1)
测试图像=np。展开图像(测试图像,轴=-1)
打印(训练图像.shape,测试图像.shape)
列车标签=至列车分类(列车标签,10)
测试标签=到分类(测试标签,10)
train_dataset=tf.data.dataset.从张量切片((train_图像,
序列号(标签)).shuffle(缓冲区大小=100000)。批(批大小)
test\u dataset=tf.data.dataset.从张量切片((test\u图像,
测试(标签)。批次(批次大小)
ConvBNRelu类(tf.keras.Model):
def uu init uu(self,filters,kernel_size=3,strips=1,padding='SAME'):
超级(ConvBNRelu,self)。\uuuu init\uuuuu()
self.conv=keras.layers.Conv2D(过滤器=过滤器,内核大小=内核大小,步幅=步幅,
padding=padding,kernel\u initializer='glorot\u normal')
self.batchnorm=tf.keras.layers.BatchNormalization()
def呼叫(自我、输入、培训=错误):
层=self.conv(输入)
层=自批处理规范(层)
图层=tf.nn.relu(图层)
返回层
DenseBNRelu类(tf.keras.Model):
定义初始值(自身,单位):
超级(DenseBNRelu,self)。\uuuu init\uuuuu()
self.densite=keras.layers.densite(单位=单位,kernel\u初始化器='glorot\u normal')
self.batchnorm=tf.keras.layers.BatchNormalization()
def呼叫(自我、输入、培训=错误):
层=自密实(输入)
层=自批处理规范(层)
图层=tf.nn.relu(图层)
返回层
类别模型(tf.keras.Model):
定义初始化(自):
超级(MNISTModel,self)。\uuuu init\uuuuu()
self.conv1=ConvBNRelu(filters=32,kernel\u size=[3,3],padding='SAME')
self.pool1=keras.layers.MaxPool2D(padding='SAME')
self.conv2=ConvBNRelu(filters=64,kernel_size=[3,3],padding='SAME')
self.pool2=keras.layers.MaxPool2D(padding='SAME')
self.conv3=ConvBNRelu(filters=128,kernel\u size=[3,3],padding='SAME')
self.pool3=keras.layers.MaxPool2D(padding='SAME')
self.pool3_flat=keras.layers.Flatten()
self.dense4=DenseBNRelu(单位=256)
self.drop4=keras.layers.Dropout(速率=0.4)
self.dense5=keras.layers.Dense(单位=10,kernel\u initializer='glorot\u normal')
def呼叫(自我、输入、培训=错误):
net=self.conv1(输入)
净=self.pool1(净)
net=self.conv2(net)
净=self.pool2(净)
net=self.conv3(net)
净=self.pool3(净)
净=自池3平(净)
净=self.dense4(净)
净=自降4(净)
净=self.dense5(净)
回报网
型号=[]
num_模型=5
对于范围内的m(num_型号):
models.append(MNISTModel())
def损失(型号、图像、标签):
logits=模型(图像,训练=真)
损失=tf.减少平均值(tf.nn.softmax)交叉熵,
标签=标签)
回波损耗
def梯度(型号、图像、标签):
使用tf.GradientTape()作为磁带:
损耗=损耗\u fn(型号、图像、标签)
返回磁带。梯度(损耗、型号、变量)
def评估(型号、图像、标签):
预测=np.类零(标签)
对于模型中的模型:
logits=模型(图像,训练=假)
预测+=logits
正确的_prediction=tf.equal(tf.argmax(预测,1),tf.argmax(标签,1))
准确度=tf.reduce_平均值(tf.cast(正确的预测,tf.float32))
返回精度
优化器=keras.optimizers.Adam(学习率=学习率)
检查点=[]
对于范围内的m(num_型号):
checkpoints.append(tf.train.Checkpoint(cnn=models[m]))
对于范围内的历元(训练历元):
平均损耗=0。
列车平均加速度=0。
平均测试加速度=0。
列车步进=0
测试步骤=0
对于图像,列_数据集中的标签:
对于模型中的模型:
梯度=梯度(模型、图像、标签)
优化器。应用梯度(zip(梯度、模型、变量))
损耗=损耗\u fn(型号、图像、标签)
平均损失+=损失/数量模型
acc=评估(模型、图像、标签)
平均列车加速度+=加速度
列车步进+=1
平均损耗=平均损耗/列车步进
平均列车加速=平均列车加速/列车步进
对于图像,test_数据集中的标签:
acc=评估(模型、图像、标签)
平均测试加速度+=加速度
测试步骤+=1
平均测试acc=平均测试ac
 return tape.gradient(loss, model.variables)
optimizer.apply_gradients(zip(grads, model.variables)) 
 return tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))