第四章 TensorFlow 基础 笔记2

4.6 索引与切片

4.6.1 索引

和numpy的索引一样

x = tf.random.normal([4,32,32,3])
#取第一章图片的,第二行,第三类的rgb向量
x[0,1,2]
#输出为
<tf.Tensor: id=9, shape=(3,), dtype=float32, numpy=array([-0.3177959 , -2.0918367 , -0.67390585], dtype=float32)>

4.6.2 切片

通过start:end:step切片方式可以方便地提取一段数据,其中start为开始读取位置的索引,end为结束读取位置的索引(不包含end位),step为步长。

x = tf.random.normal([4,32,32,3])
#读取第2,3张图片
x[1:3]

使用:来替代start, end, steps时,表示全部都取,

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

4.7 维度变换

基本的维度变换包含了改变视图reshape,插入新维度expand_dims,删除维度squeeze,交换维度transpose,复制数据tile等。

4.7.1 Reshape

x = tf.range(96)
x = tf.reshape(x,[2,4,4,3])
x
#输出结果为
<tf.Tensor: id=19, shape=(2, 4, 4, 3), dtype=int32, numpy=
array([[[[ 0,  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, 46, 47]]],


       [[[48, 49, 50],
         [51, 52, 53],
         [54, 55, 56],
         [57, 58, 59]],

        [[60, 61, 62],
         [63, 64, 65],
         [66, 67, 68],
         [69, 70, 71]],

        [[72, 73, 74],
         [75, 76, 77],
         [78, 79, 80],
         [81, 82, 83]],

        [[84, 85, 86],
         [87, 88, 89],
         [90, 91, 92],
         [93, 94, 95]]]])>

4.7.2 增删维度

\textbf{增加维度}
增加一个长度为1的维度相当于给原有的数据增加一个新维度的概念,维度长度为1,故数据并不需要改变,仅仅是改变数据的理解方式。

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

感觉这个

tf.reshape(x,[28,28,1])

结果一样。

\textbf{删除维度}
是增加维度的逆操作,与增加维度一样,删除维度只能删除长度为1的维度,也不会改变张量的存储。

x = tf.random.normal([1,28,28,1])
tf.squeeze(x,axis=0)

4.7.3 交换维度

交换维度操作是非常常见的,比如在 TensorFlow中,图片张量默认存储格式是通道后行格式:[b,h,w,c],但是部分库的图片格式是通道先行:[b,c,h,w]

通过 tf.transpose(x,perm) 完成维度交换操作,其中 perm 表示新维度的顺序 List。

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

4.7.4 数据复制

当通过增加维度操作插入新维度后,可能希望在新的维度上面复制若干份数据,满足后续算法的格式要求。

考虑\mathbf{Y} = \mathbf{X}@\mathbf{W} + \mathbf{b}的例子,偏置\mathbf{b}插入新维度后,需要在新维度上复制 batch size份数据后,才能完成张量相加。

考虑\mathbf{X}\in \mathbb{R}^{2\times 4}\mathbf{W}\in \mathbb{R}^{4\times 3},为了完成加法,\mathbf{b}的形状也应该是2\times 3

但是\mathbf{b}的定义为:
\mathbf{b} = \left[ \begin{array}{c} b_{0}\\b_{1}\\b_{2} \end{array} \right]
所以需要把\mathbf{b}变成一个2\times 3的矩阵,如下所示:
B = \left[ \begin{array}{ccc} b_{0} & b_{1} & b_{2}\\ b_{0} & b_{1} & b_{2} \end{array} \right]

