数学建模社区-数学中国

标题: Python深度学习之初窥神经网络 [打印本页]

作者: 杨利霞    时间: 2020-5-12 11:55
标题: Python深度学习之初窥神经网络

' ^) K6 \# z9 i7 v3 x4 B9 lPython深度学习之初窥神经网络% [0 W% p2 F" V1 D! k
本文为 第2章 开始之前:神经网络背后的数学 (Chapter 2. Before we begin: the mathematical building blocks of neural networks) 的笔记整合。
' P9 u4 V. Z4 b, A+ l
! m( s, ^/ h/ |! D8 N. p6 B本文目录:: k6 n4 d. E7 F& O# q- b
: G- v& Y$ {8 W; x- h0 [/ S/ M
文章目录" o0 x0 T( e4 g6 \: q
9 D) W# m$ b: u$ p4 m8 L
Deep Learning with Python
8 k- U) O  ~4 v初窥神经网络
3 y+ N: n& }' _5 D+ k导入MNIST数据集+ P- F7 n0 ]# e+ Q0 [
网络构建6 ?3 V, u% n( I# f" ^
编译2 I" S9 R! {2 x1 P+ N0 N# }
预处理6 @5 `7 S. v4 [& E
图形处理
  W1 q. M6 Y! Z5 m标签处理
" G. _7 ~- a  ?$ @2 X" ~训练网络
* A. f; [, A7 D! `- P# B' Q神经网络的数据表示
7 U0 L2 q( S& P/ x: {6 |$ [认识张量( o) M9 w* G# J. C4 R) l1 U
标量 (0D Tensors)
: j9 V" P) c; ^& l向量 (1D Tensors)/ L; j0 I; E6 T
矩阵 (2D Tensors)
1 Y& C3 t9 m/ M. ?; a高阶张量" z5 w+ L/ v5 T$ N
张量的三要素( ?- ]* t0 H& r* L8 s, M  T' g7 m
Numpy张量操作
& S( C9 \" K  `+ \. }5 S- ]张量切片:
! b5 l' H0 Q4 J# c/ Q; J. N数据批量( E+ d" F3 F. O/ S% P
常见数据张量表示( G9 V$ H# b% a9 E1 P
神经网络的“齿轮”: 张量运算
5 }4 Y6 ^- i; n' B, G4 e1 r2 s8 w逐元素操作(Element-wise)
. b1 a6 p5 B, r! F广播(Broadcasting)1 L, T* q# x, E# S6 ^# y
张量点积(dot)
' \$ T2 G$ H: k0 ]  Z张量变形(reshaping)+ ^* a' J! ]) s$ ]" \
神经网络的“引擎”: 基于梯度的优化
) M* U0 X* @& @3 @' T2 k) u& C5 M导数(derivative)
$ V( S; n4 g7 ^2 a8 b. p梯度(gradient)  p+ [0 V" b0 l1 C5 X) q
随机梯度下降(Stochastic gradient descent)1 b0 ~' m* j) ]  ~8 W
反向传播算法:链式求导9 C0 Y( Q, s' R. @8 U1 F1 J
本文由 CDFMLR 原创,收录于个人主页 https://clownote.github.io。) A  a5 f" `" W! [" }: V7 D, R" w1 F$ ], J

8 Q; b4 w- X/ L0 `# n初窥神经网络+ K2 }. z3 b. L0 F

& G6 W  l1 T; A. N7 ^- J+ O学编程语言从 “Hello World” 开始,学 Deep learning 从 MINST 开始。7 `0 U5 ?. `7 R; Y7 S
- o5 @. Y' t. s( c/ W  |2 A) x
MNIST 用来训练手写数字识别, 它包含 28x28 的灰度手写图片,以及每张图片对应的标签(0~9的值)。
/ A7 b* {) D" s2 \+ @! D( d0 b' y9 U8 d6 x- G5 S, `" }0 R
导入MNIST数据集
% b6 s+ T- W2 K' f, f6 [
  z  y+ I4 a+ E1 D# Loading the MNIST dataset in Keras& _0 E4 H5 |6 j' i: i6 A
from tensorflow.keras.datasets import mnist
; z/ Q' |! C3 c- L& Z(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
2 E, C, S4 A8 F& w& k6 ?1
$ `5 E  M1 n) n4 V26 |* u  O8 O) W) o( o
3% i; J7 U6 J, c
看一下训练集:( A" l9 D+ G5 F2 J7 P" g6 U6 E
" T4 Q% X3 C3 r- Y% [
print(train_images.shape)3 _" j. D: i8 Y0 Z8 F# q: Y+ n
print(train_labels.shape)+ m8 }8 n8 `: m! p3 B( Q5 v
train_labels4 Y5 S; z; ?5 c
1; x% X7 u9 r! b
2. U# j9 b9 ^" J0 x  j
35 K, x5 }* K" x( O* R% y
输出:
* z) n# J# N. l7 ?+ W( Z* N( ^1 Y3 }1 z5 c/ y1 B5 Z
(60000, 28, 28)
, G; v0 Z3 c3 V+ Z: D* \(60000,)
% W/ B- ?1 K) A& D6 G6 z  s0 \9 @% y) {: G% s- V8 R
array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)( r. a- b7 B* ^- s! `0 ]! @! T
1
5 n8 [/ d# U9 q% W2 Q) k. N2
4 B; P) N" i9 k! l. ^! p/ X3. G3 |. c0 a# x' [
4' _9 R: E  z; S& `
这是测试集:9 y. U0 I6 A, M+ D. h) g% O
( h, y7 ]. w/ T5 I4 D
print(test_images.shape)0 H3 }, f4 J* j* w" `. u- J% j6 Y
print(test_labels.shape)
( m) d$ p, l) `test_labels
* F& Y! \7 G& I6 ~$ u! m10 q6 b  o" k# D! c1 Z3 r
2% `6 C. i3 _1 X8 _
3
! z0 Z1 X, |* R% |1 y  P输出:# `! m, T) D$ M9 p; \2 B7 T
* P# g, W# N( s. S; c6 u2 ]
(10000, 28, 28)
% ?& s/ F; j" x/ A- g(10000,)1 w. X& M( L0 a: C. T& A
# ]- e# ~; @- G3 R9 q# v# g# t
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)
. t" }; q1 p& X6 q7 N3 [; f- L1" \0 m5 C  ~1 [/ X! [
2
9 O! Y9 v9 B' ]7 \  v1 K3
' M7 C7 F6 ~: t$ {7 E! M5 H: w0 ^4
0 h8 t$ ?9 q- a) U7 J网络构建
8 E2 e% Q6 k* q: {2 [& N  \% E0 U  C4 E" }7 g& c8 v
我们来构建一个用来学习 MNIST 集的神经网络:
) m% X' i6 }9 v0 j9 a3 `3 Q* H" G/ q3 [2 |2 B& I) [3 l( X
from tensorflow.keras import models3 s7 X; a: D# R% Y
from tensorflow.keras import layers
3 r1 X1 K9 K. h# O$ u# J2 f& @6 j& V+ Z$ d; M1 J
network = models.Sequential()1 Y4 a; ]% S* x- `
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28, )))0 l3 p0 y# |2 E! m" p
network.add(layers.Dense(10, activation='softmax'))- ?0 [0 b  v8 s8 M- [
18 D3 u; ?: C. C8 P3 [6 W
23 ~- _8 Q9 a0 k  L: S
3
: p; b4 R8 q0 V. h/ C, u4  Z' F) D/ I* v6 o6 Q
52 B) z- l7 a: {% B1 u  z0 B
6
6 j$ \: a2 k  k# Q; C; c; [神经网络是一个个「层」组成的。; w( l3 E6 c9 M, _# Z! e
一个「层」就像是一个“蒸馏过滤器”,它会“过滤”处理输入的数据,从里面“精炼”出需要的信息,然后传到下一层。# b  r/ l5 V) w4 p

* }' y7 n' F$ n) K这样一系列的「层」组合起来,像流水线一样对数据进行处理。
# G& N) a1 B5 d3 a1 y* Y, ]层层扬弃,让被处理的数据,或者说“数据的表示”对我们最终希望的结果越来越“有用”。
$ u8 }. S: O1 n) b& e% U# C! ~
2 l) W9 U" O3 A9 }; Y# Q5 E3 j$ j我们刚才这段代码构建的网络包含两个「Dense 层」,这么叫是因为它们是密集连接(densely connected)或者说是 全连接 的。0 {7 o& T5 r- n. x. P
8 z  W; a  }# W/ Y: U$ N& e
数据到了最后一层(第二层),是一个 10路 的 softmax 层。4 j" c3 T5 c! i+ `2 |$ d% e6 z
这个层输出的是一个数组,包含 10 个概率值(它们的和为1),这个输出「表示」的信息就对我们预测图片对应的数字相当有用了。; {6 H! e8 M8 q" l
事实上这输出中的每一个概率值就分别代表输入图片属于10个数字(0~9)中的一个的概率!* L& s7 Y: h& W2 a) U
. u. d" V. c5 @  r% c, w* ?
编译
% h1 s5 F  Q3 j* @; C: e( J+ v! Z- i8 O0 @
接下来,我们要 编译 这个网络,这个步骤需要给3个参数:1 Q; H7 f& i2 B: O2 o$ u

7 b7 [# r- _# {9 Z$ m1 g% s) j; i损失函数:评价你这网络表现的好不好的函数
2 ~- C/ c' W: u; a- T1 e: b优化器:怎么更新(优化)你这个网络
: h1 o- N& r9 b6 [/ c0 f% p  H1 j训练和测试过程中需要监控的指标,比如这个例子里,我们只关心一个指标 —— 预测的精度- p, `7 U  J6 s
network.compile(loss="categorical_crossentropy",# O) I& X' d. V/ N: ^
                optimizer='rmsprop',- _! k+ y) @% K  _8 E: [; o
                metrics=['accuracy']). l4 S6 l0 s. a& V, i* T" I8 C' A
1
4 e+ C; y, Z* g! p& r6 P2
2 x; n" A( ~& Y3 Z+ T  @3, J7 w% b# `1 _5 i- J; {  D
预处理2 g$ @. U+ Y6 Z
8 B9 z1 B+ G' }% U4 @0 p/ }
图形处理
, e/ j- x" ]' P! J$ \" {, F
: a9 f; m: T/ [& r6 I+ c6 N5 f我们还需要处理一下图形数据,把它变成我们的网络认识的样子。
3 O9 A/ {3 Y! w6 M. P* H; n1 H* S0 c1 r6 p9 o! g8 c
MNIST 数据集里的图片是 28x28 的,每个值是属于 [0, 255] 的 uint8。
+ a0 I) j  B, x* a而我们的神经网络想要的是 28x28 的在 [0, 1] 中的 float32。
* d5 g% n% }6 J7 w0 v% }) |  k5 u0 F" X7 |) Z
train_images = train_images.reshape((60000, 28 * 28))7 @, r7 }& b5 H; c, J4 R7 f& |
train_images = train_images.astype('float32') / 255
3 N3 o1 F0 b- J* T. v
+ W5 [, Z, `2 i0 H7 s4 h9 Dtest_images = test_images.reshape((10000, 28 * 28))
' \& @  A' A( Ktest_images = test_images.astype('float32') / 255, [, S' _  J8 n. T! l/ G
1% C4 [- O( v  P3 f
21 I# {* ?$ L* H. O
3
9 ]8 z" y2 r, ^# m8 d4
7 T) r3 g! ?0 M4 d56 n0 ~9 S* ?  t! P' u
标签处理7 T# u9 f& n: l6 s- r# x$ ?

4 R1 [5 K2 j0 i  H. @2 @0 ]/ a/ i" v同样,标签也是需要处理一下的。: q, e8 B3 v4 J1 a$ M9 w
$ F6 f7 s  o; a& M: m& K
from tensorflow.keras.utils import to_categorical
: d: [" ^4 X# ^, m: |% k  P# M
' M6 c, \" l: F3 e/ m- d; qtrain_labels = to_categorical(train_labels)
8 Z3 l- L5 K' [7 _! otest_labels = to_categorical(test_labels)6 d& k% U& t$ w
1
4 W! `* Y& _0 _( u22 [) P; p  i8 i. v+ y$ _6 j. S
3( ?1 b  G- u% K. S; J& G" @
4
+ [( o4 ]3 L& d2 N( z" `& x训练网络
3 N+ K, B4 l$ U& `: _" H
) A! Q, Q+ ?/ D# c1 b4 {3 ^; P( \network.fit(train_images, train_labels, epochs=5, batch_size=128)
: g5 H" D  R. ~1
1 ]- f; y, s1 j输出:5 o. ]8 y' d7 g9 q/ v6 k

. K" D  g' U5 d: A: R, }Train on 60000 samples
7 O: J% A" S8 s9 T2 D$ _+ o, GEpoch 1/5! B' J& k+ F( L* ]
60000/60000 [==============================] - 3s 49us/sample - loss: 0.2549 - accuracy: 0.9254
( o- m5 }, H2 z: ?Epoch 2/5
2 Q$ }& K3 H7 h5 l* H60000/60000 [==============================] - 2s 38us/sample - loss: 0.1025 - accuracy: 0.9693
- n7 c0 x: J# EEpoch 3/57 x0 c! A, ?* U/ K" `
60000/60000 [==============================] - 2s 35us/sample - loss: 0.0676 - accuracy: 0.9800
/ x: M8 U1 O( R$ _, M! f! d. kEpoch 4/58 G# C* `/ I  N0 G* m+ t; X- Z
60000/60000 [==============================] - 2s 37us/sample - loss: 0.0491 - accuracy: 0.9848  p" ]3 ~: Y( \- _
Epoch 5/5
) R+ g; \8 k& E/ K1 i' Y* y60000/60000 [==============================] - 2s 42us/sample - loss: 0.0369 - accuracy: 0.9888+ D. j# `; g9 V+ E

% B5 S9 b& a. r! T$ q: m<tensorflow.python.keras.callbacks.History at 0x13a7892d0>2 U8 I9 l2 z; J
1
$ l, O+ z9 O  M$ I2
: G0 d) I0 \/ Y+ f. k39 r4 ?" w; D: l  U6 k4 X
4
: D# ]3 ~) }3 H4 \: j# o, }, l5
/ T; U2 ]9 a; T/ {, O0 p( d6
$ `" Y9 C- k, a7* K4 ?% y+ G( _$ O+ Y, N
8
2 G' ^3 K. {6 c* N4 k  B" D" Z9
9 G! G" F6 Y& Q; B10
, y( z4 g9 c5 N8 d( O/ p11+ |4 U: E2 ~/ G4 Y* l
12) ]- Y, R- a! L4 q% F
139 X# }3 J1 d3 m% w% u! \9 h' M4 `
可以看到,训练很快,一会儿就对训练集有 98%+ 的精度了。
+ V6 n+ a! Q9 k. d4 h3 N* E
) C+ C% s1 {/ ]! _再用测试集去试试:
; `; A3 a( c' P5 B) `; I: o/ J, Y3 a8 ^" K! ?
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
, \: a" j7 Y$ y  x$ Iprint('test_acc:', test_acc)
8 e( `! B, H$ C1 j11 W3 ]1 d0 |9 b( B
2. w, |2 g4 k7 J' A" u5 J7 H8 i
输出:% o5 H$ e" _! U  W! g" E
, y/ f# G5 S: y. V( f/ T5 Z
10000/1 - 0s - loss: 0.0362 - accuracy: 0.9789( B% o* z& d& B, k1 s3 w. e! J
test_acc: 0.9789/ _' A' r9 L9 _/ |; {7 N% ~
1
& q) E, h6 f8 |7 t0 A+ ^$ y22 w+ A8 L: F( A6 D
我们训练好的网络在测试集下的表现并没有之前在训练集中那么好,这是「过拟合」的锅。
3 Q2 |, k- i& S/ v( x+ ~: e- b; p) p( s% M* [
神经网络的数据表示
7 p" W' Y3 `% J, j& w; D  w8 w0 i3 u8 \) c
Tensor,张量,任意维的数组(我的意思是编程的那种数组)。矩阵是二维的张量。, I' p( i$ ~" c' O3 U$ _
, j# e& E, l- w" `" d% y9 ]* j
我们常把「张量的维度」说成「轴」。# o6 y, |6 \. A' D9 Y

8 f- y* B2 W& W认识张量
& R6 p/ p9 x4 x& j5 N
' E' B5 A4 `% \, m, C标量 (0D Tensors)$ }& Y$ M. F1 T3 t( E* V
, J0 z' _, K9 s7 i
Scalars,标量是 0 维的张量(0个轴),包含一个数。* E) `5 g; }8 B7 q1 [+ p/ J" R

- f: }8 a8 _5 t0 J, ~* @标量在 numpy 中可以用 float32 或 float64 表示。
% e) _' x8 ]6 v6 t) _5 R
% F  ^4 F- [, R  t$ jimport numpy as np
1 F9 Q/ Y  ?5 V* E$ d3 S+ C% s2 p" j5 k( O- _" e
x = np.array(12)
: P* V, {$ h$ R) k! S4 U. Yx0 e) g  s5 {$ c' C" p) C
17 j3 ]) U8 f/ Y% u9 e
2  X3 @3 K( U/ z8 j7 S  M+ [
3
- A% @9 y. L6 O4 e' d4  O% p& F$ a. f. Q1 m8 y8 B. N
输出:
% g! C; C8 e7 Q
6 t$ R& r5 d4 h. t$ garray(12)
- b. Z& m6 p0 v1' w5 a. m1 ~8 I6 l5 q
x.ndim    # 轴数(维数)
1 y$ M& R. O4 D* A% C9 l* Q1) C) D; s; U# Y# B0 r+ z# K7 g: H$ c
输出:- Q8 g) O* U6 T+ ^; q; L4 L$ ~; f

9 |0 o6 V+ N! I1 m: z1
" t& @9 a9 ^% u3 ?' ~4 U; \! L1
2 i! }8 e+ F5 X. C& @8 r$ O( o向量 (1D Tensors)
: [! `8 D! \* p( W* ]6 X8 m9 I* B) ~. `% o3 W/ ^1 d* g
Vectors,向量是 1 维张量(有1个轴),包含一列标量(就是搞个array装标量)。" E" h2 s. y* o  Q3 a

$ |3 W  k8 {  yx = np.array([1, 2, 3, 4, 5])
1 g: v/ d+ i) ~2 S; l+ Qx
3 {7 \; R$ s0 {9 K7 h1
! V9 a/ v, y4 F2
) C! T5 C& `# _# G" e/ j' J% |+ G输出:
% o' c! {& [2 c8 _
- \8 s! I1 d7 r+ darray([1, 2, 3, 4, 5])
) j' B# L* L$ @6 ?  I) E3 @1
- a# a- W& i9 d9 n( _- [x.ndim" D. l! _0 r6 K% y* @" M' e  L) |
1% i/ ?2 d. A: [$ c6 ~2 u! c* s1 z" b
输出:, B! i( q; _8 x1 q9 }: |9 m' k
% R: Z' {- D2 e% z* \# H
1
' q' G; T9 E2 u8 L3 f  j1: I* o0 h, w/ D: N' Q  Q
我们把这样有5个元素的向量叫做“5维向量”。0 W% P  y/ V" t( r" c* i$ R
但注意5D向量可不是5D张量!; G$ T3 t( b/ i. l& Z1 ~

, g' @( s8 f% e+ U5D向量:只有1个轴,在这个轴上有5个维度。
; T$ `3 T0 c- O- f9 s/ J% ~5D张量:有5个轴,在每个轴上可以有任意维度。5 K4 ]! I+ E8 @
这个就很迷,这“维度”有的时候是指轴数,有的时候是指轴上的元素个数。
3 d8 O, t) m7 A- V# F3 y/ ^" W
3 z& |! h* q& T) ^5 E所以,我们最好换种说法,用「阶」来表示轴数,说 5阶张量。  Z+ N6 |) G. w5 B

