深度学习1——tensorflow基本操作

tensorflow2.0 基本操作——学习笔记1

文章是个人自学深度学习时的学习记录,代码在jupyter notebook上运行的,在后续学习过程中会继续积累更新

import tensorflow as tf
import numpy as np

创建tensor

tf.convert_to_tensor,其他数据类型转换为tensor格式
tf.convert_to_tensor(np.ones([2, 3]))  # [2, 3]是数组的维度
tf.convert_to_tensor([[2], [3.0]])
# tf.convert_to_tensor([2, (3, 3)])  #报错
tf.zeros/zeros_like/ones/ones_like, 传入shape或like需数据,按数据的shape生成
tf.zeros([2, 3, 3])  # 3D
a = tf.zeros([2, 3, 3])
tf.zeros_like(a)
tf.fill([2, 3], 5)  # [2, 3]是shape, 5为value
tf.random, 随机生成tensor
tf.random.normal([2, 3], mean=1, stddev=2)  # 均值mean, 方差stddev分别默认为0, 1
# 在truncated_normal中,在区间(μ-2σ,μ+2σ)之外则重新进行选择,这样保证生成的值都在均值附近
tf.random.truncated_normal([2, 3], mean=1, stddev=2, )  # 截断正态分布,截断的标准是2倍的stddev
tf.random.uniform([2, 3], minval=0, maxval=10)  # 均匀分布
 # tensor数据随机打乱
idx = tf.range(5)
idx1 = tf.random.shuffle(idx)  # 随机打乱

a = tf.random.normal([5, 10])
b = tf.random.uniform([5], minval=1, maxval=10, dtype=tf.int32)

a1 = tf.gather(a, idx1)
b1 = tf.gather(b, idx1)
constant/variable 常量与变量
tf.constant([1, 2])
# tf.constant([[1], [2, 3]])  # 报错
tf.Variable([[2,3], [4, 5]])
# scalar 例子:loss
out = tf.random.uniform([4, 10])
y = tf.range(4)
y = tf.one_hot(y, depth=10)

loss = tf.keras.losses.mse(y, out)
loss = tf.reduce_mean(loss)
loss
# vector, 例子:一维数据
# matrix, 例子:二维数据
net = tf.keras.layers.Dense(10)  # 转为[b, 10]
net.build((4, 8))  # 输入维度为(4, 8); 4为样本数量
net.kernel, net.bias  # w, shape为(8, 10)  # b, shape为(10,)
# Dim=3 tensor  例子:处理自然语言
# x: [b(句子数量), seq_len(句子中单词的数量), word_dim(单词的编码长度)]

# Dim=4 tensor  例子:处理图片
# image: [b, h, w, 3]  h高度,w宽度, 3 RGB  b 样本数量
# feature maps: [b, h, w, c]

# Dim=5 tensor 例子:
# Single task: [b, h, w, 3]
# meta-learning:[task_b, b, h, w, 3]

索引与切片

index取值
b = tf.random.normal([4, 28, 28, 3])  # 图片数据格式
b[0][0][0]  # 数据shape[3, ]
b[1, 2, 3]  # 第二张照片的第三行第四列
b[0, :, :, :]  # 等价于 b[0]  b[0, ...]
b[:, :, :, 0]
b[:, 0:28:2, 0:28:2, :]
b[2::-2]
gather/gather_nd/boolean_mask, 需要用到indices
# data: [classes, students, subjects]
ts = tf.random.normal([4, 35, 8])
# gather(data(数据集), axis(指定维度), indices(指定索引))只能指定一个维度
tf.gather(ts, axis=0, indices=[2, 3])  # 取2,3班级的学生成绩
tf.gather(ts, axis=0, indices=[2, 1, 3, 0])  # 按其他顺序取班级的学生成绩
tf.gather(ts, axis=1, indices=[2, 3, 7, 9, 16])
tf.gather(ts, axis=2, indices=[2, 5, 6])
# 多个维度指定,用gather_nd
tf.gather_nd(ts, [0])
tf.gather_nd(ts, [0, 1])
tf.print(tf.gather_nd(ts, [0, 1, 2]))  # scalar
tf.gather_nd(ts, [[0, 1, 2]])  # shape (1, )
tf.gather_nd(ts, [[0, 0], [1, 1]])  # shape(2, 8)
tf.gather_nd(ts, [[0, 0, 0], [1, 1, 1]])  # shape(3, )
tf.gather_nd(ts, [[[0, 0, 0], [1, 1, 1]]])  # shape(1, 2)
# bool取值,用boolean_mask
img = tf.random.normal([2, 4, 4, 3])
tf.boolean_mask(img, mask=[True, False])  # mask的维度数目要与数据的一样
tf.boolean_mask(img, mask=[[True, False, False, False],
                           [False, False, False, True]])

