尝试迭代循环中的张量时,Tensorflow类型错误

时间:2019-05-15 08:49:52

标签: python tensorflow

我有以下情况:

y = tf.placeholder(tf.float32, [None, 1],name="output")
layers = [tf.contrib.rnn.BasicRNNCell(num_units=n_neurons,activation=tf.nn.leaky_relu, name="layer"+str(layer))
         for layer in range(2)]
multi_layer_cell = tf.contrib.rnn.MultiRNNCell(layers)
rnn_outputs, states = tf.nn.dynamic_rnn(multi_layer_cell, X, dtype=tf.float32)
stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, 100]) 
stacked_outputs = tf.layers.dense(stacked_rnn_outputs, 1)
outputs = tf.reshape(stacked_outputs, [-1, 2, 1])
outputs = tf.identity(outputs[:,1,:], name="prediction")
loss = Custom_loss(y,outputs)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) 
training_op = optimizer.minimize(loss,name="training_op")

我尝试过的自定义损失函数是:

def Custom_loss(y,outputs):
    hold_loss = []
    for exp,pred in zip(y,outputs):
        if exp >= pred:
            result = tf.pow(pred * 0.5,2) - exp
            hold_loss.append(result)
        else:
            hold_loss.append(tf.subtract(pred-exp))
    return tf.reduce_mean(hold_loss)

现在,当我尝试实现此功能时,出现以下错误:

TypeError: Tensor objects are only iterable when eager execution is enabled. To iterate over this tensor use tf.map_fn.

我尝试实现tf.map_fn(),但是遇到相同的错误。我曾使用以下问题:
How to explain the result of tf.map_fn?

请帮我解决这个问题?我如何迭代张量?哪种方法最适合自定义损失函数?

1 个答案:

答案 0 :(得分:1)

def Custom_loss(y,outputs):
    mask = tf.greater_equal(y, outputs)
    a = tf.pow(tf.boolean_mask(outputs, mask)*0.5, 2) - tf.boolean_mask(y, mask)
    inv_mask = tf.logical_not(mask)
    b = tf.boolean_mask(outputs, inv_mask)- tf.boolean_mask(y, inv_mask)
    return tf.reduce_mean(tf.concat([a, b], axis=-1))

测试用例

def Custom_loss_np(y,outputs):
    hold_loss = []
    for exp,pred in zip(y,outputs):
        if exp >= pred:
            result = pow(pred * 0.5,2) - exp
            hold_loss.append(result)
        else:
            hold_loss.append(pred-exp)
    return np.mean(hold_loss)

np_x = np.random.randn(100)
np_y = np.random.randn(100)

x = tf.constant(np_x)
y = tf.constant(np_y)

with tf.Session() as sess:
   assert sess.run(Custom_loss(x, y)) == Custom_loss_np(np_x, np_y)

如果您使用的是张量流的最新版本,请使用tf.math

使用自定义损失训练简单线性回归模型的示例

X = tf.placeholder(tf.float32,[None,1])
y = tf.placeholder(tf.float32,[None,1])

w = tf.Variable(tf.ones([1,1]))
b = tf.Variable(tf.ones([1,1]))
y_ = tf.matmul(X, w)+b
loss = Custom_loss(y, y_) #tf.reduce_mean(tf.square(y_ - y)) 

optimizer = tf.train.AdamOptimizer(learning_rate=0.001) 
training_op = optimizer.minimize(loss,name="training_op")

#dummy data for linear regression
x_data = np.random.randn(100,1)
y_labels = 1.5*x_data + 2.5 + np.random.randn(100,1)

init = tf.global_variables_initializer()
sess.run(init)

sess = tf.Session()
sess.run(init)

for i in range(5000):
    _, loss_ = sess.run([training_op,loss], feed_dict={X:x_data, y:y_labels})
    if (i+1)%1000 == 0 :
        print (loss_)

print (sess.run([w, b]))

OP提出了计算损失的逻辑。