mnist cnn
导入包
% reload_ext autoreload
% autoreload 2
% matplotlib inline
from fastai. vision import *
导入数据
path = untar_data( URLs. MNIST)
path. ls( )
[WindowsPath('C:/Users/Wither8848/.fastai/data/mnist_png/testing'),
WindowsPath('C:/Users/Wither8848/.fastai/data/mnist_png/training')]
il = ImageList. from_folder( path, convert_mode= 'L' )
il. items[ 0 ]
WindowsPath('C:/Users/Wither8848/.fastai/data/mnist_png/testing/0/10.png')
defaults. cmap= 'binary'
il
ImageList (70000 items)
Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28)
Path: C:\Users\Wither8848\.fastai\data\mnist_png
il[ 0 ] . show( )
分割数据集
sd = il. split_by_folder( train= 'training' , valid= 'testing' )
ll = sd. label_from_folder( )
ll
LabelLists;
Train: LabelList (60000 items)
x: ImageList
Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28)
y: CategoryList
0,0,0,0,0
Path: C:\Users\Wither8848\.fastai\data\mnist_png;
Valid: LabelList (10000 items)
x: ImageList
Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28),Image (1, 28, 28)
y: CategoryList
0,0,0,0,0
Path: C:\Users\Wither8848\.fastai\data\mnist_png;
Test: None
tfms = ( [ * rand_pad( padding= 3 , size= 28 , mode= 'zeros' ) ] , [ ] )
ll = ll. transform( tfms)
bs = 128
这里不使用预训练,所以不需要加imagenet_stats
data = ll. databunch( bs= bs) . normalize( )
x, y = data. train_ds[ 0 ]
x. show( )
print ( y)
0
def _plot ( i, j, ax) : data. train_ds[ 0 ] [ 0 ] . show( ax, cmap= 'gray' )
plot_multi( _plot, 3 , 3 , figsize= ( 8 , 8 ) )
xb, yb = data. one_batch( )
xb. shape, yb. shape
(torch.Size([128, 1, 28, 28]), torch.Size([128]))
data. show_batch( rows= 3 , figsize= ( 5 , 5 ) )
定义卷积网络
def conv ( ni, nf) : return nn. Conv2d( ni, nf, kernel_size= 3 , stride= 2 , padding= 1 )
model = nn. Sequential(
conv( 1 , 8 ) ,
nn. BatchNorm2d( 8 ) ,
nn. ReLU( ) ,
conv( 8 , 16 ) ,
nn. BatchNorm2d( 16 ) ,
nn. ReLU( ) ,
conv( 16 , 32 ) ,
nn. BatchNorm2d( 32 ) ,
nn. ReLU( ) ,
conv( 32 , 16 ) ,
nn. BatchNorm2d( 16 ) ,
nn. ReLU( ) ,
conv( 16 , 10 ) ,
nn. BatchNorm2d( 10 ) ,
Flatten( )
)
learn = Learner( data, model, loss_func = nn. CrossEntropyLoss( ) , metrics= accuracy)
print ( learn. summary( ) )
Sequential
======================================================================
Layer (type) Output Shape Param # Trainable
======================================================================
Conv2d [8, 14, 14] 80 True
______________________________________________________________________
BatchNorm2d [8, 14, 14] 16 True
______________________________________________________________________
ReLU [8, 14, 14] 0 False
______________________________________________________________________
Conv2d [16, 7, 7] 1,168 True
______________________________________________________________________
BatchNorm2d [16, 7, 7] 32 True
______________________________________________________________________
ReLU [16, 7, 7] 0 False
______________________________________________________________________
Conv2d [32, 4, 4] 4,640 True
______________________________________________________________________
BatchNorm2d [32, 4, 4] 64 True
______________________________________________________________________
ReLU [32, 4, 4] 0 False
______________________________________________________________________
Conv2d [16, 2, 2] 4,624 True
______________________________________________________________________
BatchNorm2d [16, 2, 2] 32 True
______________________________________________________________________
ReLU [16, 2, 2] 0 False
______________________________________________________________________
Conv2d [10, 1, 1] 1,450 True
______________________________________________________________________
BatchNorm2d [10, 1, 1] 20 True
______________________________________________________________________
Flatten [10] 0 False
______________________________________________________________________
Total params: 12,126
Total trainable params: 12,126
Total non-trainable params: 0
Optimized with 'torch.optim.adam.Adam', betas=(0.9, 0.99)
Using true weight decay as discussed in https://www.fast.ai/2018/07/02/adam-weight-decay/
Loss function : CrossEntropyLoss
======================================================================
Callbacks functions applied
xb = xb. cuda( )
model( xb) . shape
torch.Size([128, 10])
learn. lr_find( end_lr= 100 )
epoch train_loss valid_loss accuracy time
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
learn. recorder. plot( )
learn. fit_one_cycle( 3 , max_lr= 0.1 )
epoch train_loss valid_loss accuracy time 0 0.205921 0.239571 0.923200 01:15 1 0.133586 0.106650 0.966700 01:15 2 0.073912 0.037999 0.987900 01:15
重构
def conv2 ( ni, nf) : return conv_layer( ni, nf, stride= 2 )
learn = Learner( data, model, loss_func = nn. CrossEntropyLoss( ) , metrics= accuracy)
learn. fit_one_cycle( 10 , max_lr= 0.1 )
epoch train_loss valid_loss accuracy time 0 0.075848 0.053845 0.982700 01:17 1 0.134479 0.116663 0.962900 01:17 2 0.132610 0.129293 0.957600 01:17 3 0.120464 0.089858 0.971400 01:16 4 0.114673 0.149974 0.949800 01:17 5 0.093295 0.155492 0.946700 01:16 6 0.076396 0.042374 0.986400 01:17 7 0.059397 0.035004 0.989000 01:17 8 0.051365 0.025874 0.992000 01:16 9 0.040192 0.024220 0.992600 01:16
加入resnet
class ResBlock ( nn. Module) :
def __init__ ( self, nf) :
super ( ) . __init__( )
self. conv1 = conv_layer( nf, nf)
self. conv2 = conv_layer( nf, nf)
def forward ( self, x) : return x + self. conv2( self. conv1( x) )
help ( res_block)
Help on function res_block in module fastai.layers:
res_block(nf, dense: bool = False, norm_type: Union[fastai.layers.NormType, NoneType] = <NormType.Batch: 1>, bottle: bool = False, **conv_kwargs)
Resnet block of `nf` features. `conv_kwargs` are passed to `conv_layer`.
model = nn. Sequential(
conv2( 1 , 8 ) ,
res_block( 8 ) ,
conv2( 8 , 16 ) ,
res_block( 16 ) ,
conv2( 16 , 32 ) ,
res_block( 32 ) ,
conv2( 32 , 16 ) ,
res_block( 16 ) ,
conv2( 16 , 10 ) ,
Flatten( )
)
def conv_and_res ( ni, nf) : return nn. Sequential( conv2( ni, nf) , res_block( nf) )
model = nn. Sequential(
conv_and_res( 1 , 8 ) ,
conv_and_res( 8 , 16 ) ,
conv_and_res( 16 , 32 ) ,
conv_and_res( 32 , 16 ) ,
conv2( 16 , 10 ) ,
Flatten( )
)
learn = Learner( data, model, loss_func = nn. CrossEntropyLoss( ) , metrics= accuracy)
learn. lr_find( end_lr= 100 )
learn. recorder. plot( )
epoch train_loss valid_loss accuracy time
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
learn. fit_one_cycle( 12 , max_lr= 0.05 )
epoch train_loss valid_loss accuracy time 0 0.203110 0.165042 0.952400 01:20 1 0.133723 0.180865 0.946200 01:20 2 0.113415 0.099760 0.967800 01:22 3 0.090575 0.085840 0.973300 01:20 4 0.075967 0.053531 0.984400 01:20 5 0.058811 0.049779 0.985500 01:21 6 0.051729 0.049316 0.985100 01:20 7 0.045310 0.030621 0.989900 01:20 8 0.037343 0.026640 0.992800 01:20 9 0.027271 0.018984 0.994300 01:20 10 0.019344 0.016725 0.994700 01:21 11 0.018691 0.015451 0.995100 01:21
print ( learn. summary( ) )
Sequential
======================================================================
Layer (type) Output Shape Param # Trainable
======================================================================
Conv2d [8, 14, 14] 72 True
______________________________________________________________________
ReLU [8, 14, 14] 0 False
______________________________________________________________________
BatchNorm2d [8, 14, 14] 16 True
______________________________________________________________________
Conv2d [8, 14, 14] 576 True
______________________________________________________________________
ReLU [8, 14, 14] 0 False
______________________________________________________________________
BatchNorm2d [8, 14, 14] 16 True
______________________________________________________________________
Conv2d [8, 14, 14] 576 True
______________________________________________________________________
ReLU [8, 14, 14] 0 False
______________________________________________________________________
BatchNorm2d [8, 14, 14] 16 True
______________________________________________________________________
MergeLayer [8, 14, 14] 0 False
______________________________________________________________________
Conv2d [16, 7, 7] 1,152 True
______________________________________________________________________
ReLU [16, 7, 7] 0 False
______________________________________________________________________
BatchNorm2d [16, 7, 7] 32 True
______________________________________________________________________
Conv2d [16, 7, 7] 2,304 True
______________________________________________________________________
ReLU [16, 7, 7] 0 False
______________________________________________________________________
BatchNorm2d [16, 7, 7] 32 True
______________________________________________________________________
Conv2d [16, 7, 7] 2,304 True
______________________________________________________________________
ReLU [16, 7, 7] 0 False
______________________________________________________________________
BatchNorm2d [16, 7, 7] 32 True
______________________________________________________________________
MergeLayer [16, 7, 7] 0 False
______________________________________________________________________
Conv2d [32, 4, 4] 4,608 True
______________________________________________________________________
ReLU [32, 4, 4] 0 False
______________________________________________________________________
BatchNorm2d [32, 4, 4] 64 True
______________________________________________________________________
Conv2d [32, 4, 4] 9,216 True
______________________________________________________________________
ReLU [32, 4, 4] 0 False
______________________________________________________________________
BatchNorm2d [32, 4, 4] 64 True
______________________________________________________________________
Conv2d [32, 4, 4] 9,216 True
______________________________________________________________________
ReLU [32, 4, 4] 0 False
______________________________________________________________________
BatchNorm2d [32, 4, 4] 64 True
______________________________________________________________________
MergeLayer [32, 4, 4] 0 False
______________________________________________________________________
Conv2d [16, 2, 2] 4,608 True
______________________________________________________________________
ReLU [16, 2, 2] 0 False
______________________________________________________________________
BatchNorm2d [16, 2, 2] 32 True
______________________________________________________________________
Conv2d [16, 2, 2] 2,304 True
______________________________________________________________________
ReLU [16, 2, 2] 0 False
______________________________________________________________________
BatchNorm2d [16, 2, 2] 32 True
______________________________________________________________________
Conv2d [16, 2, 2] 2,304 True
______________________________________________________________________
ReLU [16, 2, 2] 0 False
______________________________________________________________________
BatchNorm2d [16, 2, 2] 32 True
______________________________________________________________________
MergeLayer [16, 2, 2] 0 False
______________________________________________________________________
Conv2d [10, 1, 1] 1,440 True
______________________________________________________________________
ReLU [10, 1, 1] 0 False
______________________________________________________________________
BatchNorm2d [10, 1, 1] 20 True
______________________________________________________________________
Flatten [10] 0 False
______________________________________________________________________
Total params: 41,132
Total trainable params: 41,132
Total non-trainable params: 0
Optimized with 'torch.optim.adam.Adam', betas=(0.9, 0.99)
Using true weight decay as discussed in https://www.fast.ai/2018/07/02/adam-weight-decay/
Loss function : CrossEntropyLoss
======================================================================
Callbacks functions applied