TensorFlow 1.15添加@tf.function后代码报类型错误该如何修复?
问题修复方案
报错根因
你用的是TensorFlow 1.x的会话执行模式,sess.run()仅支持传入张量(Tensor)或者计算操作(Operation)作为执行目标,你直接传入了被@tf.function装饰后的函数对象,因此触发类型报错。
另外你当前代码还有两个隐藏问题:
@tf.function装饰的函数内部不支持直接调用numpy原生接口,这类接口无法被转换为TensorFlow图算子,执行时会二次报错- 你写的测试集索引逻辑
np.arange(int(t * 1), t)生成的是空数组,完全没有测试样本
修复后的完整代码
import numpy as np import tensorflow as tf print(tf.__version__) #tf ver: 1.15 # 加载本地数据 Z = np.loadtxt("Z.txt") #516 rows * 2000 columns R1 = np.loadtxt("R1.txt") #516 rows * 1000 columns R2 = np.loadtxt("R2.txt") #516*49 M = np.loadtxt("M.txt") #516*4 # 定义placeholder z_data = tf.placeholder(dtype=tf.float32) r_data = tf.placeholder(dtype=tf.float32) m_data = tf.placeholder(dtype=tf.float32) target_data = tf.placeholder(dtype=tf.float32) # 不需要@tf.function装饰,或者如果要使用装饰器,需要把内部numpy操作全部替换为TF API def data_split(z_data, r_data, m_data, target_data): ff_n = m_data.shape[1] port_n = target_data.shape[1] t, n = tf.shape(r_data)[0], tf.shape(r_data)[1] p = tf.cast(tf.shape(z_data)[1] / n, tf.int32) z_data = tf.transpose(tf.reshape(z_data, (t, p, n)), (0, 2, 1)) # dim(t,n,p) return z_data, r_data, m_data, target_data, ff_n, port_n, t, n, p # 先调用函数拿到返回的张量 z_processed, r_processed, m_processed, target_processed, ff_n, port_n, t, n, p = data_split(z_data, r_data, m_data, target_data) with tf.compat.v1.Session() as sess: # 先执行图计算拿到处理后的数据 z_arr, r_arr, m_arr, target_arr, ff_n_val, port_n_val, t_val, n_val, p_val = sess.run( [z_processed, r_processed, m_processed, target_processed, ff_n, port_n, t, n, p], feed_dict={z_data: Z, r_data: R1, m_data: M, target_data: R2} ) # 用numpy做训练测试拆分,更简单直观,此处以8:2拆分训练测试集为例,可按需调整比例 test_idx = np.arange(int(t_val * 0.8), t_val) train_idx = np.setdiff1d(np.arange(t_val), test_idx) t_train = len(train_idx) z_train = z_arr[train_idx] z_test = z_arr[test_idx] r_train = r_arr[train_idx] r_test = r_arr[test_idx] target_train = target_arr[train_idx] target_test = target_arr[test_idx] m_train = m_arr[train_idx] m_test = m_arr[test_idx]
可选优化说明
如果你一定要用@tf.function实现全图逻辑,需要把所有numpy操作替换为TensorFlow对应的API,比如tf.range、tf.sets.difference等,调用时先传入placeholder拿到返回张量,再传入sess.run执行即可。
内容的提问来源于stack exchange,提问作者lindo
相关产品推荐
相关产品推荐

