Day24 - 静态模型 part2 (CNN)

在 CNN-based 的架构中,会使用三种不同的 CNN 架构:

  1. Basic CNN
  2. Multi-Scale CNN
  3. Multi-Scale CNN with Attention Mechanism

要让语音特徵能够进入到 CNN 中,就必须将其转换成图片的维度格式。因此我们将原本384为的特徵向量 reshape 成 16x12x2 的张量(Tensor)作为 CNN 的输入。


首先是 Basic CNN 的部份,模型包含了四层卷积层(conv),每一层的输出特徵图(feature map)维度皆为 40,其卷积核(kernel)大小分别为:5x5、3x3、2x2 与 1x1。每一层的卷积层後都会接上一层最大池化层(max-pooling),其pooling size 与前一层卷积层的卷积核大小相同。经过四层的卷积层与最大池化层後,我们会将特徵图向量化(flatten)并输入至最後的输出层中,架构如图 1
https://ithelp.ithome.com.tw/upload/images/20211006/20140944z4chXdVmMd.png
图 1: CNN静态模型。每一层卷积层後的 activation function 为 ReLU,所有卷积层的最大池化层padding 方式皆为 zero-padding,卷基层 stride=2:最大池化层 stride=1


接下来说明的是 Multi-Scale CNN
Multi-scale CNN 的主要想法是基於如何找出近似 CNN 中的最佳局部稀疏结
构,目标是找出最佳的局部结构并在空间上重复。我们会透过使用多种不同大小卷
积核的卷积层来撷取相关的特徵(包含1x1、3x3、5x5、7x7、9x9)。Multi-scale
CNN 架构中另一个重要的部份为 max-out activation unit,max-out activation unit 的输入为多个不
同大小卷积核的卷积层的输出,并透过取最大值的方式来使多个卷积核相互竞争,最
後的输出即为这些卷积层输出中的最大值。在此机制中,会产生一个局部的控制机
制,让非 0 的 activation value 在传递时只会通过网路中的其中一部份。藉由此方法,在原始的
模型架构内部建构一子网路可以使模型处理更为复杂的问题。

此部份是以 Basic CNN 基础并加入 multi-scale 模组,模型架构如图 2。第一层包含五种不同
大小的卷积核,分别是:1x1、3x3、5x5、7x7 与 9x9,其输出的特徵图维度皆为 40,接下来使用max-out unit从五个相同维度的特徵图中挑选出最大值。第二层中,我们将前一层中最大的卷积核(9x9)移除并将输出的特徵图维度减为 30,一样使用 max-out unit 从四个相同维度的特徵图中挑选出最大值。第三及第四层以相同的模式移除前一层中最大的卷积核并将输出的特徵图维度减少,经过四层的多尺度卷积层後将特徵图向量化 (Flatten) 并输入至最後的输出层中。
https://ithelp.ithome.com.tw/upload/images/20211006/20140944gz1gu4d98o.png
图 2: Multi-scale CNN 静态模型。每一层卷积层後的activation function 使用 ReLU,所有卷积层 padding 方式皆为 zero-padding,浅绿色卷积层 stride=2;深绿色卷积层 stride=1

程序的部分如下

cnn_train_data = np.reshape(train_data, (train_data.shape[0], args.llds, args.functionals, args.delta))
cnn_test_data = np.reshape(test_data, (test_data.shape[0], args.llds, args.functionals, args.delta))

# 8x6x40
conv1_1 = Conv2D(filters=40,kernel_size=(1,1),strides=(2,2),padding='same', activation='relu', name='conv1_1')(cnn_input)
conv1_2 = Conv2D(filters=40,kernel_size=(3,3),strides=(2,2),padding='same', activation='relu', name='conv1_2')(cnn_input)
conv1_3 = Conv2D(filters=40,kernel_size=(5,5),strides=(2,2),padding='same', activation='relu', name='conv1_3')(cnn_input)
conv1_4 = Conv2D(filters=40,kernel_size=(7,7),strides=(2,2),padding='same', activation='relu', name='conv1_4')(cnn_input)
conv1_5 = Conv2D(filters=40,kernel_size=(9,9),strides=(2,2),padding='same', activation='relu', name='conv1_5')(cnn_input)
conv1_maxout = maximum([conv1_1, conv1_2, conv1_3, conv1_4, conv1_5], name='conv_max1')
#4x3x30
conv2_1 = Conv2D(filters=30,kernel_size=(1,1),strides=(1,1),padding='same', activation='relu', name='conv2_1')(conv1_maxout)
conv2_2 = Conv2D(filters=30,kernel_size=(3,3),strides=(1,1),padding='same', activation='relu', name='conv2_2')(conv1_maxout)
conv2_3 = Conv2D(filters=30,kernel_size=(5,5),strides=(1,1),padding='same', activation='relu', name='conv2_3')(conv1_maxout)
conv2_4 = Conv2D(filters=30,kernel_size=(7,7),strides=(1,1),padding='same', activation='relu', name='conv2_4')(conv1_maxout)
conv2_maxout = maximum([conv2_1, conv2_2, conv2_3, conv2_4], name='conv_max2')
#2x2x20
conv3_1 = Conv2D(filters=20,kernel_size=(1,1),strides=(1,1),padding='same', activation='relu', name='conv3_1')(conv2_maxout)
conv3_2 = Conv2D(filters=20,kernel_size=(3,3),strides=(1,1),padding='same', activation='relu', name='conv3_2')(conv2_maxout)
conv3_3 = Conv2D(filters=20,kernel_size=(5,5),strides=(1,1),padding='same', activation='relu', name='conv3_3')(conv2_maxout)
conv3_maxout = maximum([conv3_1, conv3_2, conv3_3], name='conv_max3')
#1x1x10
conv4_1 = Conv2D(filters=10, kernel_size=(1,1),strides=(1,1),padding='same', activation='relu', name='conv4_1')(conv3_maxout)
conv4_2 = Conv2D(filters=10, kernel_size=(3,3),strides=(1,1),padding='same', activation='relu', name='conv4_2')(conv3_maxout)
conv4_maxout = maximum([conv4_1, conv4_2], name='conv_max4')

output = Dense(units=args.classes, activation='softmax', name='output')(conv4_maxout)
model = Model(inputs=cnn_input, outputs=output)
model.summary()

明天将继续介绍 Multi-Scale CNN with Attention Mechanism 以及比较三种模型的效果~


<<:  Day20【Dev】编程方法:Imperative 与 Declarative

>>:  Day 21 Ruby 类别 vs 模组

Day08. 後疫情的新常态,运用Blue Prism「超前布署」好运自创-BP从Excel新建一个工作表

这两天台湾疫情又告急,基於同岛一命的概念防疫的习惯确实不宜松懈, 戴了一天的口罩,回到家里通常懒虫上...

Day 7-单元测试 NUnit 更多常用的特性-2 (基础-6)

如何撰写测试验证例外 — ExpectedExcetption 与 Assert.Throws(de...

Day 26 - 实战演练 — Notifier 、Notification

想先看 Code 或是 Demo 的由此去 Github Repo: ithelp-ui-demo...

day30_arm 还是 x86? 我知道该怎麽选了

ARM 与 x86 谁更对你胃口呢? 我们在之前的文章内讨论了很多 ARM 与 x86 的差异,互相...

企划实现(19)

在写app时常常会因为所有app在外观看起来一样,所以往往会要找很久才能找到自己想要执行的app,所...