tf.constant和tf.Variable的用法

483 阅读3分钟

调用基本的库

import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import sklearn
import pandas as pd
import os
import sys
import time
import tensorflow as tf

from tensorflow import keras

print(tf.__version__)
print(sys.version_info)
for module in mpl, np, pd, sklearn, tf, keras:
    print(module.__name__, module.__version__)
2.6.2
sys.version_info(major=3, minor=6, micro=8, releaselevel='final', serial=0)
matplotlib 3.3.4
numpy 1.19.5
pandas 1.1.5
sklearn 0.24.2
tensorflow 2.6.2
keras.api._v2.keras 2.6.0

定义一个常量

t = tf.constant([[1., 2., 3.], [4., 5., 6.]])

# index
print(t)
# 取出第二列之后的数值
print(t[:, 1:])
# 只要第二列的数值
print(t[..., 1])
tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[2. 3.]
 [5. 6.]], shape=(2, 2), dtype=float32)
tf.Tensor([2. 5.], shape=(2,), dtype=float32)

op

# 基本上所有的操作都支持
print(t+10)
# t的平方
print(tf.square(t))
# t * t的转置
print(t @ tf.transpose(t))
tf.Tensor(
[[11. 12. 13.]
 [14. 15. 16.]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[ 1.  4.  9.]
 [16. 25. 36.]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[14. 32.]
 [32. 77.]], shape=(2, 2), dtype=float32)

numpy conversion

# 调用numpy可以直接把值取出来
print(t.numpy())
print(np.square(t))
# 把np的值传入tf.constant会获得tf.Tensor的值
np_t = np.array([[1., 2., 3.], [4., 5., 6.]])
print(tf.constant(np_t))
[[1. 2. 3.]
 [4. 5. 6.]]
[[ 1.  4.  9.]
 [16. 25. 36.]]
tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float64)

Scalars 零维

t = tf.constant(2.718)
print(t.numpy())
print(t.shape)
2.718
()

strings 字符串

t = tf.constant("cafe")
print(t)
# 长度
print(tf.strings.length(t))
# utf8编码的长度
print(tf.strings.length(t, unit="UTF8_CHAR"))
# utf8编码
print(tf.strings.unicode_decode(t, "UTF8"))
tf.Tensor(b'cafe', shape=(), dtype=string)
tf.Tensor(4, shape=(), dtype=int32)
tf.Tensor(4, shape=(), dtype=int32)
tf.Tensor([ 99  97 102 101], shape=(4,), dtype=int32)

string array

t = tf.constant(["cafe", "coffee", "咖啡"])
print(tf.strings.length(t, unit="UTF8_CHAR"))
# 转为utf-8
r = tf.strings.unicode_decode(t, "UTF8")
print(r)
tf.Tensor([4 6 2], shape=(3,), dtype=int32)
<tf.RaggedTensor [[99, 97, 102, 101], [99, 111, 102, 102, 101, 101], [21654, 21857]]>

ragged tensor 不完整的矩阵(不规则)

r = tf.ragged.constant([[11, 12], [21, 22, 23], [], [41]])
# index op  索引操作
print(r)
print(r[1])
print(r[1:2])
<tf.RaggedTensor [[11, 12], [21, 22, 23], [], [41]]>
tf.Tensor([21 22 23], shape=(3,), dtype=int32)
<tf.RaggedTensor [[21, 22, 23]]>

ops on ragged tensor 拼接操作

r2 = tf.ragged.constant([[51, 52], [], [71]])
# 让r和r2做拼接,axis=0是按照行的维度进行拼接
# 按照列的维度进行拼接,会报错,因为行数不一样
print(tf.concat([r, r2], axis = 0))
<tf.RaggedTensor [[11, 12], [21, 22, 23], [], [41], [51, 52], [], [71]]>
r3 = tf.ragged.constant([[13, 14], [15], [], [42, 43]])
print(tf.concat([r, r3], axis = 1))
<tf.RaggedTensor [[11, 12, 13, 14], [21, 22, 23, 15], [], [41, 42, 43]]>

RaggedTensor可以转化普通tensor,只需要调用to_tensor函数

# 0都在正常值得后面
print(r.to_tensor())
tf.Tensor(
[[11 12  0]
 [21 22 23]
 [ 0  0  0]
 [41  0  0]], shape=(4, 3), dtype=int32)

sparse tensor

# 如果一个矩阵中大部分位置都是0,只有少部分位置是1的话,那么只需要把对应位置是1的值的坐标记录下来就可以
# indices 是 所有正常值的位置
# values 是 对应的值
# dense_shape 是 矩阵的具体大小
s = tf.SparseTensor(indices = [[0, 1], [1, 0], [2, 3]],
                    values = [1., 2., 3.],
                    dense_shape = [3, 4])
print(s)
# 把SparseTensor转为Tensor
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)
# ops on sparse tensors

s2 = s * 2.0
print(s2)

# 加法是不能被执行的
try:
    s3 = s + 1
except TypeError as ex:
    print(ex)

# 支持乘法
s4 = tf.constant([[10., 20.],
                  [30., 40.],
                  [50., 60.],
                  [70., 80.]])
# sparse_dense_matmul把Sparse矩阵和密集矩阵做乘法
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(
[[ 30.  40.]
 [ 20.  40.]
 [210. 240.]], shape=(3, 2), dtype=float32)
# sparse tensor 必须是排好序的,否则无法调用to_dense
# 解决方法:给s5调用sparse.reorder
s5 = tf.SparseTensor(indices = [[0, 2], [0, 1], [2, 3]],
                    values = [1., 2., 3.],
                    dense_shape = [3, 4])
print(s5)
s6 = tf.sparse.reorder(s5)
print(tf.sparse.to_dense(s6))
SparseTensor(indices=tf.Tensor(
[[0 2]
 [0 1]
 [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. 2. 1. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 3.]], shape=(3, 4), dtype=float32)

Variables 变量

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=float32, numpy=
array([[1., 2., 3.],
       [4., 5., 6.]], dtype=float32)>
tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float32)
[[1. 2. 3.]
 [4. 5. 6.]]

assign value 给变量重新赋值

v.assign(2*v)
print(v.numpy())
# 对某个位置重新赋值
v[0, 1].assign(42)
print(v.numpy())
# 对某一行重新赋值
v[1].assign([7., 8., 9.])
print(v.numpy())
[[ 2.  4.  6.]
 [ 8. 10. 12.]]
[[ 2. 42.  6.]
 [ 8. 10. 12.]]
[[ 2. 42.  6.]
 [ 7.  8.  9.]]
# 不可以用=重新赋值
try:
    v[1] = [7., 8., 9.]
except TypeError as ex:
    print(ex)
'ResourceVariable' object does not support item assignment