TensorFlow2.0入门到进阶3.4 ——稀疏张量tf.SparseTensor与变量tf.Variable

1.稀疏张量tf.SparseTensor

1.1 定义

是否还记得上一级中:基础数据类型API之strings与ragged_tensor中的ragged_tensor其实就是允许含有0元素的张量,但是,这种变量所有0都在非零数字的后面,那如果很多0穿插在张量中间怎么办?为此,引入了稀疏张量tf.SparseTensor(何为稀疏,就是很多0元素啦),这种结构只记录非零元素的位置和数值,就可以减少存储空间

1.2 创建

  • indices为非零元素所在位置的索引,values为非零元素的数值
  • dense_shape 为矩阵维度
s = tf.SparseTensor(indices=[[0,1],[1,0],[2,3]],
                    values=[1.,2.,3.],
                    dense_shape=[3,4])
print(s)
print(tf.sparse.to_dense(s))

结果:

SparseTensor(indices=tf.Tensor(
[[0 1]
 [1 0]
 [2 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([1. 2. 3.], shape=(3,), dtype=float32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
tf.Tensor(
[[0. 1. 0. 0.]
 [2. 0. 0. 0.]
 [0. 0. 0. 3.]], shape=(3, 4), dtype=float32)

1.3 运算

与常数可以做乘法,不能做加法,否则会报错

# op on sparse tensors
s2 = s*2
print(s2)

try:
    s3 = s+1
except TypeError as ex:
    print(ex)

# 矩阵乘法
s4 = tf.constant([[11.,12.],
                  [22.,23],
                  [3.1,32.],
                  [41.,42.]])
print(tf.sparse.sparse_dense_matmul(s,s4))

结果:

SparseTensor(indices=tf.Tensor(
[[0 1]
 [1 0]
 [2 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([2. 4. 6.], shape=(3,), dtype=float32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
unsupported operand type(s) for +: 'SparseTensor' and 'int'
tf.Tensor(
[[ 22.  23.]
 [ 22.  24.]
 [123. 126.]], shape=(3, 2), dtype=float32)

1.4 转换为密集矩阵

  • 注意:tf.SparseTensor中的indices 需要是排好序的
  • 否则在tf.sparse.to_dense时会报错
  • 当然,可以使用tf.sparse.reorder自动排顺序
s5 = tf.SparseTensor(indices=[[1,1],[1,0],[2,3]],
                    values=[1.,2.,3.],
                    dense_shape=[3,4])
print(s)

s6=tf.sparse.reorder(s5)
print(tf.sparse.to_dense(s6))

结果:

SparseTensor(indices=tf.Tensor(
[[1 1]
 [1 0]
 [2 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([1. 2. 3.], shape=(3,), dtype=float32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
tf.Tensor(
[[0. 0. 0. 0.]
 [2. 1. 0. 0.]
 [0. 0. 0. 3.]], shape=(3, 4), dtype=float32)

2. 变量tf.Variable

对于常量,在神经网络训练的过程中是不能变的,而变量时可以变的,变量与常量差不多,但是变量会多一些操作

2.1 创建

v = tf.Variable([[1,2,3],
                 [4,5,6]])
print(v)
print(v.value()) 
print(v.numpy())

结果:

<tf.Variable 'Variable:0' shape=(2, 3) dtype=int32, numpy=
array([[1, 2, 3],
       [4, 5, 6]])>
tf.Tensor(
[[1 2 3]
 [4 5 6]], shape=(2, 3), dtype=int32)
[[1 2 3]
 [4 5 6]]

2.2 重新复制

在运行过程中,可以通过assign()函数重新赋值

v.assign(v*2)
print(v.numpy())
# print(v*2)
v[0,1].assign(12)
print(v.numpy())
v[0].assign([51,52,53])
print(v.numpy())

结果:

[[ 2  4  6]
 [ 8 10 12]]
[[ 2 12  6]
 [ 8 10 12]]
[[51 52 53]
 [ 8 10 12]]

这里要注意,这里的重新赋值只能用assign()函数,不能用等号

try :
    v[1] = [1,2,3]
except TypeError as ex:
    print(ex)

结果:

'ResourceVariable' object does not support item assignment
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力改掉拖延症的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值