Tensorflow:不规则张量tf.RaggedTensor学习和测试

业务背景

最近有个需求使用KPRN算法预测一组输入序列的得分,问题在于不同端点之间的这一组序列数量不一致,而每一个最小颗粒度序列都需要过一个LSTM层,在LSTM之后归属于同一对端点的序列需要合并为一组,例如输入100个序列在经过LSTM+2层全连接之后得到100个值[V1,V2,V3…,V100],然后归属于同一组的至需要聚合,比如[[V1, V2], [V3, V4, V5] ,[V100]],此时已经不能使用tensorflow的reshape算子,引出不规则矩阵tf.RaggedTensor


测试使用tf.RaggedTensor能否完成静态图loss优化

工程采用tensorflow 1.X,引入不规则张量的原因是必须使用全流程使用张量构建静态图,如果因此聚合操作导致中间引入Python集合操作,势必断开了静态图导致无法训练,而要完成聚合操作目前看只能引入不规则张量。下面一个简单例子调试下,

  • 每次输入一个固定数量比如64端点对的batch,但是一对之间可能有多组序列(特征embedding),因此炸开之后每个batch的序列数不一样,比如这批100,下次150,在下次143
  • 每个batch虽然数量不一样,但是会同时输入一个rowids,这个长度也是None,所有rowids里面的最大值应该相同
  • KPRN是每个序列LSTM+两层全链接输出一个值,本次实验直接使用一个一层全链接输出一个值代替
  • LSTM+两层全链接之后是logsumexp,本次使用保持一致,并且论文中参数设置为1
  • 最后套一层sigmod和y值计算交叉熵计算loss,y等于batch聚合分组后的大小
import tensorflow as tf

input_x = tf.placeholder(tf.float32, [None, 5])
input_rowids = tf.placeholder(tf.int64, [None])
input_y = tf.placeholder(tf.float32, [None, 1])

full_connect = tf.layers.dense(input_x, units=1, activation=tf.nn.sigmoid)
agg_layers = tf.RaggedTensor.from_value_rowids(full_connect, value_rowids=input_rowids)
logsumexp_layers = tf.log(tf.reduce_sum(tf.exp(agg_layers), axis=1))
sigmoid_out = tf.sigmoid(logsumexp_layers)
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=input_y, logits=logsumexp_layers))
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_step = optimizer.minimize(loss)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(10):
        full_connect_val, agg_layers_val, logsumexp_layers_val, sigmoid_out_val, loss_val, _ = sess.run(
            [full_connect, agg_layers, logsumexp_layers, sigmoid_out, loss, train_step],
            feed_dict={input_x: [[1.0, 2.0, 3.0, 4.0, -1.0],
                                 [2.0, -2.0, -1.0, 1.0, -2.0],
                                 [3.0, -3.0, 3.0, 2.0, -3.0],
                                 [4.0, 1.0, 3.0, 2.0, 2.0],
                                 [5.0, 1.0, 2.0, 4.0, 3.0]],
                       input_rowids: [0, 0, 0, 1, 1],
                       input_y: [[1.0], [0.0]]})
        print(full_connect_val)
        print(agg_layers_val)
        print(logsumexp_layers_val)
        print(sigmoid_out_val)
        print("loss:", loss_val)
        print("---------------")

运行输出最后一轮迭代如下

[[0.67166984]
 [0.7236427 ]
 [0.82996327]
 [0.12828942]
 [0.04120561]]
<tf.RaggedTensorValue [[[0.6716698408126831], [0.7236427068710327], [0.8299632668495178]], [[0.12828941643238068], [0.04120561480522156]]]>
[[1.8425585]
 [0.7788424]]
[[0.86325103]
 [0.6854306 ]]
loss: 0.6518001
---------------

整体没有问题可以跑通进行loss迭代

以上代码主要是这一行,其他都是小场面

agg_layers = tf.RaggedTensor.from_value_rowids(full_connect, value_rowids=input_rowids)

tf.RaggedTensor.from_value_rowids输入了两个tensor,一个tensor是上一个操作产生的tensor,在例子中那就是全链接之后的向量,另一个tensor是每一个输入所属的组号,组号从0开始,如果某个组元素为空则直接跳过这个组号往后写。因此在这个地方解决了炸开之后的每个最小颗粒度输入,在经过神经网络变化之后,如果再根据分组号聚合改变形状的问题
tf.RaggedTensor支持大部分tensorflow的运算,但是本例子不支持tf.reduce_logsumexp

logsumexp_layers = tf.reduce_logsumexp(agg_layers)

TypeError: Failed to convert object of type <class 'tensorflow.python.ops.ragged.ragged_tensor.RaggedTensor'> to Tensor. Contents: tf.RaggedTensor(values=Tensor("dense/Sigmoid:0", shape=(?, 1), dtype=float32), row_splits=Tensor("RaggedFromValueRowIds_2/concat_1:0", shape=(?,), dtype=int64)). Consider casting elements to a supported type.

因此本例子手动使用tf的其他简单操作实现


tf.RaggedTensor官方文档学习

参考这个https://tensorflow.google.cn/guide/ragged_tensor

(1)构造不规则张量

最简单方式是使用 tf.ragged.constant,它会构建与给定的嵌套 Python list 或 NumPy array 相对应的 RaggedTensor

>>> tf.ragged.constant([[1, 2, 3], [2, 3]])
tf.RaggedTensor(values=Tensor("RaggedConstant/values:0", shape=(5,), dtype=int32), row_splits=Tensor("RaggedConstant/Const:0", shape=(3,), dtype=int64))

除此之外还可以通过将扁平的值张量行分区张量进行配对来构造不规则张量,行分区张量使用 tf.RaggedTensor.from_value_rowidstf.RaggedTensor.from_row_lengthstf.RaggedTensor.from_row_splits,本例就是采用的from_value_rowids
文档里面说扁平的值张量测试就算不是值张量,只要是规则的多维矩阵都可以使用这种转化为不规则的张量

>>> b = tf.RaggedTensor.from_value_rowids(values=[[1, 2], [3, 4], [5, 6]], value_rowids=[0,0,1])
>>> with tf.Session() as sess:
...     print(sess.run(b))
... 
<tf.RaggedTensorValue [[[1, 2], [3, 4]], [[5, 6]]]>

另外输入values可以是python集合,也可以是自定义的另外一个规则的tensor。

最后的最后

感谢你们的阅读和喜欢,我收藏了很多技术干货,可以共享给喜欢我文章的朋友们,如果你肯花时间沉下心去学习,它们一定能帮到你。

因为这个行业不同于其他行业,知识体系实在是过于庞大,知识更新也非常快。作为一个普通人,无法全部学完,所以我们在提升技术的时候,首先需要明确一个目标,然后制定好完整的计划,同时找到好的学习方法,这样才能更快的提升自己。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值