数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-5-12 11:55
标题: Python深度学习之初窥神经网络
# b/ N, O  y' y$ X
Python深度学习之初窥神经网络- P& F4 a# v  u! K  c! v- Z& e
本文为 第2章 开始之前:神经网络背后的数学 (Chapter 2. Before we begin: the mathematical building blocks of neural networks) 的笔记整合。  G8 c0 u( w  n, v

* i/ M/ `; V+ b本文目录:8 \6 ]) |) J" W4 H5 w
# o8 q8 `" ~5 F7 ?9 l: S: [
文章目录
; L/ D  }# {" h' O7 O4 G% u7 y2 W7 \6 M4 D
Deep Learning with Python
, u! ]. B; r/ b0 d初窥神经网络( R) F! Q$ Z: p8 O2 _
导入MNIST数据集. F0 h' Z& W: s, A8 U0 U8 r/ }
网络构建5 r" d) ]* R9 d% ^+ e
编译
( J7 w' V! o! {& M& M预处理
6 R6 j- F0 {! Y) g  C, M7 O图形处理9 ]+ J3 a, g' G( u9 O( k- A
标签处理
2 t/ q7 Y" X' u4 ?# M1 c训练网络& ^- P) U! Y7 @$ h2 E6 ^
神经网络的数据表示! [; L; d9 D, V# Z; t
认识张量
- S1 x* E4 R- |标量 (0D Tensors)
3 C) n- `3 _3 o$ c# y$ _向量 (1D Tensors)
& L' c3 E  ^2 D) l9 t' o& l矩阵 (2D Tensors)
& [7 }' d+ z( J" D) H( t0 V高阶张量7 e% J3 Z$ r* t5 @1 L, K  v
张量的三要素) l6 w" _4 U9 r, z( j& f, A" b& M
Numpy张量操作! M& F' R1 R7 I1 U$ F7 l
张量切片:
& J& b/ D. Z: q) L5 b% f2 W# b数据批量! d1 Y, Z3 S( d$ I( F
常见数据张量表示$ T: ?) U, W2 w$ R( {$ M
神经网络的“齿轮”: 张量运算! Z5 w) O( F% ~4 |6 o
逐元素操作(Element-wise)
5 m( {( \2 k: C5 [! v* Z* z& G广播(Broadcasting)
! O+ f$ z  }) T3 F+ f+ j张量点积(dot)
+ h1 w; j+ R1 L1 n& [; Y: m1 r张量变形(reshaping)) V4 C# p* j4 o( f
神经网络的“引擎”: 基于梯度的优化; U  f4 j: q. \
导数(derivative)* _5 q$ d9 d" B! {# i4 _
梯度(gradient)
+ _+ K0 S! a& D. X2 a随机梯度下降(Stochastic gradient descent)% D- W" e( g8 G# |$ y
反向传播算法:链式求导0 E: b" }& ^) N' V2 r' O; w
本文由 CDFMLR 原创,收录于个人主页 https://clownote.github.io。+ j  ?7 G: ~# j* ]% y6 J* D2 `