维度变换

# [b, 28, 28]  view, 增加channel通道[b, 28, 28, 3]
# [b, 28*28]  content
img = tf.random.normal([4, 28, 28, 3])
img.shape, img.ndim
# reshape  改变维度个数
tf.reshape(img, [4, 784, 3])
tf.reshape(img, [4, -1, 3])
tf.reshape(img, [4, 784 * 3])  # 丢失行,列,channel的信息
tf.reshape(img, [4, -1])
# transpose  维度之前交换
tf.transpose(img)  # shape为[3, 28, 28, 4]
tf.transpose(img, perm=[0, 3, 1, 2])  # shape为[4, 3, 28, 28]
# expand_dims 增加维度
a = tf.random.normal([4, 35, 8])
tf.expand_dims(a, axis=0)  # shape[1, 4, 35, 8]
tf.expand_dims(a, axis=1)  # shape[4, 1, 35, 8]
tf.expand_dims(a, axis=-1)  # shape[4, 35, 8, 1]
# squeeze 去除维度为1的
a = tf.zeros([1, 2, 1, 3])
tf.squeeze(a)  # shape (2, 3)
tf.squeeze(a, axis=0)  # shape (2, 1, 3)
tf.squeeze(a, axis=2)  # shape (1, 2, 3)
# broadcast_to
# a, b 维度不一致, [4, 16, 32]与[32]  小维度相等才能对齐,再扩展
# [32]==>[1, 1, 32]==>[4, 16, 32]
a = tf.ones([3, 4])
a1 = tf.broadcast_to(a, [2, 3, 4])  # shape(2, 3, 4)

数学运算

# +  -  *  /
# **   pow   square   sqrt
tf.pow(2, 3)
# //   %
# exp   log (以e为底)
tf.exp(2.)
tf.math.log(2.)
tf.math.log(8.) / tf.math.log(2.)  # 以2为底8的log
# @    matmul  [b, 3, 4]@[b, 4, 5]
a = tf.random.normal([3, 3, 4])
b = tf.random.normal([3, 4, 5])
b1 = tf.random.normal([4, 5])
tf.matmul(a, b)
tf.matmul(a, b1)  # 先broadcast:[4, 5] ==> [1, 4, 5] ==> [3, 4, 5]
# linear   layer

合并与分割

# tf.concat  其他维度一样
a = tf.ones([4, 35, 8])
b = tf.ones([2, 35, 8])
c = tf.concat([a, b], axis=0)  # [6, 35, 8]
# tf.stack 维度相等 增加一个维度
a = tf.ones([4, 35, 8])
b = tf.ones([4, 35, 8])
c = tf.stack([a, b], axis=0)  # [2, 4, 35, 8]
# tf.unstack 均匀拆分
aa, bb = tf.unstack(c, axis=0)
tf.unstack(c, axis=3)  # 均匀拆层8个[2,4,35]
# tf.split 指定组分数目拆分
tf.split(c, axis=3, num_or_size_splits=2)  # 分成两个[2,4,35,4]
tf.split(c, axis=3, num_or_size_splits=[2, 2, 4])  # 分成三组

数据统计

# 范数
a = tf.ones([4, 28, 28, 3])
tf.norm(a)  # 二范数
tf.sqrt(tf.reduce_sum(tf.square(a)))
tf.norm(a, ord=2, axis=1)  # 指定轴方向求解二范数
tf.norm(a, ord=1, axis=0)  # 指定轴方向求解一范数
# reduce_mean/max/min/sum
tf.reduce_min(a)  # 所有维度求最小值
tf.reduce_min(a, axis=1)  # 指定维度求最小值
# argmax/min
a = tf.random.normal([4, 28, 28, 3])
tf.argmax(a)  # 最大值的位置索引,默认第一个维度
# equal  返回bool值
a = tf.constant([1, 2, 3, 2, 5])
b = tf.range(5)

# 计算a与b的值相等的个数,用于计算准确度
tf.reduce_sum(tf.cast(tf.equal(a, b), dtype=tf.int32))  
# 准确度计算
x = tf.constant([[0.1, 0.2, 0.7], [0.9, 0.05, 0.05]]) # 两个样本数的输出
y = tf.constant([2, 1])  # 样本的标签

