龙曲良 Tensorflow —— tensorflow基础操作(自用)-1

目录

一、数据类型概念

1.1 相关类型

1.2 tf.constant(数据创建和判断)

1.3 tf.cast、tf.convert_to_tensor(类型转换)

1.4 tf.Variable

1.5 转换成 Numpy

二、创建 Tensor

2.1 From Numpy , List 

2.2 tf.zeros , tf.ones,Fill

2.3 随机化创建

2.3.1 tf.random.normal(分布初始化采样)

2.3.2 tf.random.uniform(均匀采样)

2.3.3 tf.random.shuffle(数据打散)

2.3.4 tf.constant

2.4 各种 shape 的 Tensor

2.4.1 Scalar(标量)

2.4.2 Vector(向量)

2.4.3 Matrix(矩阵)

2.4.4 Dim = 3 Tensor

2.4.5 Dim = 4 Tensor(图片)

2.4.6 Dim = 5 Tensor

三、索引与切片

3.1 单个索引 [idx][idx][idx]

3.2 单个索引 [idx, idx, idx] 

3.3 范围索引  [A : B) 和 [ : ]

3.4 间断索引(双冒号,即 : :)

3.5 三个点  . . .

3.6 selective indexing

3.6.1 tf.gather

3.6.2 tf.gather_nd 

3.6.3 tf.boolean_mask

四、维度变换

4.1 View概念

4.2 tf.reshape

4.3 tf.transpose

4.4 增加、减少维度( Expend dim 和 Squeeze dim )

4.4.1 tf.expend_dims

4.4.2 tf.squeeze

五、Broadcasting(张量维度扩张)

5.1 tf.broadcast_to

5.2 tf.tile

六、数学运算