, {8 V3 N) ^9 Q矩阵 (2D Tensors)  X9 p/ I$ ^" q: n4 |) b) D
. p3 g% ^$ I% v& B
Matrices,矩阵是 2 阶张量(2个轴,就是我们说的「行」和「列」),包含一列向量(就是搞个array装向量)。
/ I+ `4 }. S8 d7 N* Y* x3 L
$ |! T$ Y! }& Ex = np.array([[5, 78, 2, 34, 0],
9 Y/ B% {- B0 T0 E4 p$ i              [6, 79, 3, 35, 1],; J( |# p+ v% l& f0 j( I0 A0 u
              [7, 80, 4, 36, 2]])3 W: k% c' U# H3 a; I# l9 c& b5 P
x
9 o; `- Y' i9 D0 N/ `% \1
) S% }! ^- {4 K! l; V, k; l' v20 l' `5 x8 t: N) g3 Q
3: R/ P8 Q( `8 Z, D# P
4* b+ X- ^" @: p1 n/ K
输出:
) Y7 H; R$ u  y6 w* s& `. [" P: s1 B0 z* e$ h
array([[ 5, 78,  2, 34,  0],
0 g! B# s0 ^- f       [ 6, 79,  3, 35,  1],
$ v, C! K9 U+ {* Y       [ 7, 80,  4, 36,  2]])
  W" L1 F, C( q0 d4 w5 ?( {1+ \+ M1 C8 }; L- P
2% F0 g$ |5 M, s8 ?5 S, ~4 s, B
3
" P$ S* X: [/ M2 j* H- ?7 G+ Rx.ndim
2 Q( [# q* i+ @" o/ d' l; r! f11 }  T( z! O3 Z- U* \& u6 f2 [
输出:/ u, L: n# x/ Z* G# j
  Y9 _( M: q* C3 _& b/ W
24 N& k# V9 X! \1 i
1- `, R% w$ ~# I) I
高阶张量2 d$ v* C2 i5 T  a5 e

