第十二章 Tensorflow-自定义模型与训练
目录
# 使用jupyter编写
# 打印版本信息
import sys, time
import tensorflow as tf
print(f"time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
print(f"python version: {sys.version.strip().split(' ')[0]}")
print(f"tensorflow verson: {tf.__version__}")
time: 2021-02-21 09:39:32
python version: 3.8.6
tensorflow verson: 2.4.1
12.2 TensorFlow基础使用
12.2.1 张量与操作
TensorFlow的API是基于tensorflow.Tensor对象(张量)来操作的, Tensor的使用与numpy.ndarray的使用基本一样
使用tenserflow.constant() 创建Tensor常量
Tensor的值是常量,无法修改
tf.constant([[1., 2., 3.], [0, 5, 10]])
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[ 1., 2., 3.],
[ 0., 5., 10.]], dtype=float32)>
tf.constant(100)
<tf.Tensor: shape=(), dtype=int32, numpy=100>
Tensor的属性
# 形状 shape
matrix = tf.constant([[1, 3, 0], [-3, 1, 200]])
scalar = tf.constant(50)
matrix.shape, scalar.shape
(TensorShape([2, 3]), TensorShape([]))
print(matrix)
tf.Tensor(
[[ 1 3 0]
[ -3 1 200]], shape=(2, 3), dtype=int32)
# 数据类型dtype
matrix.dtype, scalar.dtype
(tf.int32, tf.int32)
Tensor的索引
# 取出1行(从0开始数)
matrix[1]
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([ -3, 1, 200], dtype=int32)>
# 取出第1行
matrix[1, :]
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([ -3, 1, 200], dtype=int32)>
# 取出 0 行 1 列 的数据
matrix[0][1]
<tf.Tensor: shape=(), dtype=int32, numpy=3>
# 取出 0行 1 列的数据
matrix[0, 1]
<tf.Tensor: shape=(), dtype=int32, numpy=3>
# 取出第1列(列从0开始数)
matrix[:, 1]
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([3, 1], dtype=int32)>
# 使用 ... 切片, 避免写多个 :, 代表多个维度
matrix[..., 1]
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([3, 1], dtype=int32)>
# 使用 tensorflow.newaxis 自动增加一个维度,例如下面将一维的[3, 1] 转成 二维的 [[3], [1]]
matrix[..., 1, tf.newaxis]
<tf.Tensor: shape=(2, 1), dtype=int32, numpy=
array([[3],
[1]], dtype=int32)>
… 切片的详细说明
# 0维度 3, 1 维度 3 , 2维度 5
import numpy as np
t = tf.constant(np.arange(1, 46).reshape(5, 3, 3))
t
<tf.Tensor: shape=(5, 3, 3), dtype=int64, numpy=
array([[[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9]],
[[10, 11, 12],
[13, 14, 15],
[16, 17, 18]],
[[19, 20, 21],
[22, 23, 24],
[25, 26, 27]],
[[28, 29, 30],
[31, 32, 33],
[34, 35, 36]],
[[37, 38, 39],
[40, 41, 42],
[43, 44, 45]]])>
# 获取0维度第下标为1的全部值
# 等价于t[:, :, 1]
t[..., 1]
<tf.Tensor: shape=(5, 3), dtype=int64, numpy=
array([[ 2, 5, 8],
[11, 14, 17],
[20, 23, 26],
[29, 32, 35],
[38, 41, 44]])>
示意图:
# 等价操作
t[:, :, 1]
<tf.Tensor: shape=(5, 3), dtype=int64, numpy=
array([[ 2, 5, 8],
[11, 14, 17],
[20, 23, 26],
[29, 32, 35],
[38, 41, 44]])>
# 获取第2维度,下标为 1 的值
# 等价于t[1, :, :]
t[1, ...]
<tf.Tensor: shape=(3, 3), dtype=int64, numpy=
array([[10, 11, 12],
[13, 14, 15],
[16, 17, 18]])>
示意图:
t[1, :, :]
<tf.Tensor: shape=(3, 3), dtype=int64, numpy=
array([[10, 11, 12],
[13, 14, 15],
[16, 17, 18]])>
# 使用 tensorflow.newaxis增加维度
t1 = t[..., 1] # 此时维度已经下降, 但有时候我们需要保持维度不变,newaxis很容易做到
print(t1)
t1.shape
tf.Tensor(
[[ 2 5 8]
[11 14 17]
[20 23 26]
[29 32 35]
[38 41 44]], shape=(5, 3), dtype=int64)
TensorShape([5, 3])
# 此时维度已经下降, 但有时候我们需要保持维度不变,newaxis很容易做到
t2 = t[..., 1, tf.newaxis] # 在后面一个维度回来
t2
<tf.Tensor: shape=(5, 3, 1), dtype=int64, numpy=
array([[[ 2],
[ 5],
[ 8]],
[[11],
[14],
[17]],
[[20],
[23],
[26]],
[[29],
[32],
[35]],
[[38],
[41],
[44]]])>
t3 = t[tf.newaxis, ..., 1] #也可以在前面增加一个维度
t3
<tf.Tensor: shape=(1, 5, 3), dtype=int64, numpy=
array([[[ 2, 5, 8],
[11, 14, 17],
[20, 23, 26],
[29, 32, 35],
[38, 41, 44]]])>
Tensor数学运算操作
t = tf.constant([[1.,3.], [-2, 1]])
t
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[ 1., 3.],
[-2., 1.]], dtype=float32)>
t + 10
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[11., 13.],
[ 8., 11.]], dtype=float32)>
t * 2
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[ 2., 6.],
[-4., 2.]], dtype=float32)>
t / 10
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[ 0.1, 0.3],
[-0.2, 0.1]], dtype=float32)>
print(t)
ts = tf.square(t) # 平方
ts
tf.Tensor(
[[ 1. 3.]
[-2. 1.]], shape=(2, 2), dtype=float32)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[1., 9.],
[4., 1.]], dtype=float32)>
print(t)
tt = tf.transpose(t) # 转置
print(tt)
tf.Tensor(
[[ 1. 3.]
[-2. 1.]], shape=(2, 2), dtype=float32)
tf.Tensor(
[[ 1. -2.]
[ 3. 1.]], shape=(2, 2), dtype=float32)
# 矩阵点乘
a = t @ tt
a
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[10., 1.],
[ 1., 5.]], dtype=float32)>
12.2.3 数据类型转换
tensorflow不会自动执行数据类型的转换, 如果数据类型不一致则会报错
t = tf.constant([1, 3])
t
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 3], dtype=int32)>
# 使用tensorflow.cast()转换数据类型
t1 = tf.cast(t, tf.float32)
t1
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1., 3.], dtype=float32)>
12.2.4 变量(tensorflow.Variable类)
Variable的基本操作与Tensor的相似
v = tf.Variable([[1., 2., 3.], [0, 8, 9]])
v
<tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=
array([[1., 2., 3.],
[0., 8., 9.]], dtype=float32)>
# 改变单个值
v[0, 0].assign(100)
v
<tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=
array([[100., 2., 3.],
[ 0., 8., 9.]], dtype=float32)>
# 改变多个值, 例如 索引为 1 的列, 传入的值shape要符合
v[:, 1].assign([55, 66])
v
<tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=
array([[100., 55., 3.],
[ 0., 66., 9.]], dtype=float32)>
# 全部值变更
v.assign(v * 2)
v
<tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=
array([[200., 110., 6.],
[ 0., 132., 18.]], dtype=float32)>