Tensorflow学习三---基础操作

本文详细介绍了TensorFlow的基础操作,包括数据类型、张量的基本概念、数据类型转换、索引切片、维度变换等核心内容,并通过实例展示了如何进行数学运算及实现简单的前向传播。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Tensorflow学习三—基础操作

Tensorflow包含的数据类型

常见的数据类型载体:
python : list
[1,1.2,“hello”,(1,2)]
numpy : np.array
tensorflow : tf.Tensor

tf.Tensor:

scalar: 1.1
vector(数组): [1.1],[1.1, 2.2, … ]
matrix(矩阵): [[1.1, 2.2],[3.3, 4.4],[5.5, 6.6]]
tensor: 𝑟𝑎𝑛𝑘 > 2(维度大于2)

tensor的数据类型有:int, float, double,bool,string
例子:
1、常数

input:(tf.constant(1))
tf.Tensor(1, shape=(), dtype=int32)
input:(tf.constant(1.))
tf.Tensor(1.0, shape=(), dtype=float32)
input:(tf.constant(2.2,dtype=tf.double))
tf.Tensor(2.2, shape=(), dtype=float64)
input:(tf.constant([True,False]))
tf.Tensor([ True False], shape=(2,), dtype=bool)
input:(tf.constant('hddd'))
tf.Tensor(b'hddd', shape=(), dtype=string)

2、常量值函数
tf.fill(dims, value, name=None)
参数:

  • dims: 类型为int32的tensor对象,用于表示输出的维度(1-D, n-D),通常为一个int32数组,如:[1], [2,3]等
  • value: 常量值(字符串,数字等),该参数用于设置到最终返回的tensor对象值中
  • name: (可选)当前操作别名

3、选择设备数据

with tf.device("cpu"):
    a = tf.constant([1])
with tf.device('gpu'):
    b = tf.range(4)
/job:localhost/replica:0/task:0/device:CPU:0
/job:localhost/replica:0/task:0/device:GPU:0    

4、等差数组

a = np.arange(5)
a = tf.range(5)

5、其他

#转为Tensor
aa = tf.convert_to_tensor(a)
aa = tf.convert_to_tensor(a,dtype=tf.int32)
#数据类型转换
tf.cast(aa,dtype=tf.float32)

a = tf.range(5)
b=tf.Variable(a)  #将Tensor有可导属性
print(b.name,b.trainable)
#Variable:0   True

索引切片

索引(indexing)

常规的索引方式:

a = tf.ones([1,5,5,3])
print(a[0][0])
print(a[0][0][0])

numpy索引方式:

a = tf.random.normal([4,28,28,3])
print(a[1].shape)
print(a[1,2].shape)

切片

1、start:end

a = tf.range(10)
#tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32)
print(a)
print(a[-1:])

2、start : end : step

 = tf.random.normal([4,28,28,3])
print(a[:,0:28:2,:,0].shape)
#(4, 14, 28)
print(a[:,::2,::2,:].shape)
#(4, 14, 14, 3)  0:28:2

3 、…

a = tf.random.normal([2,4,28,28,3])
print(a[0,:,:,:,:].shape)
print(a[0,...].shape)
#(4, 28, 28, 3)

4、tf.gather收集:根据索引收集采样数据

a = tf.random.normal([4,35,8])
#(原,axis=维度,维度的索引)
print(tf.gather(a,axis=0,indices=[2,3]).shape)
#(2, 35, 8)

5、tf.gather_nd

a = tf.random.normal([4,35,8])
print(tf.gather_nd(a,[0]))
print(tf.gather_nd(a,[0,1]))
print(tf.gather_nd(a,[0,1,2]))
print(tf.gather_nd(a,[[0,1,2]]))
print(tf.gather_nd(a,[[0,1],[1,1]]).shape)
#(2, 8)

5、tf.boolean_mask
定义mask

a = tf.random.normal([4,28,28,3])
print(tf.boolean_mask(a,mask=[True,True,False,False]).shape)
#(2, 28, 28, 8)
print(tf.boolean_mask(a,mask=[True,True,False],axis=3).shape)
#(4, 28, 28, 2)

维度变换