" V- x! ~$ x1 g你搞个装矩阵的 array 就得到了3阶张量。2 D) h$ q2 Y" G6 P$ a, _# X

- }& N; }* h, D6 x3 n再搞个装3阶张量的 array 就得到了4阶张量,依次类推,就有高阶张量了。
4 Y* g2 l6 d  K$ M9 i7 t
' i$ G+ P% \7 T8 ?" b* Gx = np.array([[[5, 78, 2, 34, 0],  G$ o: I9 r2 ~( B! E4 I6 _3 K
               [6, 79, 3, 35, 1],
/ |# n8 C7 O# X: |4 Z+ l* _: j$ W  {               [7, 80, 4, 36, 2]],' o* G0 T, Y& l* {: m5 b, m' ^* ~
              [[5, 78, 2, 34, 0],
- Z+ t$ i8 ?5 p% Y' L               [6, 79, 3, 35, 1],
3 ?# h: d4 b5 x2 V# K  p1 A6 C               [7, 80, 4, 36, 2]],5 w, L$ ^* A. {+ u, Z
              [[5, 78, 2, 34, 0],9 }6 Q) g7 ^& g6 Z# E2 V
               [6, 79, 3, 35, 1],
6 ?% _% ^# f' ], H+ b' K4 F& E               [7, 80, 4, 36, 2]]])
. o8 T' U- Z3 a. o# y- x4 A; ?# Hx.ndim1 q7 c; O/ T' ], K
1
8 K- |- I* {/ y1 \1 A2; q  u  X0 u! E# ?% L
3* @9 B! G) C4 y
4
6 L+ I+ X, S- l5 G% c: P# ]- u1 T+ g5
/ W% V7 `3 y$ X: f- @7 X& R4 C6! L/ M1 w( {  d4 v) c' n2 h
7& y, w. R# J) k/ s% }
81 z6 w% @& N* }" V& u
9
' a& [. |) T  k: W/ o: M, c) l& [10! o9 l5 L0 h( ^' T! y
输出:% A+ I6 M3 m' g/ _) E6 }
2 f: u, D' T! ?7 L- L5 {
3
9 Z" K% g9 L; }- \& R1
, U6 h8 c- r8 e深度学习里,我们一般就用0~4阶的张量。0 d' X% K8 L+ o5 d
- |( b5 r3 H2 X8 a
张量的三要素
  J& \; |& L$ W! l" u; t0 i
* g* a0 \, R. T6 U9 S0 M1 M. _, L阶数(轴的个数):3,5,…5 \8 ]" |8 K1 U. d1 G9 r
形状(各轴维数):(2, 1, 3),(6, 5, 5, 3, 6),…
2 i. I) r! q8 F数据类型:float32,uint8,…
5 n7 G; t7 M& q我们来看看 MNIST 里的张量数据:
6 o1 y& W& [9 U  W) L; L) i7 W# X
from tensorflow.keras.datasets import mnist7 S( [) v- U3 _5 Y. V$ d1 h4 @0 @, G
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()0 b2 \% L  Z. a0 E+ t4 s8 \

! h9 h: W  p# x( hprint(train_images.ndim)
( F% O/ i" y. U$ R* b: zprint(train_images.shape)
- h3 V; n3 }: I1 Dprint(train_images.dtype)5 v9 i; L9 p8 @
19 y2 D% v3 H) g2 @6 r
2
( [0 `$ D4 X7 x) `3
0 @' Q& |! q6 Y! L7 Y4! H& o/ H$ u" [5 S) U
59 h; }" N* \- ?
6
% R; d' l4 a2 H  z, W# O0 k/ M输出:
+ p7 m0 o+ U* |# |5 h7 @9 ^9 \$ O1 l0 b. V4 N
3
* I: Z- E3 l  |& L9 p/ V: D(60000, 28, 28)
& J2 H2 Z3 D$ |" N) C! t' juint87 r. f  z- r. }" p
1
- C6 \2 c# v' Y6 L4 o5 M4 |3 ?# u29 y0 j8 [: r6 [) D/ u/ H
38 s4 E6 e$ o; }" Q
所以 train_images 是个8位无符号整数的3阶张量。
4 y! z( ]  C. L, [  B$ l  M6 O; Q! w$ O3 d+ N# E" o6 ^2 S/ [# [
打印个里面的图片看看:9 w  x; _! w( Y6 @

- W$ ?- Z* y- I" Q2 Mdigit = train_images[0]
1 ^0 h2 d! ^- h$ `. Y
5 }6 o1 A+ @: U% w' @import matplotlib.pyplot as plt  G0 k) J8 c! W' b
; ]. X9 e8 ?7 d* q& G' ^
print("image:")
& U. M% o& ]: p6 E* Fplt.imshow(digit, cmap=plt.cm.binary)
! \1 P4 P- k* B2 h1 K8 Kplt.show()  }2 q# b3 o$ k  D
print("label: ", train_labels[0])+ C# B+ e( h; h6 p% G4 @+ z; \3 T
1
3 I8 i8 |: j" q2
" ?% e3 d  j2 S# }3. V& f+ z& q% N, u3 A: x
4. @1 J( a3 o' l" \: ?
56 ]3 k7 b0 \# Z0 ?/ x( Z
6
$ l( r2 S; d1 }0 J/ _7' a  Y6 `  s9 G) S  X; r
8/ g6 E1 ]0 S8 U; f& U
输出:. J* g( u# I- t$ b, h1 A: j, i

* i: ]6 [0 ^0 p 1.jpg 3 }2 F. g, P7 B8 h2 V5 \

