学习Tensorflow之基本操作

Posted _DiMinisH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Tensorflow之基本操作相关的知识,希望对你有一定的参考价值。

学习Tensorflow之基本操作

Tensorflow基本操作

1. 创建张量

创建张量的函数为

tensorflow.constant(
    value,          值
    dtype = None,   类型(默认为32位)
    shape = None,   形状
    name = 'Const'  名称
)

(1) 创建标量

import tensorflow as tf

scalarInt = tf.constant(2)
scalarFloat = tf.constant(3.0)
scalarString = tf.constant('Hello')

print(scalarInt)
print(scalarFloat)
print(scalarString)

tf.Tensor(2, shape=(), dtype=int32)

tf.Tensor(3.0, shape=(), dtype=float32)

tf.Tensor(b’Hello’, shape=(), dtype=string)

从结果可以看出,标量的维度是0,所以shape值为空

(2) 创建向量

import tensorflow as tf

vectorInt = tf.constant([2])
vectorFloat = tf.constant([3.0, 4.0])
vectorString = tf.constant(['Hello', 'World'])

print(vectorInt)
print(vectorFloat)
print(vectorString)

tf.Tensor([2], shape=(1,), dtype=int32)

tf.Tensor([3. 4.], shape=(2,), dtype=float32)

tf.Tensor([b’Hello’ b’World’], shape=(2,), dtype=string)

  向量的创建必须加上[],将他作为列表传入函数,方括号的个数代表着tensor的维度

(3) 创建矩阵

import tensorflow as tf

matrixInt = tf.constant([[2], [3]])
matrixFloat = tf.constant([[3.0, 4.0]])
matrixString = tf.constant([['Hello'], ['World']])

print(matrixInt)
print(matrixFloat)
print(matrixString)
tf.Tensor(
[[2]
 [3]], shape=(2, 1), dtype=int32)
tf.Tensor([[3. 4.]], shape=(1, 2), dtype=float32)
tf.Tensor(
[[b'Hello']
 [b'World']], shape=(2, 1), dtype=string)

(4) shape属性

shape属性记录着tensor的形状

shape的取值含义
()该tensor是标量
(列数, )该tensor是向量
(行数, 列数)该tensor是矩阵
(层数, 行数, 列数)该tensor是数据立方体

(5) 判别张量类型

使用tf.rank()函数可以判别张量的类型

import tensorflow as tf

scalarInt = tf.constant(5)
vectorFloat = tf.constant([3.0, 4.0])
matrixString = tf.constant([['Hello'], ['World']])

print(tf.rank(scalarInt))
print(tf.rank(vectorFloat))
print(tf.rank(matrixString))

tf.Tensor(0, shape=(), dtype=int32)

tf.Tensor(1, shape=(), dtype=int32)

tf.Tensor(2, shape=(), dtype=int32)

这里的0、1、2代表的是tensor的维度

(6) 列表和ndarray转张量

tensorflow.convert_to_tensor(
    value,          值
    dtype = None,   类型(默认为32位)
)
import numpy as np
import tensorflow as tf

l = [1, 2, 3]
array = np.array([1.0, 2.2])

print(tf.convert_to_tensor(l))
print(tf.convert_to_tensor(array))
tf.Tensor([1 2 3], shape=(3,), dtype=int32)
tf.Tensor([1.  2.2], shape=(2,), dtype=float32)

2. 创建特殊张量

方法作用
tf.ones(shape, dtype, name)创建全1的张量
tf.ones_like(input, dtype, name)创建全1的张量,包含所有与输入相同的形状
tf.zeros(shape, dtype, name)创建全0的张量
tf.zeros_like(input, dtype, name)创建全0的张量,包含所有与输入相同的形状
tf.fill(dims, value, name)创建值全相同的张量
tf.random.normal(shape, mean, stddev, dtype, seed, name)创建正态分布的张量
tf.random.uniform(shape, minval, maxval, dtype, seed, name)创建平均分布的张量
tf.random.poisson(shape, lam, dtype, seed, name)创建泊松分布的张量
tf.random.gamma(shape, alpha, beta, dtype, seed, name)创建伽马分布的张量

