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