通过 tf.tile(b,multiples)函数完成数据在指定维度上的复制操作。(对应位置为1表明不复制,为2表明新长度为原来的长度的2倍

 b = tf.constant([1,2,3])
b = tf.expand_dims(b,axis=0)
b
#输出结果为
<tf.Tensor: id=52, shape=(1, 3), dtype=int32, numpy=array([[1, 2, 3]])>
b = tf.tile(b,multiples=[2,1])
b
#输出结果为
<tf.Tensor: id=54, shape=(2, 3), dtype=int32, numpy=
array([[1, 2, 3],
       [1, 2, 3]])>

tf.tile会创建一个新的张量来保存复制后的张量,由于复制操作涉及到大量数据的读写\mathbf{IO}运算,计算代价太高,而且神经网络中不同 shape 之间的运算操作十分频繁,所以常常用 Broadcasting(广播)操作。

4.8 Broadcasting

Broadcasting 也叫广播机制(自动扩展也行更合适),它是一种轻量级张量复制的手段,在逻辑上扩展张量数据的形状,但是只要在需要时才会执行实际存储复制操作。

对于大部分场景,Broadcasting 机制都能通过优化手段避免实际复制数据而完成逻辑运算,从而相对于 tf.tile 函数,减少了大量计算代价。

x = tf.random.normal([2,4])
w = tf.random.normal([4,3])
b = tf.random.normal([3])
y = x @ w + b
y
#输出结果为
<tf.Tensor: id=74, shape=(2, 3), dtype=float32, numpy=
array([[-1.6606035 ,  0.35164022,  0.66946125],
       [ 0.6017679 ,  1.4871141 , -2.0808659 ]], dtype=float32)>

这里面自动调用了 Broadcasting 函数 tf.broadcast_to(x, new_shape)。

4.9 数学运算

4.9.1 加减乘除

加减乘除是最基本的数学运算,分别通过 tf.add,tf.subtract,tf.multiply,tf.divide 函数实现;或者直接用运算符

整除和余数也是常见的运算之一,分别通过//%运算符实现,如下:

a = tf.range(5)
b = tf.constant(2)
a // b
#输出结果为
<tf.Tensor: id=80, shape=(5,), dtype=int32, numpy=array([0, 0, 1, 1, 2])>
a%b
#输出结果为
<tf.Tensor: id=81, shape=(5,), dtype=int32, numpy=array([0, 1, 0, 1, 0])>

4.9.2 乘方

通过 tf.power(x,a)实现y=x^{a}乘方运算,也可以通过运算符 ** 实现 x ** a运算,

x=tf.range(4)
tf.pow(x,3)
#输出结果为
<tf.Tensor: id=87, shape=(4,), dtype=int32, numpy=array([ 0,  1,  8, 27])>
x ** 3
#输出结果为
<tf.Tensor: id=89, shape=(4,), dtype=int32, numpy=array([ 0,  1,  8, 27])>

通过设置指数为\frac{1}{a}形式即可实现根号运算:x^{\frac{1}{a}}

x = tf.constant([1.,4.,9.])
x ** (0.5)
#输出结果为  
<tf.Tensor: id=95, shape=(3,), dtype=float32, numpy=array([1., 2., 3.], dtype=float32)>

特别地,对于平方和平方根运算,可以用 tf.square(x) 和 tf.sqrt(x) 实现。

4.9.3 指数,对数

  • 通过 tf.pow(a,x) 或者 ** 运算符实现运算 a^{x}
  • 通过 tf.exp(x) 实现自然对数e^{x}
  • 通过 tf.math.log(x) 实现自然对数 log_{e}(x)
  • 通过对数换底公式 log_{a} x=\frac{log_{e}x}{log_{a}x}实现计算其他底数的对数

4.9.4 矩阵相乘

通过 @ 运算符和 tf.matmul(a,b)实现矩阵运算。

4.10 前向传播实战

w1 = tf.Variable(initial_value=tf.random.truncated_normal([784,256],stddev=0.1))
b1 = tf.Variable(initial_value=tf.zeros([256]))
w2 = tf.Variable(initial_value=tf.random.truncated_normal([256,128],stddev=0.1))
b2 = tf.Variable(initial_value=tf.zeros(128))
w3 = tf.Variable(initial_value=tf.random.truncated_normal([128,10],stddev=0.1))
b3 = tf.Variable(tf.zeros([10]))
(x_train,y_train),(x_val,y_val) = datasets.mnist.load_data()
x_train = tf.reshape(x_train,[-1,28*28])
x_train = tf.dtypes.cast(x_train,tf.float32)
y_train = tf.one_hot(y_train,depth=10)
lr = 0.1
Loss = []
for i in range(100):
    with tf.GradientTape() as tape:
        h1 = tf.matmul(x_train,w1) + b1
        h1 = tf.nn.relu(h1)
        h2 = tf.matmul(h1,w2) + b2
        h2 = tf.nn.relu(h2)
        h3 = tf.matmul(h2,w3) + b3
        loss = (y_train - h3)** 2
        loss = tf.reduce_mean(loss)
        grads = tape.gradient(loss,[w1,b1,w2,b2,w3,b3])
        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.append(loss)
        print(f"step:{i},loss:{loss}")

参考资料:https://github.com/dragen1860/Deep-Learning-with-TensorFlow-book

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容