6.1 加减乘除(+,-,*,/,%,//)

6.2 tf.math.log , tf.exp

6.3 平方,开方(pow,sqrt) 

6.4 矩阵相乘(@ matmul)

七、前向传播实战使用

7.1 代码


一、数据类型概念

1.1 相关类型

numpy 不支持 gpu 

scalar:数学上讲一个零位的数据,如 1.1,2,3,就是一个准确的数据类型

实际上都可以叫做 tensor

1.2 tf.constant(数据创建和判断)

当创建一个 2.2,却指定 int 类型的话就会报错

cpu 和 gpu 上tensor 的区别就是,对于cpu上的只能cpu操作,gpu的只能gpu操作

ndim 显示的是 维度

name 参数是没有什么意义的

判断是不是tensor 用 isinstance is_tensor

判断类型也可以如:a.dtype ==  tf.float32

1.3 tf.cast、tf.convert_to_tensor(类型转换)

numpy的类型 和 tensor 也可以转换

还有 cast 转换函数

整形和布尔型转换

1.4 tf.Variable

如 y = wx + b

x,y 都是 tensor类型;而 w 和 b 都是需要被梯度优化的参数,所以他们除了是 tensor 类型以外,还有一个 Variable 属性

相当于把 原本的tensor类型的 w 用 w = tf.Variable(w) 包一下,这样 w 就自动具备一个可求导特性

如下的 w 就具有了 name 和 trainbale(即可训练的意思) 两个属性

但用 isinstance 显示 false,is_tensor 显示 true,所以 isinstance 不推荐使用

1.5 转换成 Numpy

.numpy() ,或者可以直接如 int(b),float(b)

二、创建 Tensor

2.1 From Numpy , List 

2.2 tf.zeros , tf.ones,Fill

tf.zeros_like(a) 根据传过来的 shape 建立全 0 的, 等同于tf.zeros(a.shape) 

2.3 随机化创建

2.3.1 tf.random.normal(分布初始化采样)

mean:均值 , stddev:方差

truncated_normal:是个截断的,截断部分区间

2.3.2 tf.random.uniform(均匀采样)

均匀采样

2.3.3 tf.random.shuffle(数据打散)

可用于有对应关系的

gather 对有对应关系的数据进行打乱

2.3.4 tf.constant

tf.constant(1):创建一个标量

tf.constant([1]):创建一个向量

2.4 各种 shape 的 Tensor

2.4.1 Scalar(标量)

类似 loss 、 accuracy  

2.4.2 Vector(向量)

kernel 是 w,初始化是随机的

bias 是 b,初始化是 0

2.4.3 Matrix(矩阵)

2.4.4 Dim = 3 Tensor

2.4.5 Dim = 4 Tensor(图片)

2.4.6 Dim = 5 Tensor

如,有 4 个任务,每个人物 64 张图片,每个图片 28 × 28 ×1

三、索引与切片

3.1 单个索引 [idx][idx][idx]

3.2 单个索引 [idx, idx, idx] 

3.3 范围索引  [A : B) 和 [ : ]

[ : ] :表示取所有维度

如下 a[0] 相当于 a[0, :, :, :]

3.4 间断索引(双冒号,即 : :)

(1)范围隔行用法     ::

(2)逆序     :: -1 / -2

3.5 三个点  . . .

3.6 selective indexing

        如下,[4, 28, 28, 3],低于第一个28,我们不直接从A到B取索引,而是单独取其中的第3,27,9,13行,这就是切片indices,就用到了gather的功能,这里是取了4行,gather也就是收集的意思

3.6.1 tf.gather

假设有4个班级,每个班级35个学生,每个学生8门课程

axis 给出了要取哪个维度

indices 给出了 索引号

3.6.2 tf.gather_nd 

        如果要获得 多少个学生的多少个学科的成绩,那么该如何实现?

        比如要得到,4个班级 7个学生 3门课的成绩,首先可以通过 两个gather 串联实现

        但如果 要取第2个学生的第0门课,第3个学生的第4门课,第8个学生的第2门课这种,用两个gather的方法就无法实现

        如下 4个班级的4个学生的成绩,就有 [4, 8] 个数据,相当于是在多个维度,指定了index,gather是在某一个维度

        如下,tf.gather_nd(a, [0]) 表示在 [ [ ]  [ ]  [ ] ] 取第一个维度 [0] 的全部,所以是 [35, 8],返回的是维度

        最后的 tf.gather_nd(a, [ [0, 1, 2] ]) 输出的是 成绩的一个具体值,标量,所以是1

3.6.3 tf.boolean_mask

四、维度变换

4.1 View概念

        了解view 的概念,如下的 view1和 view2,view1 是有一个长和宽的概念,而view2 则是把这个图片当成一个整体,view2不关注图片的具体二维信息,而是直接把图片的 rgb 的数据拿过来使用;view3 把图片分成了上下两部分;view4 只是多了一个 channel;这些view对图片原来的content内容没有改变

4.2 tf.reshape

        -1  是自动计算,使得满足原来尺寸

        784*3  是数据点的总数量

        如上,reshape 操作非常灵活,提供很多的可能性,但有没有具体的含义要具体来看

       但也可能带来潜在的问题,即把图片从 [4,28,28,3] 变成 [4,784,3] 后再变回  [4,28,28,3] 时,这是就需要原来图片 content 的信息 ,如下所示,把 height 和 width 维度记错 或 记混了

        上述都是在改变 view, 那么如何改变 content 呢?如将 h,w交换,或把 c 提到前面,这就用到一个函数:tf.transpose

4.3 tf.transpose

        与矩阵的转置类似,不设置参数就是全部转置,可以设置参数规定新的维度是什么,所以每一次的 view 必须跟踪相应的 content

4.4 增加、减少维度( Expend dim 和 Squeeze dim )

4.4.1 tf.expend_dims

        如下,要增加一个 school 的维度

4.4.2 tf.squeeze

五、Broadcasting(张量维度扩张)

        指对某一个维度重复多次,但是没有真正的复制一个数据

        如下 [b, 10] + [10] 得到的是 [b, 10] 的,但不能直接相加,要把 [10] 转换成一个 [b, 10] 的tensor,这个过程就是 broadcasting

broadcasting操作流程:

        如果 a,b 的 tensor 的 维度 dimension 不一致,如 [4,16,16,32] 和 [32] 相加,首先要把小维度对齐,左边大右边小,往前延伸插入维度,再把每个维度对齐,把1扩张为4,16

那么 broadcasting 到底代表什么意义?

       如假设要把英语和物理都加分,英语加5,物理加10,此时是小维度scores,此时创建出班级学生的维度[1,1,8] 在扩张

       而下一种情况是对学生0的成绩都加5分,就是把每个班级前两个学生的每个科目都加5分         

broadcasting的好处?

(1)写起来更加简洁

(2)节省更多内存

节省了 2^7 个字节数

什么是能够broadcasting的?

如下情形: 

5.1 tf.broadcast_to

        也可以通过调用 tf.broadcast_to 来完成维度的扩张,不调用就是自动完成

5.2 tf.tile

        tf.tile(a2, [2,1,1]) 把0维复制2次,1,2维复制1次就是没变,得到shape=(2,3,4)

a1和a2 在共用上面是等价的,但a2占用内存更大,a1实际上的内存区域是没有扩张复制的

     

六、数学运算

操作类型:

        (1)对某个具体的元素

        (2)对矩阵类型

        (3)对某个维度,某个轴

6.1 加减乘除(+,-,*,/,%,//)

6.2 tf.math.log , tf.exp

        tf.math.log 是 loge ,即 ln,没有log2,log10之类的

        所以 log2 要变一下得到,根据 log_a^b / log_a^c = log_c^b

        即 ln8 / ln2 = log_2^8 = 3

6.3 平方,开方(pow,sqrt) 

6.4 矩阵相乘(@ matmul)

七、前向传播实战使用

        如何屏蔽这些无用的信息呢?

        使用 os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

        0是全打印,2是只打印error的信息,这些信息是CPP打印出来的

7.1 代码

具体原理已省略

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


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

print('tensorflow版本号:', tf.__version__)
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]
# stddev = 0.1 方差变为0.1
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))  # truncated_normal 创建一个正态分布的
b1 = tf.Variable(tf.zeros([256]))
w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))  # truncated_normal 创建一个正态分布的
b2 = tf.Variable(tf.zeros([128]))
w3 = tf.Variable(tf.random.truncated_normal([128, 10], stddev=0.1))  # truncated_normal 创建一个正态分布的
b3 = tf.Variable(tf.zeros([10]))

