经典模型WDCNN中的AdaBN复现

最近自己的故障分类论文完成的差不多了,决定抽点时间复现一下引用比较多的WDCNN。之前都是直接用别人的实验数据,没有仔细阅读过相关论文,更没有考虑过复现的问题。仔细阅读这篇论文后,查阅了网上的资料才发现复现的帖子很少,且大部分只对WDCNN复现,有些里还有明显的错误,于是决定自己整一下。

原作者用的是tensorflow,我也是,但其实目前用pytorch复现更容易。

1.首先是WDCNN的模型代码

def WDCNN():
    inputs1 = Input(shape=(2048, 1))
    x = Conv1D(filters=16, kernel_size=64,strides=16,padding='same')(inputs1)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling1D(pool_size=2, strides=2)(x)

    x = Conv1D(filters=32, kernel_size=3, strides=1, padding='same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling1D(pool_size=2, strides=2, padding='valid')(x)

    x = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling1D(pool_size=2, strides=2)(x)

    x = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling1D(pool_size=2, strides=2)(x)

    x = Conv1D(filters=64, kernel_size=3, strides=1, padding='valid')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling1D(pool_size=2, strides=2)(x)


    x = Flatten()(x)
    x = Dense(100)(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    outputs = Dense(10, activation='softmax')(x)
    model = Model(inputs=inputs1, outputs=outputs)
    # model.summary()  # 打印模型结构
    return model

模型比较简单,大家可以根据图里的结构自己查看和调整

 2.AdaBN算法原理及实现

复现WDCNN其实没啥难度,但是AdaBN还是很有说头的。简单来讲,这是BN的一个变种,首先还得对BN的机理多一点了解。我以前只管用,毕竟放到现在已经是一个常规配置项了,不理解一般也不影响使用,但是要用AdaBN的话就不能一知半解了。

大家应该都知道BN实际上就是对隐藏层的参数做批量归一化,而归一化就要用到训练集的数据分布信息,均值和方差。模型中BN模块是个特殊的存在,它不参与反向传播,查看模型时,你会发现它是不可训练的。但不可训练并不意味着不进行变化,在训练阶段它依据每一组batch的相关参数进行调整,之所以不用整个训练集的均值和方差是为了优化模型的适应能力,也可以理解为泛化能力或鲁棒性。

以上过程是model.fit过程中发生的,但是在model.evaluate中就不用了。这时大家一般用测试集来获得准确率,这里的BN用的则是之前fit过程中得到的训练集相关的全局均值和方差

如果训练集和测试集属于同一工况,或者同分布的数据集,那么这样就很合适。但是当我们做迁移学习时就不一样了,我们当然希望用测试集的均值和方差来进行model.evaluate,毕竟测试集的数据信息是我们已有的信息,这种方法就是AdaBN。

因此,整个AdaBN过程分3步实现。

1.使用训练集进行model.fit。这一步和常规训练一样,但是绝对不能把测试集当验证集进行,这是常识性错误。就像下面这样的,结果肯定准确率能提高,毕竟相当于偷看了答案。

model.fit(X_train, Y_train,validation_data=(X_test, Y_test),epochs=30,batch_size=64)

正确的应该是这样,必须使用验证集。这里我加入了早停机制、模拟褪火和保存最佳模型模块,确保模型能够有效收敛。

model.fit(trainX, trainy, epochs=epochs, batch_size=64, verbose=0, validation_data=(valX, valy),
              callbacks=[earlystopper, checkpointer,lr_reducer])

2.再次进行model.fit。这一步是最关键的,上一步我们相当于进行了正向传播和反向传播,并且保存了最佳模型的参数。这次fit中我们需要使用训练集进行正向传播,确保BN中的参数更新为训练集相关的这里如果使用pytorch的话据说非常简单,直接将BN层track_running_stats=True参数,把它改成False,这样在model.eval()时就是用目标域样本的均值和方差。但是tensorflow中我没有找到类似的,也是我个人学的比较浅。这里我使用另外一种方法代替,首先锁定所有模型参数,只允许BN层的参数进行训练,因为BN的机制本身就不参与反向更新,因此训练完成后相当于将目标域测试集的参数保留在了BN中。此时再次保存模型参数,相当于上一步中非BN层的参数+本步骤中BN层的参数组成的一个新的模型参数。

model.load_weights(path)    #载入模型参数    
model.trainable = False    #锁定所有层参数
    for i in [2, 6, 10, 14, 16, 20]:    #只允许特定层更新
        model.layers[i].trainable = True

这一步使用model.fit时需要训练集和标签信息,此时训练集就是我们目标域的测试集,标签信息从原理上来讲可以随意设置,因为除了BN所有参数都被锁定了,不会变化,而BN只受此时的训练数据影响

# np.random.shuffle(valy)

 label_te = np.array([1 for i in range(0, 1400)])
 label_te = label_te.reshape([1400, 1])
 label_te = label_te.reshape(label_te.shape[0], 1)
 label_te = label_te.astype(int)
 label_te = case10.to_one_hot(label_te)

 model.fit(testX, label_te, epochs=epochs, batch_size=64, verbose=0,
              callbacks=[lr_reducer, earlystopper2, checkpointer2])

为了验证理论的正确,这一步中我用了随机标签和类别都是1的标签,咱们看一下结果如何。进行5次后取平均值

WDCNN Accuracy: 92.764% (+/-1.967)
WDCNN_ada Accuracy: 96.202% (+/-1.447)

 可见效果确实非常不错,提升很明显,和论文中结果接近。

这个方法的好处就是适用性比较强,和很多使用BN的模型都适配,在我的ShuffleNet模型上效果更好,稳定性也更好。

shu Accuracy: 96.148% (+/-0.896)
shu_ada Accuracy: 98.129% (+/-0.445)

3.TICNN的复现

我还顺便试了一下TICNN的一部分,实际上这两个模型很接近,TICNN主要就是比WDCNN多了dropout模块,但是我个人测试中发现效果和原作者有出入。这里可能还涉及到原论文中的一点错误,我记录下来供大家参考。首先我们看模型结构

 但是作者上文中却有明显提到第一个卷积层的步长改成了8,我估计是作者在做图时的疏忽。下面是原文

 但是有意思的是很多人在复现时步长用的还是16,估计是没有好好看论文吧。

TICNN结合AdaBN的效果差一些,只提升1-2%,我个人估计是dropout的原因,因为它会随机丢弃一些参数,导致模型数据的一些不稳定。

就写到这里了,欢迎大家批评指正+点赞收藏!感谢!

  • 11
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
WDCNN(Wide and Deep Convolutional Neural Network)是一种经典的深度学习模型,它结合了卷积神经网络CNN)的广度和深度学习的思想,在多个领域都取得了良好的表现。下面是使用PyTorch复现WDCNN模型的步骤: 1. 数据准备:从数据集获取需要训练和测试的数据,并进行预处理。预处理包括数据的归一化、划分训练集和测试集等。 2. 模型搭建:使用PyTorch搭建WDCNN模型。首先定义卷积层和池化层,然后定义全连接层。可以根据具体需求选择不同的卷积神经网络结构,也可以自定义网络结构。 3. 模型训练:使用定义好的模型对训练集进行训练。可以使用随机梯度下降(SGD)等优化算法,选择合适的损失函数计算损失,并通过反向传播算法更新模型的参数。 4. 模型评估:使用训练好的模型对测试集进行预测,计算预测准确率等评价指标。可以使用混淆矩阵、准确率、召回率等指标评估模型性能。 5. 超参数调优:根据模型的评估结果,调整超参数,如学习率、batch size等,以提高模型的性能。 6. 模型保存和加载:将训练好的模型保存到本地文件,以便后续的使用和部署。可以使用PyTorch提供的模型保存和加载功能。 通过以上步骤,可以使用PyTorch复现WDCNN模型。在实际应用,根据具体任务的需求,可以对模型结构进行修改和优化,例如添加正则化、dropout层等,以提高模型的泛化能力和鲁棒性。同时,可以通过增加训练数据集的规模、使用数据增强等方法来进一步改善模型性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北漂炼丹青年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值