(1) tf.ones与tf.ones_like

import tensorflow as tf

ones = tf.ones((3, 3))
scalarInt = tf.constant(1)
print(ones)

ones_like = tf.ones_like(scalarInt, dtype = tf.float32, name = 'ones_like')
print(ones_like)
tf.Tensor(
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]], shape=(3, 3), dtype=float32)
tf.Tensor(1.0, shape=(), dtype=float32)

(2) tf.zeros与tf.zeros_like

import tensorflow as tf

zeros = tf.zeros((3, 3))
scalarInt = tf.constant(1)
print(zeros)

zeros_like = tf.zeros_like(scalarInt, dtype = tf.string, name = 'zeros_like')
print(zeros_like)
tf.Tensor(
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]], shape=(3, 3), dtype=float32)
tf.Tensor(b'', shape=(), dtype=string)

从结果可以看出,对于字符串类型,0表示的空字符串

(3) tf.fill

import tensorflow as tf

fiveInt = tf.fill((3, 3), 5)
fiveString = tf.fill((3, 3), '5')
print(fiveInt)
print(fiveString)
tf.Tensor(
[[5 5 5]
 [5 5 5]
 [5 5 5]], shape=(3, 3), dtype=int32)
tf.Tensor(
[[b'5' b'5' b'5']
 [b'5' b'5' b'5']
 [b'5' b'5' b'5']], shape=(3, 3), dtype=string)

tf.fill()函数没有dtype参数,系统通过传入value的值来自动判断张量的类型

(3) tf.random.normal

import tensorflow as tf

normal = tf.random.normal((2, 2), 0.0, 1.0, tf.float16)
print(normal)
tf.Tensor(
[[-0.919  1.498]
 [ 0.896 -2.05 ]], shape=(2, 2), dtype=float16)

默认情况下,创建的类型是tf.float32

(4) tf.random.uniform

import tensorflow as tf

uniform = tf.random.uniform((2, 2), 0.0, 10.0, tf.float16)
print(uniform)
tf.Tensor(
[[2.09  2.812]
 [2.822 6.21 ]], shape=(2, 2), dtype=float16)

默认情况下,创建的类型是tf.float32

3. 张量的运算

方法作用
tf.add(x, y, name) 或 运算符 +计算张量相加
tf.subtract(x, y, name) 或 运算符 -计算张量相减
tf.multiply(x, y, name) 或 运算符 *计算张量相乘
tf.divide(x, y, name) 或 运算符 /计算张量相除
tf.abs(x, name)计算张量绝对值
tf.pow(x, y, name)计算张量乘方
tf.sqrt(x, name)计算张量开平方
tf.matmul(a, b, transpose_a, transpose_b) 或 运算符@计算矩阵乘法
tf.cast(x, dtype, name)强制类型转换
tensor[层数][行数][列数]张量索引
[start : end : step]张量切片
tf.reshape(tensor, shape, name)张量维度转换
tf.expand_dims(input, axis, name)增加张量的维度
tf.squeeze(input, axis, name)减少张量的维度
tf.transpose(a, perm, conjugate)交换张量的维度

(1) 四则运算

import tensorflow as tf

t1 = tf.constant([1, 2])
t2 = tf.constant([2, 4])
print(tf.add(t1, t2))
print(tf.subtract(t1, t2))
print(tf.multiply(t1, t2))
print(tf.divide(t1, t2))
print()
print(t1 + t2)
print(t1 - t2)
print(t1 * t2)
print(t1 / t2)
tf.Tensor([3 6], shape=(2,), dtype=int32)
tf.Tensor([-1 -2], shape=(2,), dtype=int32)
tf.Tensor([2 8], shape=(2,), dtype=int32)
tf.Tensor([0.5 0.5], shape=(2,), dtype=float64)

