Python 如何沿输入向Tensorflow估计器提供更多的模型参数?

Python 如何沿输入向Tensorflow估计器提供更多的模型参数?,python,numpy,tensorflow,deep-learning,tensorflow-estimator,Python,Numpy,Tensorflow,Deep Learning,Tensorflow Estimator,短版: 我有一个带有图层的自定义模型,可以通过值sigma进行参数化 我将此模型与Tensorflow估计器一起使用: classifier = tf.estimator.Estimator(model_fn=model_fun) 例如,培训声明如下: # Train the model train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data}, batch_size=batch

短版: 我有一个带有图层的自定义模型,可以通过值
sigma
进行参数化

我将此模型与Tensorflow估计器一起使用:

    classifier = tf.estimator.Estimator(model_fn=model_fun)
例如,培训声明如下:

    # Train the model
    train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data}, 
    batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
    classifier.train(input_fn=train_input_fn,max_steps=nSteps)
    # Train the model
    train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data}, 
    batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
    classifier.train(input_fn=train_input_fn,max_steps=nSteps)
在此设置中,我如何将
sigma
传递给我的自定义估计器,以便使用不同的值对其进行训练/评估


较长版本:

我正在研究这个DNN自动编码器,我有一个层,通过考虑来自已知标准偏差σ分布的随机_normal()值来添加高斯噪声

这是一个通信系统的模型,使用model.predict()函数检索输出逻辑(来自最后一层),我的度量即误码率由Tensor Flow 1.5、Python 3.5、Windows 10中的自定义函数计算