, g  z' G4 P( \( e5 O: N初窥神经网络- L6 p+ {3 O) s/ f  V8 @5 c
( U% K: H$ \. t
学编程语言从 “Hello World” 开始,学 Deep learning 从 MINST 开始。# A4 P% q( r9 W4 u0 E' J+ D

; E/ x7 b# {! q  ZMNIST 用来训练手写数字识别, 它包含 28x28 的灰度手写图片,以及每张图片对应的标签(0~9的值)。
$ G  e. E" |' N7 K2 r
$ k- g. ]. f4 `5 p8 a导入MNIST数据集; f$ r, j* @8 S% s7 u9 [
& g% W, ?; ^4 n5 ]* G1 q
# Loading the MNIST dataset in Keras
+ w' \& |% I/ c, A" c3 qfrom tensorflow.keras.datasets import mnist  D  |/ u2 j2 h8 l
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()0 m. k1 i  X. y# Y2 S8 A4 @2 @
1( {# e$ S- L) _, Z5 r: ^
2( p, p: J. D: t, J
36 k, G% o3 F; a2 S8 F1 j4 T  C
看一下训练集:- u' S) f+ v6 D$ g# `- j0 r' u
! j+ _* r: N( D' U) Q: j
print(train_images.shape)" s  V9 p: d6 x9 B
print(train_labels.shape)6 e' Q+ `1 `( ^3 z6 D3 k
train_labels
$ B# P8 ?% f; X& `, ~, V13 O! t/ r2 |3 `0 R% x7 u9 b$ ~
2
" }2 e6 i- g1 [) s) l7 v& F3
: r7 \9 d" r" G* B0 y4 h输出:$ a! J# ^, X+ w, W
) F' h8 q% ]8 {$ A5 p- [4 x, p$ b
(60000, 28, 28)! o# L1 U( y0 h
(60000,)
, e5 _) ^+ f/ T0 }# S
% N5 }6 e* t* Aarray([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
1 i+ P) S/ @! p0 u2 T2 O* \1- Q  v% v7 ?, [; D) J6 {' _
2. [5 ]& F; h" ~; l, X" J% q+ O: N0 w
3
4 G: Q" t/ I, N/ _6 j" @" q: W" W46 Y4 I, r1 H5 m" L- D' l6 s7 K! V  i8 I
这是测试集:
. f9 @; `& c1 S3 _3 K/ \! G5 s5 S
print(test_images.shape)
, L) K& \4 I" Tprint(test_labels.shape)
, ^9 k% e) b* V* F* Mtest_labels$ \6 \- V3 z* q  n5 ^
1
4 ~! @; }- U5 L9 `; x6 a6 D; z8 U! Z2( u0 |0 @) x" O4 L, ~7 z
31 W9 ?4 n2 U/ d" ]. d! W$ J
输出:
) m% X" j" v4 I
9 d1 j; g3 V, a' `; h! g(10000, 28, 28)! A9 ?" J4 B: d. [9 h4 W
(10000,)
, M& T7 p. k  n/ @9 s; R* F) B2 x- k1 C
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)! I8 F4 j$ ^7 h, Y) |& v
17 w. m. Y1 l0 b3 W! ]
2+ C9 o0 t% H- l- p1 X5 r
3
6 {+ ~8 U5 r: r4. f5 M9 K+ s  t
网络构建
& u) L- x3 r& ~  ]+ H0 a) t
! E9 l% @1 N/ e* ]( Z% N% b$ D# M我们来构建一个用来学习 MNIST 集的神经网络:
1 @& w/ V6 D6 c$ }
+ a9 j2 ~4 K; Efrom tensorflow.keras import models
1 ]. a$ T' t5 B, V1 sfrom tensorflow.keras import layers9 _# C7 c' ?# c0 l
+ f8 A3 }$ D* I; t/ n/ A: i+ g
network = models.Sequential()
: v& C% g' N$ gnetwork.add(layers.Dense(512, activation='relu', input_shape=(28 * 28, )))
  {- ^: y9 F. u6 }; H7 Dnetwork.add(layers.Dense(10, activation='softmax'))- r  c  g# n" @8 v