tf.Tensor([3 6], shape=(2,), dtype=int32)
tf.Tensor([-1 -2], shape=(2,), dtype=int32)
tf.Tensor([2 8], shape=(2,), dtype=int32)
tf.Tensor([0.5 0.5], shape=(2,), dtype=float64)

(2) 绝对值、乘方、开平方

import tensorflow as tf

t1 = tf.constant([-1.0, 2])

print(tf.abs(t1))
print(tf.pow(t1, 3))
print(tf.sqrt(t1))
tf.Tensor([1. 2.], shape=(2,), dtype=float32)
tf.Tensor([-1.  8.], shape=(2,), dtype=float32)
tf.Tensor([      nan 1.4142135], shape=(2,), dtype=float32)

-1不能开平方,所以计算结果是nan,即not a number

(3) 矩阵乘法

import tensorflow as tf

a = tf.constant([1, 2], shape = (1, 2))
b = tf.constant([1, 2], shape = (2, 1))

print(a)
print(b)
print(tf.matmul(a, b))
tf.Tensor([[1 2]], shape=(1, 2), dtype=int32)
tf.Tensor(
[[1]
 [2]], shape=(2, 1), dtype=int32)
tf.Tensor([[5]], shape=(1, 1), dtype=int32)

注意:相乘的矩阵必须满足矩阵乘法的规则

设置转置参数

import tensorflow as tf

a = tf.constant([[1, 2]])
b = tf.constant([[1, 2]])
print(a)
print(b)
print(tf.matmul(a, b, False, True))
tf.Tensor([[1 2]], shape=(1, 2), dtype=int32)
tf.Tensor([[1 2]], shape=(1, 2), dtype=int32)
tf.Tensor([[5]], shape=(1, 1), dtype=int32)

  在tensorflow中,向量是不能与矩阵进行乘法运算的,我们在学习数学的时候,都把向量看成了1维矩阵,但是tensorflow中向量是向量,不是矩阵

import tensorflow as tf

a = tf.constant([1, 2])
b = tf.constant([[2], [1]])
print(a)
print(b)
print(tf.matmul(a, b, False, True))
tf.Tensor([1 2], shape=(2,), dtype=int32)
tf.Tensor(
[[2]
 [1]], shape=(2, 1), dtype=int32)
tensorflow.python.framework.errors_impl.InvalidArgumentError: function_node __wrapped__MatMul_device_/job:localhost/replica:0/task:0/device:CPU:0 In[0] and In[1] has different ndims: [2] vs. [2,1] [Op:MatMul]

所以,在tensorflow中需要注意,向量和矩阵不能进行运算

(4) tf.cast

强制类型转换

import tensorflow as tf

scalarInt = tf.constant(2)
scalarFloat = tf.cast(scalarInt, dtype = tf.float32)
print(scalarInt)
print(scalarFloat)
tf.Tensor(2, shape=(), dtype=int32)
tf.Tensor(2.0, shape=(), dtype=float32)

(5) 张量的索引与切片

按照维度:

3维:tensor[层][行][列]

2维:tensor[行][列]

1维:tensor[列]

import tensorflow as tf

t = tf.constant([i for i in range(25)], shape = (5, 5))
print(t)
# t为2维,取第二行
print(t[1])
# 取第一行第二列
print(t[0, 1])
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]], shape=(5, 5), dtype=int32)
tf.Tensor([5 6 7 8 9], shape=(5,), dtype=int32)
tf.Tensor(1, shape=(), dtype=int32)

取某一维度的全部元素,使用:

import tensorflow as tf

t = tf.constant([i for i in range(25)], shape = (5, 5))
print(t)
# 取所有行第二列
print(t[:, 1])
# 取第二行第全部列,即第二行
print(t[3, :])
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]], shape=(5, 5), dtype=int32)
tf.Tensor([ 1  6 11 16 21], shape=(5,), dtype=int32)
tf.Tensor([15 16 17 18 19], shape=(5,), dtype=int32)

按照间隔取:[start : end : step]