问题如下:

    # Train the model
    train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data}, 
    batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
    classifier.train(input_fn=train_input_fn,max_steps=nSteps)
    # Train the model
    train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data}, 
    batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
    classifier.train(input_fn=train_input_fn,max_steps=nSteps)
  • 我想对系统进行sigma=sigma1的培训,并检索输出logits(这部分很好,我能够获得所需的输出)

  • 我还想使用定义的相同估计器(在同一程序中)预测sigma=sigma2、sigma=sigma3、sigma=sigma4等的输出

  • My DNN如下所示,并在模型函数中定义:

  • 输入层-此处输入一个热编码值

  • 稠密的

  • 密集+线性

  • 规范化层

  • 添加噪声:这里我向上一层的输出添加一个tf.random_normal(stddev=sigma)。在这里,我将感谢您帮助我理解如何为每次运行(训练/测试)使用不同的SIGMA。我想你可以说sigma应该是一个参数,每个测试运行可以有不同的值

     gnoise=tf.random_normal(mean=0,stddev=sigma) 
     Then the layer's output=norm(which is the prev layer's output)+gnoise
    
  • 稠密的

  • Softmax输出为Logits

  • 我将我的估计器定义为:

        classifier = tf.estimator.Estimator(model_fn=model_fun)
    
    培训声明如下:

        # Train the model
        train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data}, 
        batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
        classifier.train(input_fn=train_input_fn,max_steps=nSteps)
    
        # Train the model
        train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data}, 
        batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
        classifier.train(input_fn=train_input_fn,max_steps=nSteps)
    
    predict函数被声明和调用为:

        pred_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": test_data}, 
        batch_size=batch_size, num_epochs=nEpochs, shuffle=False)
        pred_results = classifier.predict(input_fn=pred_input_fn)
    

    您应该将sigma作为层的参数,然后在运行时通过
    功能
    (使用列键区分
    x
    sigma
    )将其值提供给模型

    如果没有高斯层代码,很难准确回答,但假设您的模型是这样定义的:

    import tensorflow as tf
    
    def gaussian_noise_layer(x):
        # Currently, your sigma is probably fixed somewhere here, e.g.
        sigma = 1
    
        dist = tf.distributions.Normal(loc=0., scale=sigma)
    
        # Build Gaussian kernel from dist:
        # gaussian_kernel = ...
    
        return tf.nn.depthwise_conv2d(x, gaussian_kernel, [1, 1, 1, 1], padding='SAME')
    
    def model_fun(features, labels, mode, params):
    
        # Get input x from features:
        x = tf.feature_column.input_layer(features, params.feature_column)
    
        # ... building your model here, adding at some point the gaussian layer, e.g.
        # ... net = f(x)
        net = gaussian_noise_layer(net)
        # ... predictions = f'(net)
        # ...
    
        return tf.estimator.EstimatorSpec(
            mode=mode,
            predictions=predictions,
            loss=loss,
            train_op=train_op,
            eval_metric_ops=eval_metric_ops
        )
    
    with tf.Session() as sess:
        # ...
    
        # Specifying your params and inputs:
        params = tf.contrib.training.HParams(
            # ... other hyperparameters,
            # Define feature column for input x of shape "shape_x" (e.g. (64, 64, 3)):
            feature_column=tf.feature_column.numeric_column(key="x", shape=shape_x)
        )
    
        classifier = tf.estimator.Estimator(model_fn=model_fun, params=params)
    
        # For training:
        train_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x": train_data},
                                                            batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
        classifier.train(input_fn=train_input_fn, max_steps=nSteps)
    
    。。。然后您需要像这样编辑它:

    import tensorflow as tf
    
    def gaussian_noise_layer(x, sigma):
    
        # sigma is now a parameter
        dist = tf.distributions.Normal(loc=0., scale=sigma)
    
        # Build Gaussian kernel from dist:
        # gaussian_kernel = ...
    
        return tf.nn.depthwise_conv2d(x, gaussian_kernel, [1, 1, 1, 1], padding='SAME')
    
    def model_fun(features, labels, mode, params):
    
        # Get input x from features:
        x = tf.feature_column.input_layer(features, params.input_feature_column)
        # Get sigma from features:
        sigma = tf.feature_column.input_layer(features, params.sigma_feature_column)
    
        # ... building your model here, adding at some point the gaussian layer, e.g.
        # ... net = f(x)
        net = gaussian_noise_layer(net, sigma)
        # ... predictions = f'(net)
        # ...
    
        return tf.estimator.EstimatorSpec(
            mode=mode,
            predictions=predictions,
            loss=loss,
            train_op=train_op,
            eval_metric_ops=eval_metric_ops
        )
    
    with tf.Session() as sess:
        # ...
    
        # We now specify which columns contain the actual inputs (x), and which columns contain other parameters (sigma):
        params = tf.contrib.training.HParams(
            # ... other hyperparameters,
            # Define feature column for input x of shape "shape_x" (e.g. (64, 64, 3)):
            input_feature_column=tf.feature_column.numeric_column(key="x", shape=shape_x),
            # Define feature column for input sigma of shape () i.e. scalar (default shape):
            sigma_feature_column=tf.feature_column.numeric_column(key="sigma")
        )
    
        classifier = tf.estimator.Estimator(model_fn=model_fun, params=params)
    
        # Train:
        num_train_elements = train_data.shape[0]
        sigma = [1] * num_train_elements  # or e.g. sigma = [1, 1, 2, 1, 3, ...]
        # We can now feed sigma along x:
        train_input_fn = tf.estimator.inputs.numpy_input_fn(
             x={"x": train_data, "sigma": numpy.array(sigma)},
             batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
    
        classifier.train(input_fn=train_input_fn, max_steps=nSteps)
    
        # ...
    
        # Predict:
        sigma = [2] * num_train_elements  # or e.g. sigma = [1, 1, 2, 1, 3, ...]
        pred_input_fn=tf.estimator.inputs.numpy_input_fn(
             x={"x": train_data, "sigma": numpy.array(sigma)},
             batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
        pred_results = classifier.predict(input_fn=pred_input_fn)
    

    请提供高斯噪声层的代码,以便正确回答。gnoise=tf.random_normal(mean=0,stddev=sigma),然后层的输出=norm(这是前一层的输出)+gnoise谢谢你的回答。你能描述一下我将如何在预测函数声明和调用中添加不同的参数sigma吗?另外,TF似乎期望在train\u input\u fn中声明的“x”和“sigma”的值具有相同的形状。我希望sigma保持单个标量值,如1、2、3等,是否有解决办法?1)对于predict,您只需以与train相同的方式定义其输入,即将sigma(作为一个numpy元素)添加到dict中,用于tf.estimator.inputs.numpy\u input\fn。我更新了答案,添加了一个示例。2) 正如您在回答中所看到的(我添加了注释以进一步澄清),在params中定义特征列时,x和sigma的形状被传递给TF。在答案中,x有一个形状“shape_x”(例如(64,64,3)),sigma有一个默认形状(),即标量。我的意思是,在遵循这段代码时,我看到了这个错误:ValueError:x和y中张量的长度不匹配。x和y中的所有元素必须具有相同的长度。x和y是numpy输入函数的参数,可以包含特征指令。这基本上意味着numpy输入函数需要SNR和train_数据具有相同的大小。我忘记扩展
    [sigma]
    ,使其与
    列车数据
    具有相同的长度,例如执行
    [sigma\u val]*列车数据。形状[0]
    (代码已更新)。实际上,在这个实现中,必须为训练数据中的每个元素传递一个sigma值(这的一个积极方面是,您可以为每个元素设置不同的sigma值)。希望这有帮助。