* x6 z  X6 _3 K) r& wlabel:  5# e- ~6 C% P8 D! ]7 z4 ^  D! z2 q
1
1 ]+ X4 F8 `9 _9 I+ y( y  ?Numpy张量操作
3 k. }5 a( D5 s) [. d( i. [: x* \! O, p! l# T/ ], W
张量切片:
$ G/ K; e% A5 \. f. ]3 }: K- w( v; t. L. N! l9 K
my_slice = train_images[10:100]* ~# O7 x  l" f' ^0 o$ N1 D
print(my_slice.shape)/ `) p/ F! m) t# T$ P8 G9 F
14 O, V' ]$ Y6 @4 s$ H' ?2 U
2
  B9 W! R6 S+ v& G8 |+ @输出:; g  M& u0 M9 {5 m4 K) _
2.jpg
, C1 M! E$ U* U& ^(90, 28, 28)0 ?) d3 p/ J3 z, {
1; G  P/ Z6 G8 }
等价于:/ }! I8 Q, J2 }3 t
* ^7 v" E7 P' {8 T
my_slice = train_images[10:100, :, :]
( G* B" S- j% @print(my_slice.shape)6 Y& P# |, _; J+ f4 I
1, p* g; {9 D! a8 N1 y4 D. {
2- z. _: ?& X* j+ }: Q
输出:' K% Q  n/ E4 y0 r) b( d2 m1 b- c4 k7 i
3.jpg
. I: e7 s6 U/ F  M(90, 28, 28)
/ s! Y5 |. J1 l7 A1
  H3 \1 _5 @; F也等价于, B2 K5 `, E8 K
# g8 m+ Z0 P9 Q1 E' I0 U
my_slice = train_images[10:100, 0:28, 0:28]
! R7 ]9 c3 K) H7 Qprint(my_slice.shape)! o& {7 t! d. O! y: N4 q) M6 _. x
1
3 C+ a; G* v7 w, R- e$ V1 S28 y! E# y: B! u6 k% d5 R: W
输出:
" r- v5 V( J! n% V' v( o+ b% ^7 D! _1 A
(90, 28, 28)
; D6 G1 G2 M' K+ ^) j1) Q# K6 j' m0 S& k* c0 V+ D
选出 右下角 14x14 的:; r9 [. n! |- B8 I4 W' f! G

  g' e+ f! }' k0 w# D0 F) U* K& {2 \% mmy_slice = train_images[:, 14:, 14:]
: v2 q, D1 B) pplt.imshow(my_slice[0], cmap=plt.cm.binary)' [9 E% i# O# x' w2 E, |
plt.show()
3 H' V$ ]! y) K# l' ?% R3 P- {. }" \1
! b2 u- L9 R) i4 t, l, m, _& X! a) |2
8 k' E, c1 `/ V' [; V3
2 k1 N" W! O: ~输出:2 U5 t: V' b* W( s/ _/ y
6 U' d+ w! m. Z# z+ s$ k6 q

# V' P; l1 {: N2 @
3 i2 y! k& D+ B6 L* M% m5 s5 s8 q选出 中心处 14x14 的:) w8 K; ^- V* \& f2 }" r$ o6 {- V

) ~9 K! \7 E- L/ V7 i- I2 mmy_slice = train_images[:, 7:-7, 7:-7]  p0 p# C% ~7 C1 [! r
plt.imshow(my_slice[0], cmap=plt.cm.binary)
' [9 }/ ?2 m# m# @. ]# lplt.show()
" w+ N, c2 k& F% z2 b1! C8 m8 J! C' {' b8 l. s( |  E
2
" p0 l$ c+ a* Q2 ?6 q, n. R' K; |8 x3$ G6 B6 j6 w  h; i9 U" t. y& F
输出:
! k, A- D1 v0 i# R4 P; w: u4 \5 I& i7 i

  A, e& a4 m. r  k1 ]- U* ?2 F7 ]% V4 |" s$ x( ?
