python - 使用Dataset API和Keras编写summary.scalar

标签 python tensorflow keras tensorboard

我使用tensorflow Keras API并尝试将自定义标量添加到张量板,但除了损失之外什么都没有显示。

这是模型的代码:

embedding_in = Embedding(
    input_dim=vocab_size + 1 + 1,  
    output_dim=dim,
    mask_zero=True,
)

embedding_out = Embedding(
    input_dim=vocab_size + 1 + 1,  
    output_dim=dim,
    mask_zero=True,
)

input_a = Input((None,))
input_b = Input((None,))
input_c = Input((None, None))

emb_target = embedding_in(input_a)
emb_context = embedding_out(input_b)
emb_negatives = embedding_out(input_c)

emb_gru = GRU(dim, return_sequences=True)(emb_target)

num_negatives = tf.shape(input_c)[-1]


def make_logits(tensors):
    emb_gru, emb_context, emb_negatives = tensors
    true_logits = tf.reduce_sum(tf.multiply(emb_gru, emb_context), axis=2)
    true_logits = tf.expand_dims(true_logits, -1)
    sampled_logits = tf.squeeze(
        tf.matmul(emb_negatives, tf.expand_dims(emb_gru, axis=2),
                  transpose_b=True), axis=3)
    true_logits = true_logits*0
    sampled_logits = sampled_logits*0

    logits = K.concatenate([true_logits, sampled_logits], axis=-1)
    return logits


logits = Lambda(make_logits)([emb_gru, emb_context, emb_negatives])

mean = tf.reduce_mean(logits)
tf.summary.scalar('mean_logits', mean)

model = keras.models.Model(inputs=[input_a, input_b, input_c], outputs=[logits])

特别是,我想看到每批之后 mean_logits 标量的演变。

我像这样创建并编译模型:

model = build_model(dim, vocab_size)
model.compile(loss='binary_crossentropy', optimizer='sgd')
callbacks = [
        keras.callbacks.TensorBoard(logdir, histogram_freq=1)
]

我在模型中使用 tf Dataset API:

iterator = dataset.make_initializable_iterator()

with tf.Session() as sess:

        sess.run(iterator.initializer)
        sess.run(tf.tables_initializer())
        model.fit(iterator, steps_per_epoch=100, 
                  callbacks=callbacks,
                  validation_data=iterator,
                  validation_steps=1
                 )

但是,我在张量板中没有得到任何mean_logits图,并且它不在图中。 enter image description here

如何在每个批处理后跟踪张量板中的 mean_logits 标量?

我使用 tf 1.12 和 keras 2.1。

最佳答案

我也遇到了同样的问题。看来 Keras TensorBoard 回调不会自动写入所有现有的摘要,而只会自动写入那些 registered as metrics 的摘要。 (并出现在 logs 字典中)。更新 logs 对象是一个很好的技巧,因为它允许使用其他回调中的值,请参阅 Early stopping and learning rate schedule based on custom metric in Keras 。我可以看到几种可能性:

<强>1。使用 Lambda 回调

类似这样的事情:

eval_callback = LambdaCallback(
    on_epoch_end=lambda epoch, logs: logs.update(
        {'mean_logits': K.eval(mean)}
    ))

<强>2。自定义 TensorBoard 回调

您还可以对回调进行子类化并定义您自己的逻辑。例如,我的学习率监控的解决方法:

class Tensorboard(Callback):                                                                                                                                                                                                                                          
    def __init__(self,                                                                                                                                                                                                                                                
                 log_dir='./log',                                                                                                                                                                                                                                     
                 write_graph=True):                                                                                                                                                                                                                                   
        self.write_graph = write_graph                                                                                                                                                                                                                                
        self.log_dir = log_dir                                                                                                                                                                                                                                        

    def set_model(self, model):                                                                                                                                                                                                                                       
        self.model = model                                                                                                                                                                                                                                            
        self.sess = K.get_session()                                                                                                                                                                                                                                   
        if self.write_graph:                                                                                                                                                                                                                                          
            self.writer = tf.summary.FileWriter(self.log_dir, self.sess.graph)                                                                                                                                                                                        
        else:                                                                                                                                                                                                                                                         
            self.writer = tf.summary.FileWriter(self.log_dir)                                                                                                                                                                                                         

    def on_epoch_end(self, epoch, logs={}):                                                                                                                                                                                                                           
        logs.update({'learning_rate': float(K.get_value(self.model.optimizer.lr))})                                                                                                                                                                                   
        self._write_logs(logs, epoch)                                                                                                                                                                                                                                 

    def _write_logs(self, logs, index):                                                                                                                                                                                                                               
        for name, value in logs.items():                                                                                                                                                                                                                              
            if name in ['batch', 'size']:                                                                                                                                                                                                                             
                continue                                                                                                                                                                                                                                              
            summary = tf.Summary()                                                                                                                                                                                                                                    
            summary_value = summary.value.add()                                                                                                                                                                                                                       
            if isinstance(value, np.ndarray):                                                                                                                                                                                                                         
                summary_value.simple_value = value.item()                                                                                                                                                                                                             
            else:                                                                                                                                                                                                                                                     
                summary_value.simple_value = value                                                                                                                                                                                                                    
            summary_value.tag = name                                                                                                                                                                                                                                  
            self.writer.add_summary(summary, index)                                                                                                                                                                                                                   

        self.writer.flush()                                                                                                                                                                                                                                           

    def on_train_end(self, _):                                                                                                                                                                                                                                        
        self.writer.close() 

在这里,我只是明确地将“learning_rate”添加到日志中。但这种方式可以更加灵活和强大。

<强>3。指标技巧

Here是另一个有趣的解决方法。您需要做的是将自定义度量函数传递给模型的compile()调用,该调用返回聚合的汇总张量。这个想法是让 Keras 将聚合摘要操作传递给每个 session.run 调用,并将其结果作为指标返回:

x_entropy_t = K.sum(p_t * K.log(K.epsilon() + p_t), axis=-1, keepdims=True)
full_policy_loss_t = -res_t + X_ENTROPY_BETA * x_entropy_t
tf.summary.scalar("loss_entropy", K.sum(x_entropy_t))
tf.summary.scalar("loss_policy", K.sum(-res_t))
tf.summary.scalar("loss_full", K.sum(full_policy_loss_t))

summary_writer = tf.summary.FileWriter("logs/" + args.name)

def summary(y_true, y_pred):
    return tf.summary.merge_all()

value_policy_model.compile(optimizer=Adagrad(), loss=loss_dict, metrics=[summary])
l = value_policy_model.train_on_batch(x_batch, y_batch)
l_dict = dict(zip(value_policy_model.metrics_names, l))

summary_writer.add_summary(l_dict['value_summary'], global_step=iter_idx)
summary_writer.flush()

关于python - 使用Dataset API和Keras编写summary.scalar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54924673/

相关文章:

python - 是否有更简单的方法来获取张量切片,如以下示例所示?

tensorflow - TensorFlow 使用什么缓存模型?

tensorflow - 将卡住模型 '.pb' 文件转换为 '.tflite' 文件所需的参数 input_arrays 和 output_arrays 是什么?

tensorflow - 使用 load_model 时,keras 内核初始化程序被错误调用

python - 有没有理由不发送 super().__init__() 字典而不是 **kwds?

python - index() 方法不接受 None 作为开始/停止

python - 训练时 Tensorflow 形状不兼容错误

python - 如何检查 python 2.7 中的原始输入是否为整数?

python - 如何获得神经网络中权重与损失的凸曲线

tensorflow - 属性错误 : 'Sequential' object has no attribute '_feed_input_names'