用于自定义估算器的张量不在同一张图中

时间:2018-07-20 09:57:31

标签: python tensorflow machine-learning tensorflow-estimator

我是tensorflow的新手,并试图使用自定义估算器运行ConvLSTM。

我这样定义了model_fn:

def model_fn(features,labels,mode,params = None):

    if params==None:
        batch_size = 50
        time_steps = 150
        dim =40
    else:
        batch_size = params['batch_size']
        time_steps = params['time_steps']
        dim = params['dim']

    #instantiate cell
    net = tf.contrib.rnn.ConvLSTMCell(conv_ndims = 2,input_shape = [dim,dim,1],output_channels = 1,kernel_shape = [3,3])

    state = net.zero_state(batch_size,dtype = tf.float32)
    features = tf.cast(features,tf.float32)

    if mode != tf.estimator.ModeKeys.PREDICT: # Added in order to solve tf.cast problem if there is no labels
        labels = tf.cast(labels,tf.float32)
        state = net.zero_state(batch_size,dtype = tf.float32) # <-- inconsistent state size between training and predict, is it problematic ?
    else:
        state = net.zero_state(1,dtype = tf.float32)

    inputs = tf.split(features,time_steps,axis = 1)
    inputs_list = [tf.squeeze(input_,[1]) for input_ in inputs]

    outputs = []

    with tf.variable_scope("convLSTM") as scope: 
        for i, input_ in enumerate(inputs_list):
            if i>0:
                scope.reuse_variables()
            t_output ,state = net(input_,state)
            outputs.append(t_output)
    outputs = tf.stack(outputs,1)
    rmse = tf.Variable(tf.zeros([],dtype = np.float32))

    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(mode,predictions=outputs)

    elif mode == tf.estimator.ModeKeys.TRAIN:
        loss = tf.losses.absolute_difference(labels,outputs)
        optimizer= tf.train.AdagradOptimizer (learning_rate = 0.1)
        train_op = optimizer.minimize(loss,global_step = tf.train.get_global_step())

        rmse = tf.metrics.root_mean_squared_error(labels,outputs)[0]
        tf.summary.scalar('RMSE loss',rmse)

        return tf.estimator.EstimatorSpec(mode,loss=loss,train_op = train_op)

    elif mode == tf.estimator.ModeKeys.EVAL:
        loss = tf.losses.absolute_difference(labels,outputs)
        rmse = tf.metrics.root_mean_squared_error(labels,outputs)[0]

        tf.summary.scalar('RMSE loss',rmse)

        return tf.estimator.EstimatorSpec(mode,loss=loss,eval_metric_ops = {'RMSE':rmse})

输入功能:

def input_fn_train(batch_size):
    dataset = tf.data.TFRecordDataset(['Data/train.tfrecords'])
    dataset = dataset.map(parse_)
    dataset = dataset.shuffle(buffer_size = 5)
    dataset = dataset.batch(batch_size)

    return dataset.prefetch(buffer_size = 5)


def input_fn_eval(batch_size):
    dataset = tf.data.TFRecordDataset(['Data/eval.tfrecords'])
    dataset = dataset.map(parse_)
    dataset = dataset.shuffle(buffer_size = 5)  
    dataset = dataset.batch(batch_size)
    return dataset.make_one_shot_iterator().get_next()

哪种方法更好,迭代器还是数据集输出?

主要:

def main():

    batch_size = 5
    data_pred = misc.input_fn_eval(1)


    rnn = tf.estimator.Estimator(
                                model_fn = model.model_fn,
                                model_dir = "logs/20_08/",
                                params = {'batch_size':batch_size,'time_steps':150,'dim':40})

    rnn.train(input_fn =lambda : misc.input_fn_train(batch_size),steps = 1)

    video = rnn.predict(input_fn = lambda:data_pred)


    print(next(video))

if __name__ == "__main__":
    main()

现在,该代码似乎很不错,至少在语法上适合训练。我想预测几帧,以便检查演变情况,但我不断出错:

ValueError: Tensor("ConvLSTMCellZeroState_1/zeros_1:0", shape=(1, 40, 40, 1), dtype=float32) must be from the same graph as Tensor("Squeeze:0", shape=(?, 40, 40, 1), dtype=float32).

我在Iterator和Dataset上也有这个功能(我相信用于预测输入功能,该功能以前与培训中的功能相同。创建一个不同的功能似乎已经解决了。)

非常感谢您的帮助!我希望这个问题很清楚,如果不是这样,请告诉我。

1 个答案:

答案 0 :(得分:2)

尝试通过以下方式更改代码:

video = rnn.predict(input_fn = lambda:misc.input_fn_eval(1))

问题是您必须从input_fn_eval呼叫input_fn。然后,该函数创建的所有张量都属于Estimator

创建的图

您可以找到类似的问题herehere