数据批量
8 V5 n7 X# {/ r- x  f- m1 H3 C$ h3 i$ q' W- F% E, K
深度学习的数据里,一般第一个轴(index=0)叫做「样本轴」(或者说「样本维度」)。( `( p% N0 G" Y6 R8 g& t) P/ y

. j* ]# ^7 K' m" ]6 M/ ~  j/ ]* g深度学习里,我们一般不会一次性处理整个数据集,我们一批一批地处理。9 x7 H4 b( X. w2 C1 t

2 |  J& S; `4 `! N/ O  o/ B. C在 MNIST 中,我们的一个批量是 128 个数据:
# Y, u" y$ C8 U; p4 c: f1 l  ], o, Z% r
# 第一批
0 l" r2 D+ Y' ibatch = train_images[:128]
1 E( p; T4 d) d# 第二批4 P( E: y4 K+ C% P
batch = train_images[128:256]0 [( V7 v$ C# T+ b6 c
# 第n批
/ S5 b; b! t5 f# z, q! Yn = 12
5 v% A; C8 o% W7 _/ N2 ^3 u2 u* Cbatch = train_images[128 * n : 128 * (n+1)]( p( k- l  A9 f7 Y
1; S5 |7 x* s$ S0 n0 D. O
2
- ?" Z; T& s) N- ?6 r' W3
3 L% S% w: |1 Z4
/ M/ y7 b! R- r9 M5
, j% b4 S$ O3 Q  n' y) _6 @6' f% ~, C8 L! R0 A* x. O3 K
7
7 {* o$ Z; D; g3 P. G所以,在使用 batch 的时候,我们也把第一个轴叫做「批量轴」。4 S. o9 i# D7 c9 u' R( r# J
) ]4 F+ R+ a. s2 n  C) Q7 V
常见数据张量表示5 N* N0 u7 `, F9 n9 d7 x

- f  r( J- {6 b5 P: L1 S' [数据
' w5 B/ `( @3 x' F
作者: 2863358207    时间: 2020-5-12 12:11
好好好好好好好好好啊发表回复
* r) U1 b' ~+ w5 T2 l




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5