tensorflow基础2

创建4维张量

x = tf.random.normal([4,32,32,3])

取第 1 张图片的数据

x[0]

取第 1 张图片的第 2 行

x[0][1]

取第 1 张图片,第 2 行,第 3 列的数据

x[0][1][2]

取第 3 张图片,第 2 行,第 1 列的像素, B 通道(第 2 个通道)颜色强度值

x[2][1][0][1]

取第 2 张图片,第 10 行,第 3 列的数据

x[1,9,2]

切片

读取第 2,3 张图片

x[1:3]

读取第一张图片

x[0,::]

x[:,0:28:2,0:28:2,:]

考虑一个 0~9 的简单序列向量, 逆序取到第 1 号元素,不包含第 1 号

创建 0~9 向量

x = tf.range(9)

从 8 取到 0,逆序,不包含 0

x[8:0:-1]

逆序全部元素

x[::-1]

逆序间隔采样

x[::-2]

读取每张图片的所有通道,其中行按着逆序隔行采样,列按着逆序隔行采样

x = tf.random.normal([4,32,32,3])

行、列逆序间隔采样

x[0,::-2,::-2]

取 G 通道数据

x[:,:,:,1]

读取第 1~2 张图片的 G/B 通道数据

高宽维度全部采集

x[0:2,…,1:]

读取最后 2 张图片

高、宽、通道维度全部采集,等价于 x[2:]

x[2:,…]

读取 R/G 通道数据

所有样本,所有高、宽的前 2 个通道

x[…,:2]

维度变换

改变视图

生成向量

x=tf.range(96)

改变 x 的视图,获得 4D 张量,存储并未改变

x=tf.reshape(x,[2,4,4,3])
x

改变视图

我们通过 tf.range()模拟生成一个向量数据,并通过 tf.reshape 视图改变函数产生不同的视图

生成向量

x = tf.range(96)

改变 x 的视图,获得 4D 张量,存储并未改变

x = tf.reshape(x,[2,4,4,3])
x

获取张量的维度数和形状列表

x.ndim,x.shape

通过 tf.reshape(x, new_shape),可以将张量的视图任意地合法改变

tf.reshape(x,[2,-1])

tf.reshape(x,[2,4,12])

tf.reshape(x,[2,-1,3])

增、删维度

产生矩阵

x = tf.random.uniform([28,28],maxval=10,dtype=tf.int32)
x

通过 tf.expand_dims(x, axis)可在指定的 axis 轴前可以插入一个新的维度

axis=2 表示宽维度后面的一个维度

x = tf.expand_dims(x,axis=2)
x

x = tf.expand_dims(x,axis=0) # 高维度之前插入新维度
x

x = tf.squeeze(x, axis=0) # 删除图片数量维度
x

x = tf.random.uniform([1,28,28,1],maxval=10,dtype=tf.int32)
tf.squeeze(x) # 删除所有长度为 1 的维度

交换维度

x = tf.random.normal([2,32,32,3])

交换维度

tf.transpose(x,perm=[0,3,1,2])

x = tf.random.normal([2,32,32,3])

交换维度

tf.transpose(x,perm=[0,2,1,3])

复制数据

创建向量 b

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

插入新维度,变成矩阵

b = tf.expand_dims(b, axis=0)
b

样本维度上复制一份

b = tf.tile(b, multiples=[2,1])
b

x = tf.range(4)

创建 2 行 2 列矩阵

x=tf.reshape(x,[2,2])
x

列维度复制一份

x = tf.tile(x,multiples=[1,2])
x

行维度复制一份

x = tf.tile(x,multiples=[2,1])
x

Broadcasting

创建矩阵

A = tf.random.normal([32,1])

扩展为 4D 张量

tf.broadcast_to(A, [2,32,32,3])

A = tf.random.normal([32,2])

不符合 Broadcasting 条件

try:
tf.broadcast_to(A, [2,32,32,4])
except Exception as e:
print(e)

数学运算

加、减、乘、除运算

a = tf.range(5)
b = tf.constant(2)

整除运算

a//b

余除运算

a%b

乘方运算

x = tf.range(4)

乘方运算

tf.pow(x,3)

乘方运算符

x**2

x=tf.constant([1.,4.,9.])

平方根

x**(0.5)

