关于断点调试TensorFlow代码的一点儿总结

背景

这一周在学习某篇论文的代码,里面大量用到了TensorFlow

问题

主要问题是:断点调试程序时,我需要查看某一张量的值,这个张量存储在一个类的函数的一个局部变量里,而且其依赖的张量还使用了占位符,因此不能等到会话开启或占位符填充时,再查看这个局部张量的值,因为那时就访问不到了。

解决方法

1、启动会话。将会话启动提早到那个类的初始函数之前,并把会话对象做为参数传给类的初始函数,做为类的属性之一

之前这部分代码是这样

interaction_table, offset = get_interaction_table(train_data, n_entity)
interaction_table.init.run()

model = KGNN_LS(args, n_user, n_entity, n_relation,
                        adj_entity, adj_relation, interaction_table,
                        offset)    

with tf.Session() as sess:
        sess.run(init)
        ....

更改后变成了这样

    with tf.Session() as sess:
        sess.run(init)

        interaction_table, offset = get_interaction_table(train_data, n_entity)
        interaction_table.init.run()

        model = KGNN_LS(args, n_user, n_entity, n_relation,
                        adj_entity, adj_relation, interaction_table,
                        offset, sess)

2、占位符填充。原来的代码里关于占位符填充的部分如下所示

            while start + args.batch_size <= train_data.shape[0]:
                _, loss = model.train(sess, get_feed_dict(model, train_data, start, start + args.batch_size))
                start += args.batch_size
                ...


def get_feed_dict(model, data, start, end):
    feed_dict = {model.user_indices: data[start:end, 0],
                 model.item_indices: data[start:end, 1],
                 model.labels: data[start:end, 2]}
    return feed_dict

看来是分批次从训练集中取数据去训练,这样,我们先把训练集也保存到模型类里面,就像保存会话对象一样;而后可以把这个获取填充数据的函数稍加改动也封装到模型类里,为了避免测试集太大,我们可以固定只查看固定行数的样例,具体多少行可以根据一批处理样本的数量决定。相关代码如下所示

模型构造函数

        model = KGNN_LS(args, n_user, n_entity, n_relation,
                        adj_entity, adj_relation, interaction_table,
                        offset, sess, train_data)

模型类构造函数的实现

    def __init__(self, args, n_user, n_entity, n_relation,
                 adj_entity, adj_relation, interaction_table,
                 offset, session, train_data):
        self.session = session
        self.train_data = train_data
        ....

模型类内部获取填充数据的函数

    def get_feed_dict_test(self):
        start = 0
        end = self.batch_size
        data = self.train_data

        feed_dict = {self.user_indices: data[start:end, 0],
                     self.item_indices: data[start:end, 1],
                     self.labels: data[start:end, 2]}
        return feed_dict

然后把查看张量值的步骤封装成函数即可

    def test_tensor(self, tensor):
        return self.session.run([tensor], self.get_feed_dict_test())

这样就可以查看局部张量的值了

遇到的问题

在这个模型类的某部分,用到了XavierInitializer,我在用上面的方法查看被它初始化的张量时,报了如下错误

{FailedPreconditionError}Attempting to use uninitialized value XXX

解决方法

在XavierInitializer初始化的张量下面,再次初始化全局初始化器即可,代码如下

        self.relation_emb_matrix = tf.get_variable(
            shape=[n_relation, self.dim], initializer=self.initializer, name='relation_emb_matrix')  # 被XavierInitializer初始化的张量之一

        self.session.run(tf.global_variables_initializer())

然后查看XavierInitializer初始化的张量值就没问题了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值