取的范围为 [start : end),即不会取到end

import tensorflow as tf

t = tf.constant([i for i in range(25)], shape = (5, 5))
print(t)

print(t[0:5:2])
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]], shape=(5, 5), dtype=int32)
tf.Tensor(
[[ 0  1  2  3  4]
 [10 11 12 13 14]
 [20 21 22 23 24]], shape=(3, 5), dtype=int32)

(6) tf.reshape

张量维度转换

import tensorflow as tf

t = tf.constant([i for i in range(20)], shape = (4, 5))
print(t)

t = tf.reshape(t, (2, 10))
print(t)
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]], shape=(4, 5), dtype=int32)
tf.Tensor(
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]], shape=(2, 10), dtype=int32)

从结果可以看出4×5的矩阵转换成了2×10的矩阵

如果在reshape时,某一维度写-1,系统会自动计算出这个维度的值

import tensorflow as tf

t = tf.constant([i for i in range(20)], shape = (4, 5))
print(t)

t = tf.reshape(t, (-1, 10))
print(t)
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]], shape=(4, 5), dtype=int32)
tf.Tensor(
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]], shape=(2, 10), dtype=int32)

(4, 5) -> (-1, 10)可以理解为将4×5的矩阵转换成了若干行10列的矩阵

(7) 增加和减少张量的维度

使用tf.expand_dims()可以增加张量的维度

import tensorflow as tf

# 增加张量的维度
t = tf.random.normal((2, 2))
print(t)
# 增加第一维度
t = tf.expand_dims(t, axis = 0)
print(t)
# 增加第四维度
t = tf.expand_dims(t, axis = 3)
print(t)
tf.Tensor(
[[-1.4346067  -0.69587547]
 [-2.1144965   0.55389005]], shape=(2, 2), dtype=float32)
tf.Tensor(
[[[-1.4346067  -0.69587547]
  [-2.1144965   0.55389005]]], shape=(1, 2, 2), dtype=float32)
tf.Tensor(
[[[[-1.4346067 ]
   [-0.69587547]]
  [[-2.1144965 ]
   [ 0.55389005]]]], shape=(1, 2, 2, 1), dtype=float32)

从结果可以看出,增加了两个维度

使用tf.squeeze()可以减少张量的维度

import tensorflow as tf

t = tf.constant([[[[1], [2]]]])
print(t)
# 减少最后一个维度
t = tf.squeeze(t, axis = 3)
print(t)
tf.Tensor(
[[[[1]
   [2]]]], shape=(1, 1, 2, 1), dtype=int32)
tf.Tensor([[[1 2]]], shape=(1, 1, 2), dtype=int32)

这里需要注意,减少的维度必须是1

(1, 2, 2, 2) 不能减少第四维度,即不能减少为(1, 2, 2, 2),但可以减少第一维度变成(2 ,2 ,2)

(8) 维度交换

使用tf.expand_dims()可以增加张量的维度

import tensorflow as tf

t = tf.zeros((1, 28, 28, 1))
print(t)
t = tf.transpose(t, [2, 3, 1, 0])
print(t)
[[[[ ... ]]]], shape=(1, 28, 28, 1), dtype=float32)
[[[[ ... ]]]], shape=(28, 1, 28, 1), dtype=float32)

每一个维度对应一个下标,从0开始

(1, 28, 28, 1) -> (0, 1, 2, 3)

tf.transpose()函数通过写下标的序号,把对应的维度进行交换

(2, 3, 1, 0) -> (28, 1, 28, 1)

4. 字符串张量

方法作用
tf.strings.as_string(input, precision, scientific)转为字符串张量
tf.strings.bytes_split(input, name)分割每一个字符
tf.strings.split(input, sep)按照指定字符分割字符串
tf.strings.join(inputs, separator)字符串拼接
tf.strings.upper(input, encoding)将字符串转为大写
tf.strings.lower(input, encoding)将字符串转为小写

(1) 转为字符串张量

import tensorflow as tf

