ValueError:Tensor(“ cnn / conv2d / kernel:0”,shape =(),dtype = resource)必须与Tensor(“ Placeholder:0”,shape =(),dtype = variant)来自同一张图

时间:2020-04-02 00:37:48

标签: tensorflow keras deep-learning cnn tensorflow-federated

我是深度学习和TFF的新手。我需要使用CNN对来自EMNIST的图像进行分类。我在GitHub上看到了名为Federated Learning for Image分类的教程。我创建了一个名为CNN的网络,然后使用forward_pass函数实例化一个cnn模型来计算预测。但是TFF需要将模型变量作为可训练变量传递给tff.learning.Model。我打印了CNN model.variables。我不知道如何命名它们,所以我使用cnn_conv2d_kernel表示cnn / conv2d / kernel。这是我的代码:

打印出的model.variables:

variables: [<tf.Variable 'cnn/conv2d/kernel:0' shape=(5, 5, 1, 32) dtype=float32>, <tf.Variable 'cnn/conv2d/bias:0' shape=(32,) dtype=float32>, <tf.Variable 'cnn/conv2d_1/kernel:0' shape=(5, 5, 32, 64) dtype=float32>, <tf.Variable 'cnn/conv2d_1/bias:0' shape=(64,) dtype=float32>, <tf.Variable 'cnn/dense/kernel:0' shape=(3136, 1024) dtype=float32>, <tf.Variable 'cnn/dense/bias:0' shape=(1024,) dtype=float32>, <tf.Variable 'cnn/dense_1/kernel:0' shape=(1024, 10) dtype=float32>, <tf.Variable 'cnn/dense_1/bias:0' shape=(10,) dtype=float32>]

创建我的变量是为了将可训练和不可训练的变量传递给tff.learning.Model:

MnistVariables = collections.namedtuple(
'MnistVariables','cnn_conv2d_kernel cnn_conv2d_bias cnn_conv2d_1_kernel cnn_conv2d_1_bias cnn_dense_kernel cnn_dense_bias cnn_dense_1_kernel cnn_dense_1_bias num_examples loss_sum accuracy_sum'

def create_mnist_variables():
  return MnistVariables(
      # weights=tf.Variable(
      #     # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
      #     lambda: tf.zeros(dtype=tf.float32, shape=(28,28,10)),
      #     name='weights',
      #     trainable=True),
      # bias=tf.Variable(
      #     lambda: tf.zeros(dtype=tf.float32, shape=(10)),
      #     name='bias',
      #     trainable=True),

      cnn_conv2d_kernel=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(5,5,1,32)),
          name='cnn_conv2d_kernel',
          trainable=True),
      cnn_conv2d_bias=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(32,)),
          name='cnn_conv2d_bias',
          trainable=True),
      cnn_conv2d_1_kernel=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(5,5,32,64)),
          name='cnn_conv2d_1_kernel',
          trainable=True),
      cnn_conv2d_1_bias=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(64,)),
          name='cnn_conv2d_1_bias',
          trainable=True),
      cnn_dense_kernel=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(3136,1024)),
          name='cnn_dense_kernel',
          trainable=True),
      cnn_dense_bias=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(1024,)),
          name='cnn_dense_bias',
          trainable=True),
      cnn_dense_1_kernel=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(1024,10)),
          name='cnn_dense_1_kernel',
          trainable=True),
      cnn_dense_1_bias=tf.Variable(
          # lambda: tf.zeros(dtype=tf.float32, shape=(784,10)),
          lambda: tf.zeros(dtype=tf.float32, shape=(10,)),
          name='cnn_dense_1_bias',
          trainable=True),
      num_examples=tf.Variable(0.0, name='num_examples', trainable=False),
      loss_sum=tf.Variable(0.0, name='loss_sum', trainable=False),
      accuracy_sum=tf.Variable(0.0, name='accuracy_sum', trainable=False)
  )

我的部分tff.learning.Model代码:

class MnistModel(tff.learning.Model):

  def __init__(self):
    self._variables = create_mnist_variables()

  #所有的“tf.Variables”都应该在“__init__”中引入
  @property
  def trainable_variables(self):
    #return [self._variables.weights, self._variables.bias]
    return [self._variables.cnn_conv2d_kernel,
        self._variables.cnn_conv2d_bias,
        self._variables.cnn_conv2d_1_kernel,
        self._variables.cnn_conv2d_1_bias,
        self._variables.cnn_dense_kernel,
        self._variables.cnn_dense_bias,
        self._variables.cnn_dense_1_kernel,
        self._variables.cnn_dense_1_bias
        ]

请原谅我的英语不好,请帮助我。(请)

现在,我有一个新问题:

ValueError: No gradients provided for any variable: ['cnn_conv2d_kernel:0', 'cnn_conv2d_bias:0', 'cnn_conv2d_1_kernel:0', 'cnn_conv2d_1_bias:0', 'cnn_dense_kernel:0', 'cnn_dense_bias:0', 'cnn_dense_1_kernel:0', 'cnn_dense_1_bias:0'].

1 个答案:

答案 0 :(得分:1)

在这种情况下,写一个tff.learning.Model并使用TFF的utilities将此转换成tf.keras.Model可能比直接子类tff.learning.Model容易。

在TFF托管的研究代码中有一些完全做到这一点的例子; here是此类指针之一。该指针指向纯Keras模型。要在TFF中使用此功能,我们必须使用上面链接的tff.learning.from_keras_model函数。如果您有一个tf.data.Dataset ds(其中包含图片和标签)以及损失函数loss_fn,则可以通过以下方法来使用tff.learning.model

keras_model = create_keras_model()
tff_model = tff.learning.from_keras_model(
    keras_model=keras_model, loss=loss_fn, input_spec=ds.element_spec)

直接继承tff.learning.Model有点高级用户功能;例如,您将需要编写本机TensorFlow来定义正向传递。对于一般的深度学习(特别是TFF),我建议以上述方式使用更高级别的API,例如tf.keras和TFF的keras实用程序。

相关问题