pred = tf.cast(tf.argmax(x, axis=1), dtype=tf.int32)  # 预测样本的标签
correct = tf.reduce_sum(tf.cast(tf.equal(y, pred), dtype=tf.int32)) / len(y)
print(correct)
# unique  返回去重后的tensor和之前的元素在现在的tensor中索引
b = tf.constant([4, 2, 2, 4, 3])
tf.unique(b).y,  tf.unique(b).idx #tensor [4, 2, 3], 索引[0, 1, 1, 0, 2]
# tf.gather(tf.unique(b), [0, 1, 1, 0, 2])  # 还原

张量排序

# Sort/argsort
a = tf.random.shuffle(tf.reshape(tf.range(6), [2, 3]))
tf.sort(a, direction='DESCENDING')  # 默认最后一个维度排序
tf.argsort(a, direction='DESCENDING')  # 排序前元素的索引的降序排列
# tf.gather(a, tf.argsort(a, direction='DESCENDING'))  # 也可以达到排序的效果
# Top_k 默认最后一个维度
res = tf.math.top_k(a, 2)  # 取前两个
res.indices  # 最大的几个值的索引
res.values  # 最大的几个值
prob = tf.constant([[0.1, 0.2, 0.7], [0.2, 0.7, 0.1]])
target = tf.constant([2, 0])

k_b = tf.math.top_k(prob, 3).indices
k_b = tf.transpose(k_b, [1, 0])
k_b
target = tf.broadcast_to(target, [3, 2])
# 计算Top_k的准确度的例子
def accuracy(out, target, topk=(1,)):
    maxk = max(topk)
    batch_size = target.shape[0]

    pred = tf.math.top_k(out, maxk).indices
    print(pred.numpy())
    pred = tf.transpose(pred, perm=[1, 0])
    target_ = tf.broadcast_to(target, pred.shape)
    correct = tf.equal(pred, target_)  # [k, b]

    res = []
    for k in topk:
        correct_k = tf.cast(tf.reshape(correct[:k], [-1]), dtype=tf.float32)
        correct_k = tf.reduce_sum(correct_k)
        acc = float(correct_k / batch_size)
        res.append(acc)

    return res


out = tf.random.normal([10, 6])
out = tf.math.softmax(out, axis=1)  # 使六类的总和为1
target = tf.random.uniform([10], maxval=6, dtype=tf.int32)
pred = tf.argmax(out, axis=1)
print('pred', pred.numpy())
print('label', target.numpy())

acc = accuracy(out, target, topk=(1, 2, 3, 4, 5, 6))
print('top-1-6 acc', acc)

填充与复制

# pad
a = tf.ones([2, 3])
tf.pad(a, [[1, 1], [2, 2]])  # 上下增加1, 左右增加2
# tile复制
a = tf.constant([[1, 2, 0], [3, 4, 5]])
tf.tile(a, [1, 2])  # 指定维度方向的复制次数
tf.tile(a, [2, 2])  # 先复制小维度

张量的限幅

# maximun/minimum/clip_by_value
tf.maximum(a, 3)  # 超3,等于3
tf.clip_by_value(a, 1, 3)  # >=1,<=3
tf.nn.relu(a)  # >=0
# clip_by_norm
tf.clip_by_norm(a, 3)  # 先除以范数,再乘以3
# clip_by_global_norm 用于gradient exploding or vanishing
# grads, _ = tf.clip_by_global_norm(grads, 25)

高阶操作

where
a = tf.random.normal([3, 3])

mask = a > 0
tf.boolean_mask(a, mask)
indices = tf.where(mask)  # 返回True 的坐标
tf.gather_nd(a, indices)
A = tf.ones([3, 3])
B = tf.zeros([3, 3])
tf.where(mask, A, B)  # true 选A中对应的位置值
tf.where(tf.greater(A, B), A, B)
scatter_nd
indices = tf.constant([[4], [3], [1], [7]])  # 索引值
updates = tf.constant([9, 10, 11, 12])  # 需要插入的值
shape = tf.constant([8])  # 维度

tf.scatter_nd(indices, updates, shape)
meshgrid 生成网格的坐标
x = tf.linspace(-1., 1., 3)
y = tf.linspace(-2., 2., 5)

point_x, point_y = tf.meshgrid(x, y)
points = tf.stack([point_x, point_y], axis=2)
point_x,point_y, points

你可能感兴趣的:(深度学习系列,tensorflow,深度学习)