1( l$ X# D6 G/ a- i  K
2
; r+ ?2 I: Z* ^' `3% }! s9 p' \! H& _1 L# s5 Z
48 W5 O- O9 U/ S. }7 `
5
* s! ]3 i: p) C- ?6 b6
: H1 e, W! i, c神经网络是一个个「层」组成的。% a4 J& ~1 U  m1 _: O
一个「层」就像是一个“蒸馏过滤器”,它会“过滤”处理输入的数据,从里面“精炼”出需要的信息,然后传到下一层。
$ n# a, J+ M+ o0 H- x& @* `7 }  M
这样一系列的「层」组合起来,像流水线一样对数据进行处理。
! b. v* ]! U) a层层扬弃,让被处理的数据,或者说“数据的表示”对我们最终希望的结果越来越“有用”。
4 T  ~* `" A  r' r; [
0 C( W" U/ J0 ]# q  I我们刚才这段代码构建的网络包含两个「Dense 层」,这么叫是因为它们是密集连接(densely connected)或者说是 全连接 的。
" A6 k9 G' j) Q6 {; \0 L) L, ^& E' N3 f& V- _, L
数据到了最后一层(第二层),是一个 10路 的 softmax 层。8 v/ t' k+ q& ^* _- t7 \) m( \
这个层输出的是一个数组,包含 10 个概率值(它们的和为1),这个输出「表示」的信息就对我们预测图片对应的数字相当有用了。
% U7 t" P" p& o) H事实上这输出中的每一个概率值就分别代表输入图片属于10个数字(0~9)中的一个的概率!. Y: I/ t. w9 N8 D5 w

6 U* C: }& q! o, l5 s1 s- U编译
* B5 t# p* ~" U* b+ T& A( {
# j/ c" ^. c2 T6 n) V/ g* Z接下来,我们要 编译 这个网络,这个步骤需要给3个参数:
: g' j( v9 ]; ~
/ S, h8 K/ U$ D4 V损失函数:评价你这网络表现的好不好的函数
8 k1 |! E: t* y6 r优化器:怎么更新(优化)你这个网络
6 Z* [7 F# ~6 a训练和测试过程中需要监控的指标,比如这个例子里,我们只关心一个指标 —— 预测的精度7 m: \; x- g: z. B2 O
network.compile(loss="categorical_crossentropy"," g  @" ?! C* F
                optimizer='rmsprop',
- i  I# u! Q6 D! t! K% K9 z                metrics=['accuracy'])
2 ]: ~2 {) c7 D18 O  I0 ?! D, `) x
2
5 S, `+ H6 N5 D39 N+ ^) y+ `8 `+ ]# S' _; y
预处理9 j' N, B# E# V6 J
& Y9 v8 f- p0 C5 U5 S
图形处理* x( G4 I( `1 h' K: d% S) j
) z, S/ j4 E: _+ [0 e/ \
我们还需要处理一下图形数据,把它变成我们的网络认识的样子。! U, ]" D; u# p8 {

