mnist学习实例(2)

环境: Ubuntu 18.04, tensorflow 2.4.1

该版本是全连接网络的优化版本,采用了卷积神经网络,参考
可以看到BATCH_SIZE没有改动,而EPOCH明显减少。
但是EPOCH一轮的时间明显增长了很多。

代码

import tensorflow as tf
import numpy as np
from tensorflow import keras

EPOCH = 15
BATCH_SIZE = 128
VERBOSE = 1
NUM_CLASSES = 10


# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, NUM_CLASSES)
y_test = keras.utils.to_categorical(y_test, NUM_CLASSES)


## build network
model = tf.keras.Sequential(
    [
        tf.keras.Input(shape=(28, 28, 1)),
        tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
        tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
        tf.keras.layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
        tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(NUM_CLASSES, activation="softmax"),
    ]
)

model.summary()

## compile network
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCH, validation_split=0.1)

## validation  0.991
val_loss,val_acc = model.evaluate(x_test, y_test, verbose=VERBOSE)
print("Test loss: ", val_loss)
print("Test accuracy: ", val_acc)

model summary解读

model summary

输入层是 (,28,28,1)4维张量,分别是数量,长度,宽度,通道(灰度)

第一层conv2d

  • kernel_size=(3,3)
    因为输入时长宽相等,我们就看一边。 没有指定strides,默认为1,
    ( 28 − 3 ) / 1 + 1 = 26 (28-3)/1+1=26 (283)/1+1=26
  • filter=32
    表示有32个kernel,每个kernel在原张量上卷积后,都会有一个结果,所以最后一维就是32.
    这个就是第一层conv2dshape(,26,26,32)的由来。
  • param个数
    ( ( 核 宽 ∗ 核 高 ) ∗ 通 道 数 + 1 ) ∗ 卷 积 核 数 ((核宽*核高)*通道数+1)*卷积核数 (()+1)注:+1是因为一个bias
    ( ( 3 ∗ 3 ) ∗ 1 + 1 ) ∗ 32 = 320 ((3*3)*1+1)*32=320 ((33)1+1)32=320

第二层pooling

它主要是做收缩,所以不产生新的param。
pool_size=(2, 2),所以shape变成 (,13,13,32)

第三层conv2d

  • kernel_size=(3, 3)
    ( 13 − 3 ) / 1 + 1 = 11 (13-3)/1+1=11 (133)/1+1=11
  • filter=64
    所以shape为(,11,11,64)
  • param个数
    ( ( 核 宽 ∗ 核 高 ) ∗ 通 道 数 + 1 ) ∗ 卷 积 核 数 ( ( 核宽 *核高)*通道数+1)* 卷积核数 +1 注:这一层的通道数就是上层卷积核数
    ( ( 3 ∗ 3 ) ∗ 32 + 1 ) ∗ 64 = 18496 ((3*3)*32+1)*64=18496 ((33)32+1)64=18496

Flatten层

其实就是将多维张量变为一维输入,所以
5 ∗ 5 ∗ 64 = 1600 5*5*64=1600 5564=1600

dropout层都改变shape

最后dense层

  • param个数
    ( 通 道 数 + 1 ) ∗ 输 出 数 ( 通道数+1)* 输出数 +1
    ( 1600 + 1 ) ∗ 10 = 16010 (1600+1)*10=16010 (1600+1)10=16010

Total Param直观地体现了整体训练的时长

占用资源怎么样?

在云端上使用单虚拟核,1G内存是跑不了的,主要是内存不够。mnist跑起来大概需要1G+内存。


一些尝试

上面的样例,在15epoch跑下来,accuracy大致为0.991, 它比全连接网络确实准确了很多。

那么究竟增加卷积层带来了多少优化呢,在这里我们尝试做一些改动试一下。


TEST 1. 去除一层卷积层

网络结构
我们把两层卷积层中的第二层去除,看一下效果。
accuracy: 0.9831
准确度降低了约0.7%,从summary来看,时间(训练params个数)反而增加了。

model summary

另外,因为mnist数据集中的图片较小,卷积层对它特征提取效果与层数应该增加没有太大关联。

TEST 2. 去除每层卷积层的Pooling

网络结构
accuracy: 0.9968
准确度基本没有变化,但是时间(参数)指数级增长了

model summary

TEST 3. 去除Dropout层

网络结构
accuracy: 0.9868
根据前面的说明,可以看到dropout并不改变model的shape也不会减少训练的参数个数。
所以时间虽然跟TEST 2一样,但是效果没有上面的好

model summary

TEST 4. 只留一层Conv并修改Conv层kernel参数

网络结构

kernel_size=(3, 3) 改为kernel_size=(5, 5)
将kernel增加,是会增加该层的param的,所以虽然整体只有一层Conv2D,但是最终的训练参数比标准网络要多一个数量级

accuracy: 0.9871结果跟TEST 1差不多

model summary

TEST 5 只留一层Conv和Pooling并修改Conv层kernel参数

网络结构
与 TEST 4的区别就是,保留了Pooling层,其他都一致。

accuracy: 0.987结果也差不多

但可见参数数据量明显下降一个数量级,Pooling的作用还是很凸显的。
在这里插入图片描述

TEST 6. 只留一层Conv和Pooling,并修改Conv层filter参数

网络结构
filter=32 改为filter=8

accuracy: 0.9809

model summary

TEST 7. 只留一层Conv和Pooling,修改pooling参数

网络结构
pool_size=(2, 2) 改为pool_size=(5, 5))

accuracy: 0.977这个结果较原网络差了快2%,但是训练的参数最少,比原网络少了一个数量级

model summary

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值