iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0

前言

基礎的資料生成模組已經有了,那接下來今天會介紹基礎的模型定義方式。

模型的根本--任務(task)

在設計模型之前,要先體認到最根本的問題:我們要執行怎麼樣的任務?

根據我們前幾天資料的介紹,可以得知ChestMNIST是一項具有下列特徵的資料集:

  • 每一個資料點是一張胸腔X光影像
  • 每一張影像的解析度都是28x28
  • 由於是灰階,影像的channel是1 (相對於常見的rgb就是3)
  • Outcome的部份,則是分別預測影像之中是否存在給定的14個不同的症狀(且可能存在多個)

根據以上,可以進行一個基礎的設計來達成這個目標:

一個image in,然後會output出14個對應症狀機率值的模型。

design a backbone

這邊採用最常見的摺積神經網路(Convolutional Neural Network, CNN/ConvNet)作為開發,骨幹(backbone)的部份則是選取近年來很紅很高效的Efficient Net,是一個Google爸爸花了很多錢燒出來的框架,要好好的站在巨人的肩膀上。

現在很多地方都有 Efficient Net的實作可以直接採用,也包括MONAI。

這邊我們修改最小的B0來做使用。不過首先會發現一件問題是B0的設計是設計給ImageNet使用的,因此輸入的維度是常見的224x224:

>>> import monai
>>> monai.networks.nets.efficientnet.efficientnet_params['efficientnet-b0']
(1.0, 1.0, 224, 0.2, 0.2)

於是我們這裡稍微做一個小修改後再建立骨幹,以確保整個骨幹能夠正常運行:

monai.networks.nets.efficientnet.efficientnet_params['efficientnet-b0'] = (1.0, 1.0, 28, 0.2, 0.2)
model = monai.networks.nets.EfficientNetBN('efficientnet-b0', 
                                           spatial_dims = 2, # 表示2D 或 3D影像
                                           in_channels = 1, # 採用灰階 所以設定1
                                           num_classes = 14) # 14個不同的症狀

測試模型

這邊介紹一個好用的工具TorchInfo,可以用來觀看模型的各階層:

>>> import torchinfo
>>> torchinfo.summary(model, input_size=(16,1,28,28))
====================================================================================================
Layer (type:depth-idx)                             Output Shape              Param #
====================================================================================================
EfficientNetBN                                     [16, 14]                  --
├─ConstantPad2d: 1-1                               [16, 1, 29, 29]           --
├─Conv2d: 1-2                                      [16, 32, 14, 14]          288
├─BatchNorm2d: 1-3                                 [16, 32, 14, 14]          64
├─MemoryEfficientSwish: 1-4                        [16, 32, 14, 14]          --
├─Sequential: 1-5                                  [16, 320, 1, 1]           --
│    └─Sequential: 2-1                             [16, 16, 14, 14]          --
│    │    └─MBConvBlock: 3-1                       [16, 16, 14, 14]          1,448
│    └─Sequential: 2-2                             [16, 24, 7, 7]            --
│    │    └─MBConvBlock: 3-2                       [16, 24, 7, 7]            6,004
│    │    └─MBConvBlock: 3-3                       [16, 24, 7, 7]            10,710
│    └─Sequential: 2-3                             [16, 40, 4, 4]            --
│    │    └─MBConvBlock: 3-4                       [16, 40, 4, 4]            15,350
│    │    └─MBConvBlock: 3-5                       [16, 40, 4, 4]            31,290
│    └─Sequential: 2-4                             [16, 80, 2, 2]            --
│    │    └─MBConvBlock: 3-6                       [16, 80, 2, 2]            37,130
│    │    └─MBConvBlock: 3-7                       [16, 80, 2, 2]            102,900
│    │    └─MBConvBlock: 3-8                       [16, 80, 2, 2]            102,900
│    └─Sequential: 2-5                             [16, 112, 2, 2]           --
│    │    └─MBConvBlock: 3-9                       [16, 112, 2, 2]           126,004
│    │    └─MBConvBlock: 3-10                      [16, 112, 2, 2]           208,572
│    │    └─MBConvBlock: 3-11                      [16, 112, 2, 2]           208,572
│    └─Sequential: 2-6                             [16, 192, 1, 1]           --
│    │    └─MBConvBlock: 3-12                      [16, 192, 1, 1]           262,492
│    │    └─MBConvBlock: 3-13                      [16, 192, 1, 1]           587,952
│    │    └─MBConvBlock: 3-14                      [16, 192, 1, 1]           587,952
│    │    └─MBConvBlock: 3-15                      [16, 192, 1, 1]           587,952
│    └─Sequential: 2-7                             [16, 320, 1, 1]           --
│    │    └─MBConvBlock: 3-16                      [16, 320, 1, 1]           717,232
├─Identity: 1-6                                    [16, 320, 1, 1]           --
├─Conv2d: 1-7                                      [16, 1280, 1, 1]          409,600
├─BatchNorm2d: 1-8                                 [16, 1280, 1, 1]          2,560
├─MemoryEfficientSwish: 1-9                        [16, 1280, 1, 1]          --
├─AdaptiveAvgPool2d: 1-10                          [16, 1280, 1, 1]          --
├─Dropout: 1-11                                    [16, 1280]                --
├─Linear: 1-12                                     [16, 14]                  17,934
====================================================================================================
Total params: 4,024,906
Trainable params: 4,024,906
Non-trainable params: 0
Total mult-adds (M): 128.06
====================================================================================================
Input size (MB): 0.05
Forward/backward pass size (MB): 31.48
Params size (MB): 16.10
Estimated Total Size (MB): 47.63
====================================================================================================

最後以Batch Size = 16來實際測試 Forward Propogation:

>>> device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
>>> model = model.to(device)
>>> test_input = torch.rand([16,1,28,28]).to(device)
>>> test_output = model(test_input)
>>> print(test_output.shape)
torch.Size([16, 14])

一切大功告成!

本日小節

  • 根據任務展開的簡單模型需求設計
  • 以Efficient-B0來實作

上一篇
[Day05] Dataloader with PyTorch and MONAI
下一篇
[Day07] Model Training with PyTorch
系列文
PyTorch 生態鏈實戰運用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言