- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563431 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174252
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
7 b1 Z W" V- v7 D( k9 X$ O
Python深度学习之初窥神经网络2 O, Q1 t* M) \ `2 j& B$ q0 ]
本文为 第2章 开始之前:神经网络背后的数学 (Chapter 2. Before we begin: the mathematical building blocks of neural networks) 的笔记整合。
# {5 W" P* B m& \! H
8 Z$ n0 {7 i8 b( \" \5 M) M本文目录:
# Z* K7 A6 b7 {1 i3 W- w& M3 d/ I* x) P H% D2 s- C$ o
文章目录2 n; h7 s0 |8 S& k
' ~# U7 d2 l; PDeep Learning with Python
7 b" m+ [0 G$ \5 }4 ?初窥神经网络
+ H% k, e( T2 B! X: b导入MNIST数据集
! W0 V8 ]9 w1 X3 c1 V/ s$ \网络构建* |, v" d4 \! Y$ V2 z
编译) [! H& |! d: p4 H9 Z$ g N
预处理, A1 j. ]% C$ ^5 X- t
图形处理4 u- F# z6 C* u, _( c0 f
标签处理$ B7 e( Q2 ^' ^/ o0 a2 N
训练网络
1 K/ S5 A' m* {" }& [ v神经网络的数据表示
/ U% ?/ D3 \; t5 U; i# h: o认识张量
: ?5 Z0 G2 ]' E标量 (0D Tensors)' ^, o G+ O# W# K/ y4 ^/ R
向量 (1D Tensors)# {* K3 E+ `4 t9 m
矩阵 (2D Tensors)* A& ?* f+ J" f3 Q- H* L3 [
高阶张量
) t# r$ E9 Z( e8 s张量的三要素, [$ G- s" X3 y( W6 @# g# o: J
Numpy张量操作# ]& V5 l9 @8 [, z
张量切片:
* Y8 ]( U2 F4 J* a数据批量
/ X$ V( v s3 t8 O) g常见数据张量表示
% \/ C: M- a H2 @/ g5 {- o. v神经网络的“齿轮”: 张量运算
: t8 a# P" [0 X3 k) |' s逐元素操作(Element-wise)/ m. L. p) o& F3 p8 w$ ]6 h9 ^0 x
广播(Broadcasting)
# ]$ Y7 c! F, S% S. ~ q张量点积(dot)
! b* w8 k& z j- F0 _; B张量变形(reshaping)
. Y6 z5 t; `0 B' n' }/ Y& b+ H7 g神经网络的“引擎”: 基于梯度的优化
5 r# T' Y) W- ^; {8 V0 J7 }导数(derivative) \( d5 w' ^1 [7 B3 F( k0 @5 F: E6 [
梯度(gradient)2 `% v L' @+ e, u
随机梯度下降(Stochastic gradient descent): o3 H& W& s+ y) Q ~$ I& q
反向传播算法:链式求导' F0 o6 R# q; o$ N
本文由 CDFMLR 原创,收录于个人主页 https://clownote.github.io。0 o' s) k9 w6 ?+ a
5 O# i9 P: ?+ U% U
初窥神经网络
' V9 g, [. `. I' E
0 l) w0 \1 m J' V0 v7 z. f3 ]学编程语言从 “Hello World” 开始,学 Deep learning 从 MINST 开始。
+ ?" H6 S# Z: L' ^+ o5 R+ T
. @, [. b3 `& W! z3 ?; l* k2 FMNIST 用来训练手写数字识别, 它包含 28x28 的灰度手写图片,以及每张图片对应的标签(0~9的值)。
8 [6 m9 u5 w# [3 q: ?) [$ e1 u, F2 i
导入MNIST数据集
$ l9 z" W' T* y' Z$ r
# D$ H9 u" L5 Q4 f# Loading the MNIST dataset in Keras9 E/ C8 M3 f7 R0 G$ ~7 ^
from tensorflow.keras.datasets import mnist
( x% X& V, I" D5 h4 i9 a$ u(train_images, train_labels), (test_images, test_labels) = mnist.load_data(): W/ T, @$ q7 U: f2 D. u
1% I9 e: u7 ~+ _+ R
2
/ j5 l6 F6 @" L0 \) \7 V3
8 F* Z$ S* \( ?看一下训练集:3 D0 o/ G/ j6 E% ~$ @. x
6 O3 k) f4 U' o
print(train_images.shape)* C: d- z2 v3 ]
print(train_labels.shape)
- Y( R! E0 y1 Otrain_labels
0 t4 n a8 h$ c, N3 k* l14 [% w+ X- s: [8 ^1 Z0 O
2. b1 x& Q7 U! K0 \; T
3 P) X. u( }6 j: ?+ {0 l
输出:
$ q" o: ^0 [8 Z( ^6 m0 Y1 l# l3 s1 I! t' g! }6 t( c
(60000, 28, 28), C/ ^3 t' ~5 t% V% `1 |
(60000,)1 ^2 f) D# ~8 l1 ?$ D1 m
3 Y- D% c& ]& |* y# q$ b3 O5 r/ Tarray([5, 0, 4, ..., 5, 6, 8], dtype=uint8)( d& H' @, q% o' u
1! [! x8 \6 L2 C" o+ ?
2
! X. c A z7 V5 V5 [( a( A3
9 J8 N' w; [$ H, c3 J9 a3 B6 b3 K0 b1 U4$ F6 v5 F) A5 Y# I" D
这是测试集:9 x; ]/ }8 q) G( h, d# B
+ Z. C- t$ o1 xprint(test_images.shape)
; p. [) `; `) N" l3 Z a' sprint(test_labels.shape)
# N/ H6 m. z+ R, o* F Q9 Xtest_labels9 o( A6 C8 ?0 {! U
1
' ]1 R1 ?3 X5 j9 O& X+ B/ \28 \% F. U( K- I6 c. N
3
6 `8 J7 Q4 ]" T5 e0 P输出:- [! ^1 f2 d. @0 f7 U
. N; B8 H) W& A* s* @# p: j* M8 A(10000, 28, 28)3 T G- H' d* ~( d0 `* s
(10000,)
1 s" Z; Q! m. K/ R1 k- Q, T# j0 s* z' x2 k' [, f
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)
# \' |! u( g! k- S1$ G- Y$ Q* K7 V. ^
2
+ D% H9 ?# |: O3
4 d3 T1 `; _) J0 k& p. a5 Y( ~1 |4
9 n) H6 ~: i! w/ ^$ F1 m网络构建' C+ g7 I" n$ h, ~& \0 z
L Y3 v1 o" }, \4 o, i' }" W) F7 x
我们来构建一个用来学习 MNIST 集的神经网络:! ?% S+ m/ I1 x! Z3 F. G) M
' ], ^0 m& j' E: G! q! v8 B, mfrom tensorflow.keras import models
2 h3 V8 R/ |) f' S' a1 a, G4 Afrom tensorflow.keras import layers0 u0 l$ [9 x7 x# G W7 }
# E& f% I E7 E) C3 D" S( N8 qnetwork = models.Sequential()
+ V" u; }: D6 T1 Y5 a9 n! [network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28, )))+ t1 c% P; t8 c- L$ U3 k# U
network.add(layers.Dense(10, activation='softmax'))
$ o0 y9 m# f; L, E1 ^6 y1
: I* e1 y/ ~9 v/ ~+ E2% a3 M M5 b1 @
33 p+ C2 [; n6 b
4/ U" ~# e4 L5 ?8 R* g
5" Z, A5 }. m$ R9 p0 V8 y
6
5 {9 ~* ]' o7 ^神经网络是一个个「层」组成的。# Z, X' H; e2 ~
一个「层」就像是一个“蒸馏过滤器”,它会“过滤”处理输入的数据,从里面“精炼”出需要的信息,然后传到下一层。
$ G2 v% u! I) ~( A9 Z8 @% T
% J) U$ G1 @% j" ^, V# T% e$ G这样一系列的「层」组合起来,像流水线一样对数据进行处理。
4 ~0 ^2 Z* `+ s' V% F层层扬弃,让被处理的数据,或者说“数据的表示”对我们最终希望的结果越来越“有用”。6 y& @: Q5 k% c$ G
7 Q, d7 n m1 G; {6 i3 E+ w
我们刚才这段代码构建的网络包含两个「Dense 层」,这么叫是因为它们是密集连接(densely connected)或者说是 全连接 的。# k8 h- e4 _+ r: U* J
0 B$ g% x7 F# Y数据到了最后一层(第二层),是一个 10路 的 softmax 层。: E" I) _& a) I3 ]
这个层输出的是一个数组,包含 10 个概率值(它们的和为1),这个输出「表示」的信息就对我们预测图片对应的数字相当有用了。, L2 G- q+ u' e7 d1 d0 P
事实上这输出中的每一个概率值就分别代表输入图片属于10个数字(0~9)中的一个的概率!
4 Q4 Y% ^8 d# r# t5 g+ d9 }0 J+ T: g! n2 `8 c
编译0 B1 O5 F- z: E7 s* k$ ^+ W/ l, q
+ I6 h- r4 S' u接下来,我们要 编译 这个网络,这个步骤需要给3个参数:7 F- v& T' N4 R
5 h$ h6 ?; m8 e& j" o3 S
损失函数:评价你这网络表现的好不好的函数. L ^1 L- o6 P* f) X
优化器:怎么更新(优化)你这个网络% i/ \- R5 _" u. U4 W# o5 H
训练和测试过程中需要监控的指标,比如这个例子里,我们只关心一个指标 —— 预测的精度
! n! O$ r) C/ H( y% n) j1 snetwork.compile(loss="categorical_crossentropy",1 t9 a( Y( K% o5 d! q
optimizer='rmsprop',
* L$ p* a. U0 F9 Q6 o metrics=['accuracy'])0 Q2 i5 o+ h, K2 m- h* d" J
1
* d. A, k$ W3 u7 L4 d8 {2: S& V2 P" U3 j% O; k( h: F
3
+ M& m3 |4 T$ n0 d T+ O预处理6 F- Z6 L5 p) @4 o5 t
4 `+ Q4 J' A4 ? R3 ?% a; J% [图形处理! \: Q2 V2 n! h) i
7 Z( y+ e& f. e! f8 u9 p2 j我们还需要处理一下图形数据,把它变成我们的网络认识的样子。 h- @7 s; n' ^! K( q& p( A+ A' ?
6 K3 y4 V3 x* _1 X% ~
MNIST 数据集里的图片是 28x28 的,每个值是属于 [0, 255] 的 uint8。
4 H; x& _& z' M9 E% [而我们的神经网络想要的是 28x28 的在 [0, 1] 中的 float32。7 m* u" e$ i0 l
2 }; k1 T/ _0 ]0 E2 Htrain_images = train_images.reshape((60000, 28 * 28))0 t$ J4 v0 v" F- M
train_images = train_images.astype('float32') / 255. R/ O" S& A. s+ \
2 ^5 X9 z' e R! ~
test_images = test_images.reshape((10000, 28 * 28))" O. \6 G" e- h8 e
test_images = test_images.astype('float32') / 2559 J$ R# T9 g) Z3 y) E
1! |% S5 _1 ?3 e9 M- Z1 q
2
1 _. u5 q6 q& q( f* @3+ m/ J8 ~8 n# @- J& _! e
4
- h! _9 X( v5 Q4 V5
5 Z9 _6 G7 N; n# P" g* c$ s; X' @标签处理3 t$ j8 H" m4 g C7 h
6 X f3 R, d; [1 P( }
同样,标签也是需要处理一下的。
2 R' ?, O: I* q6 B& S" b Q( [ v
5 h* N' x' B' ] O/ ]5 G% afrom tensorflow.keras.utils import to_categorical
6 V: X# o5 c6 }1 r" k. d9 N! x* } [: \) d& n' T- v) w
train_labels = to_categorical(train_labels)
# Z# D/ a8 j, H0 e" Ztest_labels = to_categorical(test_labels)
S' {$ _0 s! {5 K3 [, S12 X- J9 `$ }, A" _0 |* W6 {- e" K
2# r5 J: s( |# y) g r* T/ S4 K9 @
3
% b6 a7 t. n: O4 c7 J S4 b+ }4& [& K" E1 k: w: r1 K: `
训练网络
# m; P* ~( Y3 a
, T8 ?. N$ `& S) b( E2 y/ ] I# `network.fit(train_images, train_labels, epochs=5, batch_size=128)
. Y1 x/ [2 Y/ J1! V9 e6 q4 ~& p1 L. e
输出:
1 V$ f7 N% f: w: N Y
% t8 ]9 \( Q7 M* ?" bTrain on 60000 samples$ I9 j0 s& y6 F) K
Epoch 1/5
/ ]/ v' R: J! W# q8 `6 c60000/60000 [==============================] - 3s 49us/sample - loss: 0.2549 - accuracy: 0.9254, I, r# s x0 {. s0 h7 {
Epoch 2/5: j; Q+ g' q; I5 t) d8 i V1 G- L
60000/60000 [==============================] - 2s 38us/sample - loss: 0.1025 - accuracy: 0.9693
$ l% q6 r6 t: r9 k. |Epoch 3/5 ?! I1 i' U* u g3 u
60000/60000 [==============================] - 2s 35us/sample - loss: 0.0676 - accuracy: 0.98008 @# O2 Z2 k* N1 e1 h* J2 m+ H
Epoch 4/57 C% b9 ]: ?" V5 }1 G2 c' m
60000/60000 [==============================] - 2s 37us/sample - loss: 0.0491 - accuracy: 0.9848( {- t' S }. I8 o N' j! J
Epoch 5/55 T$ ]8 @ z" f0 L' t- ^
60000/60000 [==============================] - 2s 42us/sample - loss: 0.0369 - accuracy: 0.98884 T. ]* g) C" \$ h) M: L
, P7 P2 ]/ _: C0 H
<tensorflow.python.keras.callbacks.History at 0x13a7892d0>
, x& Y$ h# H: [, H) k! p+ N2 q- p1
$ J0 n/ {8 c3 E6 M- o' {2, I: i j2 w M* F3 }0 G
3
! K+ Y6 a5 w' X) f% H$ P7 s4
, Y: n* t. S2 |5, u' J8 ~( @" E
6- x/ c& g7 ^. w7 d6 ~. n) j+ V
7: Z" k2 b: A3 T U5 R0 |) {) C
8
0 o4 V' L% a: Q1 X- D9
# N/ P0 Y4 O3 z( a$ y* ^10) ?3 H* D% W' z4 k
11 [5 Y0 w3 V" C; `
12
% r& Y- C* y+ N2 j2 F; C13$ d0 g) s. W$ c& K
可以看到,训练很快,一会儿就对训练集有 98%+ 的精度了。9 E" o) S7 L6 @, e
+ g: M! r! \- N' W) p3 S' e3 Q5 e, C再用测试集去试试:
# X; d- k; S4 g/ ^! @7 g7 [7 S I% @+ Y% N) @+ ^
test_loss, test_acc = network.evaluate(test_images, test_labels, verbose=2) # verbose=2 to avoid a looooong progress bar that fills the screen with '='. https://github.com/tensorflow/tensorflow/issues/32286
3 e. h% J, N/ F4 E4 J- k/ tprint('test_acc:', test_acc)
8 b% h2 y8 x3 x0 N2 X: E1; o- t! U' ^1 }. D5 T/ {
2
1 z; m- v7 g' }9 b输出:# g+ o. q/ [/ U
( ]( M* @) f8 N$ E) ~10000/1 - 0s - loss: 0.0362 - accuracy: 0.9789) f% t6 _8 w. |% @
test_acc: 0.9789
7 E1 h: b% v; Q# n0 A1 s2 f3 O1$ N( f9 g) Z5 c" \6 f. _
2
, y5 ]" {* ]- p" e! s5 {4 s3 t* }我们训练好的网络在测试集下的表现并没有之前在训练集中那么好,这是「过拟合」的锅。) K( Q: y ]! y8 }9 p& D, X% w
" A P& _9 q, b+ v2 ]
神经网络的数据表示+ v+ [, c- C# y, N- z, H
( T8 a0 X9 C) s% F; m. f0 S
Tensor,张量,任意维的数组(我的意思是编程的那种数组)。矩阵是二维的张量。* i! q/ Y9 O$ e+ b3 V7 G
( a' Y, U8 v' Z: b, \
我们常把「张量的维度」说成「轴」。" I' E) U/ I; U3 u$ d" K
3 d& T' i& G* [! s
认识张量+ X! O- \7 d, @0 ~! [$ L( Z
7 i% u. |. Q+ [' _6 @! L; \( R, N i
标量 (0D Tensors)
! |$ P8 M( i9 o# E( e: a+ l; E0 I$ h& r
Scalars,标量是 0 维的张量(0个轴),包含一个数。
3 l: }! x+ e* Q) I6 P' M2 M6 J1 u3 S" W' |" w
标量在 numpy 中可以用 float32 或 float64 表示。! v8 y& ]) G0 P2 e1 J
1 U# {! U1 k$ S) x
import numpy as np
# O- G0 I/ A. q
2 ?# r4 k3 Y% [x = np.array(12)
# ?3 P5 h, y1 m$ rx* t! ?8 T! T, Y: U# E( c
1
: i) A3 k, t! j- R# J9 n2
- K% ]9 o7 f, |6 x9 D2 T) p3
: S2 ^! Z4 ]- b7 M1 [4
- w# _( T+ N8 h' C6 ~% v5 I输出:# `2 B. Y9 j6 e J) D
* u& X( X+ U- `; `1 } H9 U$ Y6 b
array(12)2 b. J! c- Y7 o9 W$ C- \! C. i1 p! x
1
1 i# x5 U$ B$ m# c' M8 o3 px.ndim # 轴数(维数)/ H) c8 R8 D v; j4 B0 k2 X
1
4 P; z* B! g! n( A输出:
' V" ^% F/ b- t
# S0 g& {2 A3 k; W2 z1
3 }3 a5 |# r# k& d% M. m1
1 P$ @# `) m5 K向量 (1D Tensors)1 n2 K, t) C9 `+ b( n
+ S5 p5 ?3 E$ U2 PVectors,向量是 1 维张量(有1个轴),包含一列标量(就是搞个array装标量)。. o/ S: H! t& `- M1 Z/ H, `
y! A1 \- N5 Q& A4 E
x = np.array([1, 2, 3, 4, 5])) q9 \' }& ~" L. _. M) m9 e+ `
x
& }( c# D7 O; q {$ h1( S( g; V7 L# E" l3 q9 u" [
2
) b J- i! g5 ~4 \9 K输出:
8 Y/ r/ J9 E, g
! y+ ?! K V; y( xarray([1, 2, 3, 4, 5])! ~" w5 b4 m* K0 R
1/ K1 P& d% H3 |6 K
x.ndim! ~* W0 N5 U1 Y& T; ^& I& h4 X
1
U9 j* s8 c& H5 I* ]输出:- m4 H$ `' Y0 x* G$ [, n! c. g4 |
6 a. j0 z% p: R5 w/ u2 O% M
17 P) w% x1 q# z4 K; N9 }
19 ~. J2 c& }. H8 s0 o
我们把这样有5个元素的向量叫做“5维向量”。! J, f1 F7 ` O
但注意5D向量可不是5D张量!
1 \; t( s+ K H
9 s! J, ^8 A" R8 R+ q8 [5D向量:只有1个轴,在这个轴上有5个维度。
0 g2 ?7 N9 l$ B* P& ~: G2 X ^# d5D张量:有5个轴,在每个轴上可以有任意维度。! Z0 P7 ^* c* Z) _* A
这个就很迷,这“维度”有的时候是指轴数,有的时候是指轴上的元素个数。
1 d; m7 ]7 i0 W8 a; l5 Y6 q' _7 @* F% \2 g
所以,我们最好换种说法,用「阶」来表示轴数,说 5阶张量。. M+ H, S4 I7 Z+ z( o9 d- a2 c
4 C! L9 f2 X, _5 I* @ R; L矩阵 (2D Tensors)
2 ]9 C/ }% [# p2 G: b7 F7 d; [; I# l0 h4 i6 d6 U% H3 R( A2 O6 m
Matrices,矩阵是 2 阶张量(2个轴,就是我们说的「行」和「列」),包含一列向量(就是搞个array装向量)。5 x# `! g5 }; t% }
: ]9 p/ ?2 U2 B! Yx = np.array([[5, 78, 2, 34, 0],
- Z3 R% D) X0 i' g0 d- o. v3 C [6, 79, 3, 35, 1],- @( s9 O& j5 [- K X
[7, 80, 4, 36, 2]])
0 s3 R4 r1 w$ |& M9 z4 ?x
6 J6 d6 Q6 d R( r1 w1- @5 m: E$ z7 s) z5 ^: h. x) f
27 p( t+ M) d3 Q/ y7 d) N
3
1 m% W* A2 |* s9 q. u' {4
* g8 t" X6 W- I! G输出:/ _2 T. Q8 `( k
# e) c E) X4 b' H" ^. Q" o
array([[ 5, 78, 2, 34, 0],, J' p8 r6 P$ X7 x" ^5 y
[ 6, 79, 3, 35, 1],# l& S+ H5 C+ \( J" d6 X
[ 7, 80, 4, 36, 2]])3 `* C, s7 _& X; p/ X2 C
1, ~9 }- b4 S; |+ E" `+ n, y
2
4 G# z) a. i( o; Q7 q3
0 V6 U1 A" P& l9 e/ \8 z$ p5 gx.ndim
" v& w2 v- H0 Z: F6 Z j1( m* k2 ]. _. T1 s$ N' O0 U
输出:$ f U( r% p4 A6 g2 R, q
. K% v( p5 y/ t% _2' o( d- c. Y4 X6 u6 h
12 R$ b. C6 D* I
高阶张量
/ B$ }2 @$ l$ t6 f# E+ D& A8 {" [) A/ Q* _; ^5 z% C5 J! X9 ]
你搞个装矩阵的 array 就得到了3阶张量。: |; ?5 P, L1 T5 s: x
4 C U2 o" T H G
再搞个装3阶张量的 array 就得到了4阶张量,依次类推,就有高阶张量了。
% L, J$ R7 m7 Y' l. W5 W
6 f5 \$ g+ T" X- d+ dx = np.array([[[5, 78, 2, 34, 0],
7 R v$ Q+ ~) z' u [6, 79, 3, 35, 1],5 B6 u$ H) G) V. y& ~3 t
[7, 80, 4, 36, 2]],7 k m1 s' w% z: h/ C3 E1 }
[[5, 78, 2, 34, 0],
; M8 h2 l# @( ^" T0 ?) U [6, 79, 3, 35, 1],
7 I& `5 p* S, N" U3 g6 M [7, 80, 4, 36, 2]],# |0 m2 `; i) \! B9 Y
[[5, 78, 2, 34, 0],
0 l1 @7 o' Z. B9 e. B6 c% h [6, 79, 3, 35, 1],
1 [2 X* [' j2 o- W [7, 80, 4, 36, 2]]])
/ m7 k; c) {* B+ h( v9 b4 tx.ndim
$ O( Z/ e9 l3 O# K. J0 l1* [3 x/ U8 k" T* j) ]- x, ~
2
. g( u! u7 l" c3
' X1 T J4 b/ |; V+ t* s4 {/ ?4/ Y5 ]0 s! x+ v
5
1 Z2 }* L2 e( T9 d$ d' }6; w8 I0 W8 V# o) p
7
d7 u5 X, D6 o# [- M8
7 _# m0 r" p5 J9
$ K" h/ u& S- D3 k( L; G/ B3 W10# r* c- p; L6 D, r" G3 y3 o
输出:
) H" A X( V' p1 }& D( l; i) _9 X
3
( L* s- G# F k$ U$ b1' P7 D8 x: Y n
深度学习里,我们一般就用0~4阶的张量。
9 I. _1 `8 a6 u/ s, t9 Z7 D
, \2 {, L6 `: f) g3 J张量的三要素) h/ _' P) \% m: J
* C( i6 A1 p% n. E$ P/ }. N; k阶数(轴的个数):3,5,…
/ Z' v2 x& ~. D% B4 ]形状(各轴维数):(2, 1, 3),(6, 5, 5, 3, 6),…. F2 h: z" I( p, a$ w. R1 [
数据类型:float32,uint8,…( t6 X: t+ B6 [
我们来看看 MNIST 里的张量数据:
4 z: `3 h4 \* h$ r/ r2 }$ v* d, {! K
9 _* q' i$ Y2 |+ p0 |from tensorflow.keras.datasets import mnist
! R4 F& W; }; v0 K3 {(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
( s3 P& P& p4 h+ K
7 O* p3 {6 x/ R( s: Pprint(train_images.ndim)3 M, I( m+ H7 W9 C* z
print(train_images.shape)
) D/ T6 M9 R+ v/ R" K9 Z( yprint(train_images.dtype)
3 _' p/ ^% Q+ e8 p1
7 g/ ^& M2 W D/ e+ c2; F& i+ L K5 C% ]4 |# c
3( o/ e( K8 D6 s4 w/ ~
4
% T. T+ u+ S: M" h/ [% c6 l4 B# \54 Q+ m/ `5 D0 z8 m
6
+ d( m' ^' ^& v8 _输出:4 h* `3 v+ y' W* s9 r* t
$ Z9 M' o7 O+ J3
1 x _/ P' A9 }5 Q" D+ j(60000, 28, 28)( i" G' e9 N: I4 O; @
uint8
5 P' q4 Y+ S& z/ T- C1" y9 A( P6 {( Q) t* ]6 M% K
2
9 m) V/ |" j V& A1 H! T2 |% ]7 h3
6 o0 I+ ~! j9 c# B/ }所以 train_images 是个8位无符号整数的3阶张量。
/ N6 D K; @; ?5 z, O/ X
# Y, y/ D9 m l6 P+ v打印个里面的图片看看:$ x2 S ?; X# o, I
1 }7 E0 R5 j: F3 F# C5 a1 bdigit = train_images[0]
& F/ _) K2 \# d: ~: Q
& \- b" E" e! X( b8 S1 limport matplotlib.pyplot as plt! H' ~9 y9 H* B9 l( d
4 h% c6 d' U0 h+ P" {: p% s( p: mprint("image:")
/ I: K1 R4 j7 q. cplt.imshow(digit, cmap=plt.cm.binary)4 h/ @# @" ?& k3 m' `
plt.show()
$ F0 [8 X9 [: K' i* J; j5 o& O$ oprint("label: ", train_labels[0])+ M3 w9 j2 f, S4 ~& o3 c
1
+ q5 P# K8 J, D, W0 H2
+ |0 n7 _8 D( r5 M' ]. O5 N38 ]9 _( N, s5 v' Y* t
4
2 a A6 b3 g/ K( s, n" i3 w: ^( v& L5
1 }) O) S! x w* u/ v0 |) g6
+ l7 y1 E( f! r D# {7 `) y& E: h7
' s, i' Q- t2 a- u* T2 H8% o1 d' B/ s# P! g, y( [. \6 L
输出:
' z) K- ]- j. j$ x& t/ W5 G
; i7 _ K: E& H
2 o9 Q( `; v; z; O
9 `5 `9 B2 M" E
label: 59 {: |( H. A% N# }. ]+ W4 m1 D# n! r Y
1
7 Q3 i G; C$ x9 ONumpy张量操作 V* i/ ^( D/ Z) I2 Z
- E* A1 n& Z: [7 k3 o6 H张量切片:
; N) u: D5 E" d: F3 s+ `+ [9 Z' B6 G6 g; a! N2 `
my_slice = train_images[10:100]
4 F9 [& V# W8 p* Z9 Lprint(my_slice.shape)
; v4 J0 Q0 v) `" H1( G$ Z( C7 U/ P) w
2
* B# ^9 z7 Z4 V ?. ?输出:( X0 j9 O3 Y: } b
: q" D1 w# `7 {& G1 |
(90, 28, 28)$ S' W" }6 A. D6 n
1- Q/ W3 z5 u# Y" ~9 B
等价于:; ?; Y' Z( X6 Y
8 ~! B! b5 {0 N% U" g/ F( m3 P
my_slice = train_images[10:100, :, :]
* S1 K5 J$ N! P# F* b7 kprint(my_slice.shape)9 H) m! d* z! {' Y7 A, j; B3 ^
1
) J+ S! n* M+ z/ M27 D3 I/ j8 M7 x) V" G: A" X
输出:
3 _* ?3 H8 S% h- L
% t- x7 p& b# B+ P3 v& N& n(90, 28, 28)
( R2 W. L( @( J" U5 R1
0 ~; \# E1 r, x. T也等价于/ f8 S1 t9 @+ ]1 r
- H! H' l8 C! i% y9 B% {. n
my_slice = train_images[10:100, 0:28, 0:28]4 N' f4 i; N- J9 a5 k: u2 k6 f% K/ q
print(my_slice.shape)/ A3 |0 d" Z! Y, ^9 |; r
13 h9 d U) K# m T$ B) A
20 x% p6 ?5 Y5 z, h
输出:* Y5 v) i/ H) x8 M# F- x
& }, @" J8 @3 k# T c% ^(90, 28, 28)
Q" @& X2 Y( A& K' g8 A% N1% B C8 ?: S$ |$ X' q# M
选出 右下角 14x14 的:# x. f# n$ x6 D& Z/ Q- }. E
- d- U2 F' V' w) S# e3 S- `3 k8 G9 P
my_slice = train_images[:, 14:, 14:]- ~( j0 _2 I# V. L4 n9 s( Q
plt.imshow(my_slice[0], cmap=plt.cm.binary): I* i4 k/ N$ ^3 g/ a( g
plt.show()3 K) j9 w& x; A' G2 H
1 T& A/ A( Z, ]! x2 M, V, s0 q
2
1 M7 ?5 h0 C# ]5 H37 c$ C7 g7 q$ q1 y6 `
输出:0 @& A! g+ L% Q2 E) t/ g- W
3 j0 T$ B ^" |3 ?
, j/ w' R5 }5 H- {' _; k5 B0 A y
% q9 B9 J/ L9 m* i# T, @
选出 中心处 14x14 的:
) u c1 |; x4 s2 N4 _' P7 i2 D! V3 n& U" a! ^
my_slice = train_images[:, 7:-7, 7:-7]" v3 y! I1 P/ S, m% r9 `
plt.imshow(my_slice[0], cmap=plt.cm.binary)) H2 \( @, q$ m- r+ f& f
plt.show()
. q) m8 O: Q) |! b7 S- k1. T3 ^3 }- W# d X2 h, O3 O# K4 |3 P
2
/ q* _0 i* n! K# v) o. Y# W6 }38 z1 R/ v3 N3 n' R
输出:7 S0 ?% Y# u1 a; \/ j# R0 |$ e
) M ?* C5 _* Y# _) D3 r. ] u
5 F8 M3 H. \% f1 E2 M
2 L6 y& x9 g$ |. X5 l' z
数据批量3 T, N4 A. g' X' f- G& C* H x/ g
8 u8 U9 R5 A& x深度学习的数据里,一般第一个轴(index=0)叫做「样本轴」(或者说「样本维度」)。
; \6 l& E8 v4 j/ z, m. ^
# T w t8 x' X9 U7 R深度学习里,我们一般不会一次性处理整个数据集,我们一批一批地处理。; B" Q" {" |% r8 `) u, e
; i# Z' V5 e2 ]1 ?在 MNIST 中,我们的一个批量是 128 个数据:2 l- L( d/ n0 F9 R4 Z7 U, W
2 @( o3 K2 A! W7 _* f0 x! R
# 第一批' j& `% W1 E* f, |+ ~( l
batch = train_images[:128]# m7 j% \- O$ _/ I' i& g
# 第二批" \- O; ~/ z& R ]& I! h' d
batch = train_images[128:256]* B6 [7 x: P0 G0 g0 `) I3 j" x
# 第n批
- i9 T% K8 |- Z0 Z4 Tn = 12
4 u) ?! q2 @- ~5 G9 }$ qbatch = train_images[128 * n : 128 * (n+1)]
1 k! H! n' K- F6 g+ ^1
: I" y7 [! z, |1 T1 g2
3 i, \# z% c/ c3 R% Y- f( c5 q30 R* B. K% u9 ?* {$ J, V9 A, ~
4
$ P/ d( p$ {* ~+ w. G9 q* l5
5 F! l! y/ s! T6
2 B! o9 c- y, o/ r2 Q; Q7( h! k3 ]2 L- ^: ^
所以,在使用 batch 的时候,我们也把第一个轴叫做「批量轴」。* Q# T- c# }( N1 Y/ h( o, s
+ _! `9 v, ]0 V6 v- T: _+ b
常见数据张量表示3 V$ i! a3 S! V
6 w5 J$ N$ Z8 {4 _数据4 ^% M& O8 N8 R0 I
|
zan
|