x = tf.range(5)

转换为浮点数

x = tf.cast(x, dtype=tf.float32)

平方

x = tf.square(x)

平方根

tf.sqrt(x)

指数和对数运算

x = tf.constant([1.,2.,3.])

指数运算

2**x

自然指数运算

tf.exp(1.)

x = tf.exp(3.)

对数运算

tf.math.log(x)

x = tf.constant([1.,2.])
x = 10**x

换底公式

tf.math.log(x)/tf.math.log(10.)

矩阵相乘运算

a = tf.random.normal([4,3,28,32])
b = tf.random.normal([4,3,32,2])

批量形式的矩阵相乘

a@b

a = tf.random.normal([4,28,32])
b = tf.random.normal([32,16])

先自动扩展,再矩阵相乘

tf.matmul(a,b)

前向传播实战

import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow.keras.datasets as datasets

plt.rcParams[‘font.size’] = 16
plt.rcParams[‘font.family’] = [‘STKaiti’]
plt.rcParams[‘axes.unicode_minus’] = False

def load_data():
# 加载 MNIST 数据集
(x, y), (x_val, y_val) = datasets.mnist.load_data()
# 转换为浮点张量, 并缩放到-1~1
x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
# 转换为整形张量
y = tf.convert_to_tensor(y, dtype=tf.int32)
# one-hot 编码
y = tf.one_hot(y, depth=10)

# 改变视图, [b, 28, 28] => [b, 28*28]
x = tf.reshape(x, (-1, 28 * 28))

# 构建数据集对象
train_dataset = tf.data.Dataset.from_tensor_slices((x, y))
# 批量训练
train_dataset = train_dataset.batch(200)
return train_dataset

def init_paramaters():
# 每层的张量都需要被优化,故使用 Variable 类型,并使用截断的正太分布初始化权值张量
# 偏置向量初始化为 0 即可
# 第一层的参数
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
# 第二层的参数
w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
b2 = tf.Variable(tf.zeros([128]))
# 第三层的参数
w3 = tf.Variable(tf.random.truncated_normal([128, 10], stddev=0.1))
b3 = tf.Variable(tf.zeros([10]))
return w1, b1, w2, b2, w3, b3

def train_epoch(epoch, train_dataset, w1, b1, w2, b2, w3, b3, lr=0.001):
for step, (x, y) in enumerate(train_dataset):
with tf.GradientTape() as tape:
# 第一层计算, [b, 784]@[784, 256] + [256] => [b, 256] + [256] => [b,256] + [b, 256]
h1 = x @ w1 + tf.broadcast_to(b1, (x.shape[0], 256))
h1 = tf.nn.relu(h1) # 通过激活函数

        # 第二层计算, [b, 256] => [b, 128]
        h2 = h1 @ w2 + b2
        h2 = tf.nn.relu(h2)
        # 输出层计算, [b, 128] => [b, 10]
        out = h2 @ w3 + b3

        # 计算网络输出与标签之间的均方差, mse = mean(sum(y-out)^2)
        # [b, 10]
        loss = tf.square(y - out)
        # 误差标量, mean: scalar
        loss = tf.reduce_mean(loss)

        # 自动梯度,需要求梯度的张量有[w1, b1, w2, b2, w3, b3]
        grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])

    # 梯度更新, assign_sub 将当前值减去参数值,原地更新
    w1.assign_sub(lr * grads[0])
    b1.assign_sub(lr * grads[1])
    w2.assign_sub(lr * grads[2])
    b2.assign_sub(lr * grads[3])
    w3.assign_sub(lr * grads[4])
    b3.assign_sub(lr * grads[5])    

return loss.numpy()

def train(epochs):
losses = []
train_dataset = load_data()
w1, b1, w2, b2, w3, b3 = init_paramaters()
for epoch in range(epochs):
loss = train_epoch(epoch, train_dataset, w1, b1, w2, b2, w3, b3, lr=0.001)
print(‘epoch:’, epoch, ‘loss:’, loss)
losses.append(loss)

x = [i for i in range(0, epochs)]
# 绘制曲线
plt.plot(x, losses, color='blue', marker='s', label='训练')
plt.xlabel('Epoch')
plt.ylabel('MSE')
plt.legend()
plt.show()

train(epochs=20)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值