% z4 x) G' o( k( s0 z. zMNIST 数据集里的图片是 28x28 的,每个值是属于 [0, 255] 的 uint8。3 U5 n8 I6 m9 p$ S5 l' C
而我们的神经网络想要的是 28x28 的在 [0, 1] 中的 float32。
$ T2 g0 N$ n% b! w3 b% N) f, S
& i0 ~+ e. s% O; L2 z; Itrain_images = train_images.reshape((60000, 28 * 28))
! \  W" ]* l6 `train_images = train_images.astype('float32') / 255
& @2 C/ K8 W; x+ k* L: M
3 o0 i) X6 o5 C8 j- y: T0 stest_images = test_images.reshape((10000, 28 * 28)); y: M  A' o6 z  h2 D
test_images = test_images.astype('float32') / 255
& c- C5 ?, j8 U1
8 C7 K- P; m5 |+ |. a2) i6 }" n/ u# J# u9 E7 |6 [/ Z0 o
3" P4 k6 ?- W5 M- t& Q
4
* l" v8 n* t' a: t5
% A+ U# [4 ^/ o4 \标签处理
8 h* K( {# [8 |0 e/ `+ x% k" T6 m& f
同样,标签也是需要处理一下的。
" C! C# \" f& v0 s) D8 ^' i  Y! j8 L, O/ |; w) S7 p
from tensorflow.keras.utils import to_categorical6 n* W" y, M+ r" D* V. I0 l, a
9 I4 P. o' v6 N! N9 r  N8 b
train_labels = to_categorical(train_labels)* V. r# g3 k, x6 v/ `" h) [
test_labels = to_categorical(test_labels)4 A- Z) S9 w9 _' [
1. [8 i5 U7 ^+ H& D4 z6 {
2
9 b; R6 x5 q0 m) U3
9 I2 }6 T5 ]' T" x* P4
1 H: {3 b7 s+ o2 i3 I+ N训练网络9 e$ S6 E4 w" I0 \) b. ^5 W

. V# [- f% u% e5 y5 Onetwork.fit(train_images, train_labels, epochs=5, batch_size=128)! m2 ?  d5 r1 z& I" i  V6 c" T) j
1: ^' X; C! ^" C- s
输出:
( S5 o1 J" u; c0 D  f9 h8 ~0 o3 W" N) f) I& A. ]2 r* y* k
Train on 60000 samples: _6 [; U" C( r5 s
Epoch 1/5
, \: P/ Z( O# j. N60000/60000 [==============================] - 3s 49us/sample - loss: 0.2549 - accuracy: 0.9254" Y) Q  J2 z' c7 \. N8 w
Epoch 2/5
; ~/ @9 X& P1 @$ W, k/ ^- C60000/60000 [==============================] - 2s 38us/sample - loss: 0.1025 - accuracy: 0.9693) u! Y1 T0 W9 P% ^7 W
Epoch 3/57 c0 R1 N$ L% A0 E3 j9 g  `
60000/60000 [==============================] - 2s 35us/sample - loss: 0.0676 - accuracy: 0.9800
; M+ x" F) a8 Z6 hEpoch 4/5
' X# d5 e* e) B1 c0 ~& a" D60000/60000 [==============================] - 2s 37us/sample - loss: 0.0491 - accuracy: 0.98480 S6 t9 D8 @7 O) F# S
Epoch 5/5! k. i0 z5 f1 a$ F% E* f( @5 J
60000/60000 [==============================] - 2s 42us/sample - loss: 0.0369 - accuracy: 0.9888; ]$ R$ D! T. z; h- u

" K/ T- S2 {) D9 {/ N1 L& O<tensorflow.python.keras.callbacks.History at 0x13a7892d0>
/ i+ [* k  f4 K6 b11 ^8 S1 L9 y, j
2
! D* p: [  T- G7 L, q3
6 e* ?* c1 J9 Y9 C( N( l0 J4
# J8 @6 y4 i7 ~" ]8 C5
) \1 @& V  `9 K# D) K6 H4 h* ?6
+ }8 H! l( Z' n! ]% R$ U7
" Y7 N$ X# |: ]3 f# n: M85 D0 o* r: X1 s7 X
9
) W! h' k9 J& W8 W9 I6 O" E8 I10" {1 ~# X( _0 L# T* N  P
11
% m! [! L+ L' f- S0 k121 D0 g, ^" g9 w% }: i, N8 k& r$ _
136 @! r# y8 Y$ ?% E* z5 g* A$ n
可以看到,训练很快,一会儿就对训练集有 98%+ 的精度了。# J0 m+ y8 S$ @/ A

- V7 y/ g6 v8 t3 O1 V+ k8 @5 ~再用测试集去试试:
7 K0 m4 @1 h* J9 d1 |. d6 @& D) U2 c' c/ J  r
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
8 h4 p: q* g& `/ O9 Eprint('test_acc:', test_acc)
) v% E/ L) F  F1
8 U' x  y( ~; p4 P5 t2
* `; q& ^+ W- i9 M- ^, B* h输出:
8 ]" s0 G+ t- G# \, O; p
: |6 K7 s2 ?% @0 d5 i' S10000/1 - 0s - loss: 0.0362 - accuracy: 0.9789
+ J" f: t; h3 [$ A9 V- Utest_acc: 0.9789: [2 y- z% A3 q8 f# q  I- E+ b
1
! ?7 a$ l. X& D  Q# z2 `0 D2! _1 p! {' \% t& `! g1 V4 E# n
我们训练好的网络在测试集下的表现并没有之前在训练集中那么好,这是「过拟合」的锅。. T! E* j8 E( r- m, z
3 H& @$ L) D- }! o9 Z
神经网络的数据表示
( [/ i% U) N- e7 c. b" A- P- e. f7 K: c9 }4 @
Tensor,张量,任意维的数组(我的意思是编程的那种数组)。矩阵是二维的张量。
) Y7 n  f  V1 W6 _, h& @
: W; [: `$ E5 F) W4 @我们常把「张量的维度」说成「轴」。7 E# O7 y& z- V# S7 i) V

# K8 b3 m! i3 L5 ^认识张量
& G# B$ N3 G5 ~1 i" Z6 Z+ T: F8 Q( B; _/ K
标量 (0D Tensors)$ E3 C8 Z# y1 I% v
* v; i. U% N- i2 A! g
Scalars,标量是 0 维的张量(0个轴),包含一个数。$ @" E: P( ~1 Z# l4 s# Z

& b; O$ L0 K* Q2 s/ ~# g1 O* P标量在 numpy 中可以用 float32 或 float64 表示。5 ~8 I) q7 t$ X% X7 g/ F) K
8 e. ^+ a4 x- F  D
import numpy as np
, H' I8 }/ c8 B: V. ?
$ z4 @; I! ^, ^/ a/ U% q  |9 f8 ix = np.array(12)
% z! ]* v; A0 s4 Tx
5 ]! N1 D$ T; e* F1 [1
2 p; F* Q0 M; ?: H' O( C; D2
. h2 b0 W% a$ C' a3
6 m8 M. U+ o2 f; a4
. e. {! N( ]2 `2 d. a输出:& F0 g; [" I# Q+ U! |
( E6 R; c  h+ |2 x$ ~0 S
array(12)1 K/ G; r% W5 P0 X5 k& K
12 ^7 Y# N# c8 W+ r' K
x.ndim    # 轴数(维数)4 c! V! N$ r+ d3 z" B
1
6 D7 x' m( @; l. D, w( f+ u! i, \2 x输出:4 S; g$ ^5 X# ^! K7 T! @

, y/ W+ J  {' c9 f1* M6 `% p. S; X- N7 H
1) d, K( K! n8 v! t& C5 v2 W
向量 (1D Tensors)
4 W! k% g$ i' ]: `
, i! o6 x: r, I; t$ R6 uVectors,向量是 1 维张量(有1个轴),包含一列标量(就是搞个array装标量)。# G. `" J( {! K, r0 N
' N, C, G2 z/ V4 S( C+ _: |
x = np.array([1, 2, 3, 4, 5])
- G$ d7 m! F1 }' S" ^8 Nx
' x' W9 F) ^$ Q3 j5 S* E6 B" n1
" Y' d0 s- }& e8 w2  C" n8 D8 l' Y8 `
输出:& Y! U" h4 l+ l# P  @1 A$ q

$ F( \7 f- G3 n) B% k; n4 Larray([1, 2, 3, 4, 5])6 _5 i) y5 U4 B. Z# w
1$ Y0 ?3 q2 G9 y0 Q$ ?3 h2 F1 x
x.ndim
/ C5 T: b2 K) l1
# `4 V8 J/ F  K: F+ W输出:
0 D/ y+ a+ V; {% \# k8 p" b% g: L; b/ O1 t! o0 y& }) N
1
; G- B) ?! K8 J8 H- s( G; m5 R. D1
7 w( s5 a+ y% f0 _( H我们把这样有5个元素的向量叫做“5维向量”。
4 |4 z6 F- w8 k8 n" g' o但注意5D向量可不是5D张量!
- N, `/ C7 w8 Y% H$ f. F- Y* u% Q/ z( z( f, O
5D向量:只有1个轴,在这个轴上有5个维度。# _8 a' x5 h# j; }- a
5D张量:有5个轴,在每个轴上可以有任意维度。8 j7 a' {" [2 n2 ]; [5 ^- m4 v
这个就很迷,这“维度”有的时候是指轴数,有的时候是指轴上的元素个数。% Y/ W5 @/ X0 A2 R1 d* n
5 P/ Y+ J4 O% f: t! Q
所以,我们最好换种说法,用「阶」来表示轴数,说 5阶张量。
; f1 g$ h$ l/ q3 }; l: x/ D  e4 _2 A, H& R- t* v
矩阵 (2D Tensors), a; y8 V/ k- i3 {2 i* k
, p( |; w) C# e5 K
Matrices,矩阵是 2 阶张量(2个轴,就是我们说的「行」和「列」),包含一列向量(就是搞个array装向量)。
) C) v( D3 ^5 n% v- f1 k7 e* T- E% V9 u/ p! _+ ~4 O
x = np.array([[5, 78, 2, 34, 0],
6 m/ f( y( u; N/ W3 O' Z              [6, 79, 3, 35, 1],/ @* r, j1 e. T+ `
              [7, 80, 4, 36, 2]])
5 b6 B: K/ e% o3 Ix
4 K& k+ N0 j& R# h0 d. S1* o0 ]7 m7 o/ U( l7 B& K& x, K
21 R; n: ^5 v! S+ N: i
31 ^5 T8 k# @% I3 z8 E: s: k. _
4( N' Z- w# e, f  O
输出:
8 |2 H7 v2 W3 C7 M1 L; ]' G: z5 _; K' F( x% Z' B' p; c
array([[ 5, 78,  2, 34,  0],* a8 F* G" U5 p6 q0 H7 t. u3 D  o
       [ 6, 79,  3, 35,  1],9 t2 F. l. F) ]' b. U8 f) @
       [ 7, 80,  4, 36,  2]])