string = tf.constant([1.0, 2.0])
print(string)
t = tf.strings.as_string(string)
print(t)
t = tf.strings.as_string(string, precision = 3)
print(t)
tf.Tensor([1. 2.], shape=(2,), dtype=float32)
tf.Tensor([b'1.000000' b'2.000000'], shape=(2,), dtype=string)
tf.Tensor([b'1.000' b'2.000'], shape=(2,), dtype=string)

(2) 字符串分割

import tensorflow as tf

string = tf.constant('H e l l o')
print(tf.strings.bytes_split(string))
print(tf.strings.split(string, ' '))
tf.Tensor([b'H' b' ' b'e' b' ' b'l' b' ' b'l' b' ' b'o'], shape=(9,), dtype=string)
tf.Tensor([b'H' b'e' b'l' b'l' b'o'], shape=(5,), dtype=string)

(3) 字符串拼接

import tensorflow as tf

string = tf.constant([b'H' b' ' b'e' b' ' b'l' b' ' b'l' b' ' b'o'])
print(tf.strings.join(string))
tf.Tensor(b'H e l l o', shape=(), dtype=string)

(3) 字符串大小写转换

import tensorflow as tf

string = tf.constant('aaa')
upper = tf.strings.upper(string)
lower = tf.strings.lower(string)
print(upper)
print(lower)
tf.Tensor(b'AAA', shape=(), dtype=string)
tf.Tensor(b'aaa', shape=(), dtype=string)

5. 不规则张量

方法作用
tf.ragged.constant(pylist, dtype)创建不规则张量
tf.ragged.map_flat_values(op, *args)对不规则张量进行数学变换

(1) 创建不规则张量

使用tf.ragged.constant()创建不规则张量

import tensorflow as tf

t = tf.ragged.constant([[1, 2], [], [1, 2, 3]])
print(t)
<tf.RaggedTensor [[1, 2], [], [1, 2, 3]]>

不规则张量类似Java中的数组,每一行的元素个数可以不一致

不规则张量中的所有元素类型必须是一致的

(2) 不规则张量的运算

import tensorflow as tf

t = tf.ragged.constant([[1, 2], [], [1, 2, 3]])
print(t + 2)
print(tf.subtract(t, 2))
print(t * 2)
print(tf.divide(t, 2))
<tf.RaggedTensor [[3, 4], [], [3, 4, 5]]>
<tf.RaggedTensor [[-1, 0], [], [-1, 0, 1]]>
<tf.RaggedTensor [[2, 4], [], [2, 4, 6]]>
<tf.RaggedTensor [[0.5, 1.0], [], [0.5, 1.0, 1.5]]>

同样的,不规则张量也支持普通张量的四则运算、乘法、开平方等

相同形状的不规则张量之间可以做四则运算、乘法、开平方等

import tensorflow as tf

