我是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'] #实例化单元 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: # 添加以解决如果没有标签时的tf.cast问题 labels = tf.cast(labels,tf.float32) state = net.zero_state(batch_size,dtype = tf.float32) # <-- 训练和预测之间的状态大小不一致,这是否会造成问题? 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).
我还遇到了迭代器和数据集的问题(我认为是预测输入函数的问题,之前与训练的输入函数相同。创建一个不同的输入函数似乎解决了这个问题)。
非常感谢您的帮助!希望我的问题足够清楚,如果不是,请告诉我。
回答:
尝试按以下方式更改您的代码:
video = rnn.predict(input_fn = lambda:misc.input_fn_eval(1))
问题在于您必须从input_fn
中调用input_fn_eval
。这样,该函数创建的所有张量都属于Estimator
创建的图形