lr = 1e-3  # 0.001 = 10^-3

for epoch in range(10): # iterate db for 10 对整个数据集迭代10次
    for step, (x,y) in enumerate(train_db): # for every batch对数据集每个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 类型,所以在上面 w,b 的前面加上 tf.Variable
                                         # 这两个类型是一样的,只是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 = x@w1 + b1
            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)  # 只需在 loss 计算之前 onehot 就行

            # 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])
        # 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])
        # 此时出现 loss:nan 梯度爆炸的情况,要在w,b初始化时,给一个范围,stddev = 0.1

        # w1 = w1 - lr * grads[0] # 对 w1 的求导结果,此时计算返回的是 tf.Tensor 类型,不是 tf.Variable 类型了
        #                         # 所以要进行原地更新的操作,使用 w1.assign_sub(lr * grads[0]),使引用保持不变
        # b1 = w1 - lr * grads[1]
        # w2 = w2 - lr * grads[2]
        # b2 = b2 - lr * grads[3]
        # w3 = w3 - lr * grads[4]
        # b3 = b3 - lr * grads[5]

        if step % 100 == 0:
            print(epoch, step, 'loss:', float(loss))  # 美100次打印一次

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
安装TensorFlow 1.4.0的方法是先下载对应的whl文件,然后使用pip进行安装。然而,目前我没有找到适用于Python 2.7的TensorFlow 1.4.0版本的whl文件。如果您想在低版本的Python中安装TensorFlow,您可以考虑使用TensorFlow 1.5.0版本的whl文件进行安装。您可以在网上搜索并下载适用于Python 2.7的TensorFlow 1.5.0版本的whl文件,然后按照安装教程进行安装。请注意,安装过程中可能会遇到一些问题,您可以参考相关的安装教程和临时添加镜像源的方法来解决这些问题。 #### 引用[.reference_title] - *1* [Windows+Python 2.7 成功安装 Tensorflow 1.4.0](https://blog.csdn.net/piupiu78/article/details/124658637)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [下载安装Anaconda及tensorflow1.4教程(自用)](https://blog.csdn.net/zjj_learning_path/article/details/126826732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [日常防忘:安装tensorflow_gpu-1.4.0](https://blog.csdn.net/weixin_45486448/article/details/109484600)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清园暖歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值