a = tf.ragged.constant([[1, 2], []
import tensorflow as tf
import os
os.environ[TF_CPP_MIN_LOG_LEVEL] = 2#把报错的这个警告等级降低
#图:默认已经注册,一组表示tf.Operation(节点)计算单元的对象和tf.Tensor(张量)操作之间的数据单元的对象,所以一张图包含两个:
#一个是OP一个是Tensor
#获取一个图的方法有:tf.get_default_graph()
a = tf.constant(8.0)
b = tf.constant(5.0)
sum1 = tf.add(a,b)
gra = tf.get_default_graph() #<tensorflow.python.framework.ops.Graph object at 0x000001F51CBD9438>
                             #说白了其实还是给你一个地址,你以后的操作的程序就在这个内存块内进行
print(gra)
with tf.Session() as sess:
    print(sess.run(sum1)) #打印13
    #接下来我们看看每个Operation的图也就是地址是不是在一起的,答案是一样的,都在这个地址上0x000001F7992AA438>
    print(a.graph)
    print(sum1.graph)
    print(sess.graph)

#哪些是Operation呢:标量运算(加减乘除等数学运算);向量运算;矩阵运算;带状态的运算;神经网络的组件;控制流等等
#只要是使用tensorflow的API定义的函数都是OP,例如上边的a,b,sum1,gra等等
#什么是Tensor呢:就是指的是数据,例如上边的a = tf.constant(8.0)中的8.0就是Tensor类型的
#所以可以抽象的理解成:OP是一个载具,Tensor是一个被载的数据
import tensorflow as tf
import os
os.environ[TF_CPP_MIN_LOG_LEVEL] = 2#把报错的这个警告等级降低
#placeholder是一个占位符,feed_dict是一个字典
plt = tf.placeholder(tf.float32,[None,3])#一个未知维列表,未知的行但是有3列张量类型是tf.float32
with tf.Session() as sess:
    print(sess.run(plt,feed_dict={plt:[[1,2,3],[4,5,6]]}))

#哪些是Operation呢:标量运算(加减乘除等数学运算);向量运算;矩阵运算;带状态的运算;神经网络的组件;控制流等等
#只要是使用tensorflow的API定义的函数都是OP,例如上边的a,b,sum1,gra等等
#什么是Tensor呢:就是指的是数据,例如上边的a = tf.constant(8.0)中的8.0就是Tensor类型的
#所以可以抽象的理解成:OP是一个载具,Tensor是一个被载的数据
#run()方法:run(fetches,feed_dict=None,graph=None):是运行OP和Tensor
#参数:fetches是嵌套的列表,元组
#参数:feed_dict允许调用者覆盖图中指定的张量的值,提供给placeholder使用

张量的动态形状和静态形状:

张量的静态形状:创建一个张量初始状态的形状,方法有:tf.get_shape():获取静态的形状,tf.set_shape() :更新Tensor对象的静态形状

张量的动态形状:描述原始张量在执行过程中的一种形态,tf.reshape():创建一个不同动态的新张量

import tensorflow as tf
import os
os.environ[TF_CPP_MIN_LOG_LEVEL] = 2#把报错的这个警告等级降低

plt = tf.placeholder(tf.float32,[None,3])
shape1 = plt.get_shape()
print(shape1)  #(?, 3)
plt.set_shape([4,3])
print(plt.get_shape()) #(4, 3)
#再次设置形状,他会报错,对于静态形状来说只能设置一次形状
plt.set_shape([5,3])
print(plt.get_shape()) #(4, 3)


with tf.Session() as sess:
    pass

接下来试验一下张量的动态性状:需要特别注意的是:动态完后的元素个数和分配前是一样 的,4 * 3 = 3 * 4

import tensorflow as tf
import os
os.environ[TF_CPP_MIN_LOG_LEVEL] = 2#把报错的这个警告等级降低

plt = tf.placeholder(tf.float32,[None,3])
shape1 = plt.get_shape()
print(shape1)  #(?, 3)
plt.set_shape([4,3])
print(plt.get_shape()) #(4, 3)
#再次设置形状,他会报错,对于静态形状来说只能设置一次形状
# plt.set_shape([5,3])
# print(plt.get_shape()) #(4, 3)
#接下来就是动态形状了
plt_reshape = tf.reshape(plt,[3,4])
print(plt_reshape.get_shape()) #(3, 4)

with tf.Session() as sess:
    pass

总结一下:

1.转化静态形状的时候一维只能到一维,二维只能到二维,三维只能到三维

2.对于已经固定的静态形状的张量或者变量,不能再次设置他的静态形状

3.tf.reshape(张量对象,[新设置的维度]),元素的个数不能不匹配

 

以上是关于学习Tensorflow之基本操作的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记TF061:分布式TensorFlow,分布式原理最佳实践

谷歌移动端深度学习框架 TensorFlow Lite 正式发布

最受欢迎机器学习框架“王座”之争:PyTorch “存在感”已直逼 Tensorflow

学习Tensorflow之基本操作

[学习笔记] TensorFlow 入门之基本使用

深度 | TensorFlow开源一周年:这可能是一份最完整的盘点