每个Tensor都是有一个shape的,例如之前的MNIST数据集来说它的shape就是[b,28,28,1]->[batch,weight,height,channed]。
view(视图):每个数据都是有多种View的看法,例子:
[b,28,28]
[b,28*28]
[b,28,28,1]
1、reshape:

a = tf.random.normal([4,28,28,3])
print(tf.reshape(a,[4,784,3]).shape)
#当你不知道原来的数据的大小就可以使用-1自动计算
print(tf.reshape(a,[4,-1,3]).shape)
#后一个[]恢复大小
print(tf.reshape(a,([4,-1]),[2,28,28,3]).shape)

2、tf.transpose 转置 改变视图

a = tf.random.normal((4,3,2,1))
print(tf.transpose(a).shape)
print(tf.transpose(a,perm=[0,3,2,1]).shape)

这个常用在pytoc<->tensorflow
pytoch中[b,3,h,w] tensorflow[b,h,w,c]
3、expand dim

a = tf.random.normal([4,35,8])
print(tf.expand_dims(a,axis=0).shape)
#(1, 4, 35, 8)

4、squeeze dim

a=tf.zeros([1,2,3,1,2])
print(tf.squeeze(a).shape)
#(2, 3, 2)
print(tf.squeeze(a,axis=0).shape)
#(2, 3, 1, 2)

Broadcasting

什么是Braodcasting,张量维度的扩张手段,他和tf.tile形成对比,它是对张量维度复制但没复制真实数据。
1、使用环境
当两个不同维度的张量进行相加的时候,Tensorflow会自动调用Broadcasting来进行补齐,
或者使用tf.broadcast_to。
2、具体使用流程
当两个不同维度的进行相加的时候小维度对齐,大维度依次补齐。
3、意义
简洁,节省内存

a = tf.random.normal([4,32,32,3])
print((a+tf.random.normal([3])).shape)

#tf.broadcast_to
b=tf.broadcast_to(tf.random.normal([4,1,1,1]),[4,32,32,3])
print(b.shape)

4、broadcast vs tile

a=tf.ones([3,4])
a1=tf.broadcast_to(a,[2,3,4])
print(a1)
"""
tf.Tensor(
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]], shape=(2, 3, 4), dtype=float32)
"""
a2=tf.expand_dims(a,axis=0)
a2=tf.tile(a2,[2,1,1])
print(a2)
"""
tf.Tensor(
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]], shape=(2, 3, 4), dtype=float32)
"""

数学运算

1、+ - * / // %
2、** pow square sqrt
3、exp log
4、@, matmul 矩阵乘法

向前传播(张量)

作为总结编写一个前向传播使用张量的形式,而不是用层的形式。
依旧是采用之前MNIST数据集的例子。

(x, y), _ = datasets.mnist.load_data()
# x: [0~255] => [0~1.]
x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
y = tf.convert_to_tensor(y, dtype=tf.int32)

print(x.shape, y.shape, x.dtype, y.dtype)
print(tf.reduce_min(x), tf.reduce_max(x))
print(tf.reduce_min(y), tf.reduce_max(y))


train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128)
train_iter = iter(train_db)
sample = next(train_iter)
print('batch:', sample[0].shape, sample[1].shape)


# [b, 784] => [b, 256] => [b, 128] => [b, 10]
# [dim_in, dim_out], [dim_out]
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]))

训练+测试

for epoch in range(10): # iterate db for 10
    for step, (x, y) in enumerate(train_db): # for every batch
        # x:[128, 28, 28]
        # y: [128]

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

        with tf.GradientTape() as tape: # tf.Variable
            # x: [b, 28*28]
            # h1 = x@w1 + b1
            # [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

            # compute loss
            # out: [b, 10]
            # y: [b] => [b, 10]
            y_onehot = tf.one_hot(y, depth=10)

            # mse = mean(sum(y-out)^2)
            # [b, 10]
            loss = tf.square(y_onehot - out)
            # mean: scalar
            loss = tf.reduce_mean(loss)

        # compute gradients
        grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
        # print(grads)
        # w1 = w1 - lr * w1_grad
        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])


        if step % 100 == 0:
            print(epoch, step, 'loss:', float(loss))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值