' q' u+ ?; b* _1/ u+ O* V3 Y! J/ \9 H6 t  \# ^- ?+ W
2! T" y, K3 z7 q. x5 \9 z2 v6 {
3
! C# a. ^% N" r8 g$ p- ?x.ndim
0 U( K7 i5 v; j3 Z! |9 c3 T2 t4 H  N1
+ b6 N0 D, h& F" S输出:% w$ V% j( I9 @+ c* _
9 \& S$ e: C' t& n- G& ?1 o+ q7 U
23 E7 U. F# P8 ?6 z! I
1
0 ~7 K  @/ |/ G高阶张量
4 Y8 E; p# b# a# q
. Y" w$ f- e5 C  v# c+ [2 p你搞个装矩阵的 array 就得到了3阶张量。( K  S# C+ {5 l! g: T* _# ^* Y

/ ]; P+ x: Q/ v再搞个装3阶张量的 array 就得到了4阶张量,依次类推,就有高阶张量了。
3 G- f7 I+ s" q: B+ [& ~& {
* M* {- u' R% B8 ~1 Ux = np.array([[[5, 78, 2, 34, 0],
; Z! o) i6 l, J1 }( _+ M0 J8 r2 ~               [6, 79, 3, 35, 1],  \3 e- A, i( X# S
               [7, 80, 4, 36, 2]],; L* X7 R' j& V3 A! i4 }
              [[5, 78, 2, 34, 0],
: j6 X+ B0 \9 A$ C               [6, 79, 3, 35, 1],
# A; m( a' s& O4 n& @: ^& I- w               [7, 80, 4, 36, 2]],
( b" p" l3 p& i! n3 {6 ^" }              [[5, 78, 2, 34, 0],
  c# Z6 |. F3 l( F! \               [6, 79, 3, 35, 1],) ]4 q5 `3 O7 l" O$ }' w! ?9 D& B
               [7, 80, 4, 36, 2]]])6 Q: G2 V. t, \  e
x.ndim
( H! m( O5 k' \3 C) g18 Q/ W- A2 E6 y2 _9 f. H- E& t/ a
2. b" _$ _7 l8 [$ u4 ~, N
3  P" u+ z- P5 x! l4 m8 S3 h* V4 Z
4
! m' n7 E$ I- j( |5- t0 B3 H$ ]  y9 A8 J
6  o2 R1 x' Y, w- d/ N( R
75 @# l9 h* s. v% A1 e; I. M
87 [8 K9 x$ x/ {4 ]
9
# G; p% K8 X! H! q10
) X; ^' A6 [# k7 L8 @" s输出:) v/ Y$ {. O1 }

9 {$ X% D& }' E$ s$ K' }, u2 f30 y7 v5 i- q! `9 n! C# N
11 r3 W, _6 D: n1 p* u
深度学习里,我们一般就用0~4阶的张量。
: L/ C4 e0 K  b7 [3 y% n; Q( S4 ]  i9 C3 C- ^
张量的三要素. e) W7 A% i5 g) S

2 f* g# K$ X2 H* ^$ O* L1 w阶数(轴的个数):3,5,…
; O3 W$ _& K7 B: q6 z" O6 V形状(各轴维数):(2, 1, 3),(6, 5, 5, 3, 6),…7 @' `8 m! S! v+ |
数据类型:float32,uint8,…/ Y1 L2 T, D3 ]
我们来看看 MNIST 里的张量数据:
& R+ M8 |* P9 P8 T( w( ~  O7 k+ B, V2 R/ M) }4 a; ~+ J
from tensorflow.keras.datasets import mnist5 `6 h9 A$ F) ~0 R
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()( }3 E+ o4 S9 t  f, X; r
7 w9 |0 H5 ~1 E! e
print(train_images.ndim)1 Q! r8 E& c- S3 V
print(train_images.shape)
; d& Q6 l: m- B2 W: s# @- jprint(train_images.dtype)
: c: [" M) A& \  ]1) r/ V4 M% K! O- K6 R- K
29 {7 S# I! ?7 ~8 V8 f$ }
3" T' D' p. r  S. Q6 a& G
4
+ _# ]: I2 e9 R. k- S9 u) \5
  b( a+ W% c: W& [6
) F6 f' D0 E, |/ P% L' }输出:3 i  q4 L/ H7 R- H6 r1 }( W

( k( \' E2 u& }( s& [' N3+ C9 {6 r& Z! F
(60000, 28, 28)+ w6 {- \5 `2 ?" r8 b' D( Y- T& }
uint8
; ^. Y( u: M9 u+ t0 Z6 G$ S1
  A! f, p  V+ @9 I2+ G* \7 q; g: M" Q
3
( v4 y" b3 U" g. T: g+ `所以 train_images 是个8位无符号整数的3阶张量。1 D$ i) x( k) Q6 R; X' U3 \  E

: n$ x* H  o  ]- d打印个里面的图片看看:) Y. T4 c  b: P# q: m+ t

$ s6 w% r0 {' \% Wdigit = train_images[0]
7 {- k( [! o, f6 {$ K, e9 _( o
7 B. c+ X/ A5 g% T7 @; B  W+ A' qimport matplotlib.pyplot as plt
0 G& \3 M; u3 t: d5 e
7 w& x2 o3 y% [& x7 T6 N; Aprint("image:")5 T) a, X5 l) r5 c
plt.imshow(digit, cmap=plt.cm.binary)
+ w' J/ l, _) Bplt.show(), D  T! ]: h/ r4 i# Y
print("label: ", train_labels[0])" F( f* q8 W; g+ D
1( y  E: Y) |8 @4 x; @: s, w; r( c
2
/ ?2 T0 c8 d4 j% v3
2 A; f- \$ o( o9 _4 g- m9 O9 e4
5 l+ l( a: _' n1 t- I, i5! ?/ D" D5 S5 o4 r
60 S; X" Y0 M& G6 F4 V3 O2 f) u4 j
74 H1 Q7 z1 }# t0 F  C+ O; _" [0 W
80 v( S- u! J% n* L& n5 P; o' {! i
输出:" I8 c& ?2 Z% T% p
: O6 F1 I$ L" v
1.jpg   B9 L1 a* f9 L! S: d. Z; s

) O& w0 z8 U; Ylabel:  5
5 v. C- K! Q9 P: w$ j$ {1
  d! Q6 n0 r% F. X" J$ gNumpy张量操作: a3 f. `- D3 T5 Z7 X- P

/ b8 U+ z. }8 E2 Q' I: F7 h张量切片:
/ J* y7 v0 L" t: O. x
  \. W& E1 U+ j  emy_slice = train_images[10:100]
4 c# z! f; Z$ @3 ?4 w# R3 r( j- ]print(my_slice.shape)
( y* `! R" t+ l  N1( v$ j7 z' b7 F% ~+ Y1 t( u5 Z
2
6 n+ h$ @! @. e  ]# M输出:0 A& I$ }7 p- I+ ]
2.jpg . v- @1 ^0 A' y
(90, 28, 28)
$ f, ]3 ~1 _9 H& b" B9 X& x+ T1
2 o9 n* H5 F$ u( A+ I% y等价于:9 K# a8 a  p! ?% W* ~) H

' q4 F1 U4 W! n8 K0 emy_slice = train_images[10:100, :, :]; n7 Z) i' i# H5 t) a5 a. x
print(my_slice.shape)
; B, E1 p' N. Z1
+ N4 V( s8 n/ j2 W- B2, D( ]( i& c* I' I* v& U& s
输出:5 p( B: U" \  Y) M# y' f
3.jpg   R( B/ |7 T9 ?4 v7 \. G$ `
(90, 28, 28)
- ~5 u7 w. V9 h6 ?) O3 J6 A1
: b' j1 s9 }2 T& G, Q! \也等价于
9 X1 w6 H% T# W; l+ m, Z% p) n+ _: S, V% I3 t8 S& R9 D  |% k
my_slice = train_images[10:100, 0:28, 0:28]
" p% E: [* O; \6 f1 D# x+ x. w. Aprint(my_slice.shape)3 f- H1 X$ j* e  y0 }& f/ \
17 k5 M/ h' r) Y$ h6 k; k; b3 A
2
9 W. s  l8 [" V输出:
9 b7 y2 O5 q2 O: k: z( L( {5 K& _( m7 b# B" K9 M5 i& u
(90, 28, 28): T. C* `  r4 ]; M# ]7 s2 z
1) Y$ x" t) e) r; X+ V
选出 右下角 14x14 的:
  e8 S7 Y: [7 V$ m6 K' K' M! F0 m
my_slice = train_images[:, 14:, 14:]% _6 l4 l8 r, W
plt.imshow(my_slice[0], cmap=plt.cm.binary)
8 ?6 t4 E9 e) D# \6 }, L" rplt.show()
5 I0 e$ f& @3 X  w4 N+ X* X  n1
' r7 }# H# z+ `& a7 o$ F8 J4 q2+ Z) B) |' z; f9 V
3
' e$ Z( `7 O; k1 ^' b输出:
( C2 F, f% W+ I0 f# p+ w+ k9 D2 [! \! L# O3 Y
6 o* a' y( ^) j, G

1 M! j2 A' J( N# e& e, F选出 中心处 14x14 的:
6 H7 ]  f& [- G1 x
- C% ^" A* [9 W4 v- T" Lmy_slice = train_images[:, 7:-7, 7:-7]4 M$ A* `$ P2 i5 D* y* E+ Q5 _
plt.imshow(my_slice[0], cmap=plt.cm.binary)
! e( ?" ]; @0 X  w) L0 H) ?+ Hplt.show()
: a3 Y! l; K* N8 g; N, w6 u' w* d0 X1& @" d4 b+ y9 _9 b! ]4 s# J8 G
2% l8 I# A2 p# X, R, r( d
3
3 ]1 Z: I% t' m. Q3 v% `) y输出:
+ s  y! r- |' [2 y# d- I8 v. `4 |5 D
4 L4 l* W+ @$ U2 ]. L0 |0 @

7 ~& ~! s* i- J) ^/ r7 K数据批量# }. _' q) z' h" @- V
- q7 ]# T# ^% l/ w, z: V9 l) D
深度学习的数据里,一般第一个轴(index=0)叫做「样本轴」(或者说「样本维度」)。
& U+ h8 J' A. J/ w9 f, m) A. P" G: L4 }+ q
深度学习里,我们一般不会一次性处理整个数据集,我们一批一批地处理。8 _3 d" T3 [1 {
0 a4 Z" }8 d' b! U. E# H/ T- Z" t
在 MNIST 中,我们的一个批量是 128 个数据:9 ~' Y/ G0 q/ R5 U6 I

6 e# [0 M6 c+ i# k% p( [  k0 `# 第一批2 _$ A  W9 S) l1 o  o; N1 m
batch = train_images[:128]
; v0 t2 ]; t7 u& f# 第二批
2 x7 F: q& M" o; m7 E1 Ybatch = train_images[128:256]$ @4 E( i  A  r* }, g* |6 @
# 第n批  t, Q6 t/ a% u; ?
n = 12+ m" @- l% A1 t: ~
batch = train_images[128 * n : 128 * (n+1)]% `- N4 w9 E0 j& Y- v8 I! _% a
1
0 `4 e3 L# c7 ~  S" W2 m& n2* m) F: {5 ^' Y% g( F
3
1 D6 j# X6 b$ l% A5 T( _! o4. ^- x2 {7 u5 z* W. b- g" @
5
5 w: W' d" U1 f) W6
0 i( q$ C, F" [" O7& p( [6 ^1 o0 [1 J
所以,在使用 batch 的时候,我们也把第一个轴叫做「批量轴」。
& S" Z% p: f1 a& }- [* Q  L. v
常见数据张量表示
7 L# G+ A" P0 I4 @7 v( H5 c! O* g4 S$ s2 G  a1 P" Q+ O
数据
$ P- O# \( D) H2 Y: F
作者: 2863358207    时间: 2020-5-12 12:11
好好好好好好好好好啊发表回复" c' @. [& x# @





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