【代码复现(吐槽向)】Revisiting a Methodology for Efficient CNN Architectures in Profiling Attacks

【论文写不出来,痛苦中】

这篇文章是我看到框架最简单,效果最好的对于公开数据集的攻击没有之一。

代码:KULeuven-COSIC/TCHES20V3_CNN_SCA (github.com)

代码很简单,很好复现,就是要注意环境问题。

吐槽:

1坑:TF的版本问题,有了torch,谁用TF,但是偏偏GITHUB上所有的SCA的代码都是TF写的,还有丧心病狂TF1.x,版本安装几十年,不如选一个服务器(🤮没有显卡太惨了)

2坑:想要深度学习的新框架,那当然的用torch,于是学了torch然后把这篇文章的代码转换为torch试一试了啊!!那么问题来了,ASCAD100的CNN模型在tf上效果很好,但是改成torch后!他的rank居然不收敛!!!谁懂啊!!!其他数据集都还行!!就一个数据集有问题!!rank从200多直接变成了不收敛!!!我真是服了!!!TF和torch的默认设置差太多了!!初始化设置烦死了!!!!!我做不出来!!!

谁能告诉我怎么回事!!!

我就当成世界未解之谜吧,我累了

def noConv1_ascad_desync_100(input_size=700, learning_rate=0.00001, classes=256):
    trace_input = Input(shape=(input_size, 1))
    x = AveragePooling1D(2, strides=2, name='initial_pool')(trace_input)

    x = Conv1D(64, 50, kernel_initializer='he_uniform', activation='selu', padding='same', name='block1_conv')(x)
    x = BatchNormalization()(x)
    x = AveragePooling1D(50, strides=50, name='block2_pool')(x)

    x = Conv1D(128, 3, kernel_initializer='he_uniform', activation='selu', padding='same', name='block2_conv')(x)
    x = BatchNormalization()(x)
    x = AveragePooling1D(2, strides=2, name='block3_pool')(x)

    x = Flatten(name='flatten')(x)

    x = Dense(20, kernel_initializer='he_uniform', activation='selu', name='fc1')(x)
    x = Dense(20, kernel_initializer='he_uniform', activation='selu', name='fc2')(x)
    x = Dense(20, kernel_initializer='he_uniform', activation='selu', name='fc3')(x)
    x = Dense(classes, activation='softmax', name='predictions')(x)

    model = Model(trace_input, x, name='noConv1_ascad_desync_100')
    optimizer = Adam(lr=learning_rate)
    model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
    return model

变成torch

class NoConv1ASCADDesync100(nn.Module):
    def __init__(self, input_size=700, classes=256):
        super(NoConv1ASCADDesync100, self).__init__()

        self.initial_pool = nn.AvgPool1d(2, stride=2)

        self.block1_conv = nn.Conv1d(1, 64, kernel_size=50, stride=1, padding=(50 // 2))
        self.block1_bn = nn.BatchNorm1d(64)
        self.block1_act = nn.SELU()

        self.block2_pool = nn.AvgPool1d(50, stride=50)

        self.block2_conv = nn.Conv1d(64, 128, kernel_size=3, stride=1, padding=(3 // 2))
        self.block2_bn = nn.BatchNorm1d(128)
        self.block2_act = nn.SELU()

        self.block3_pool = nn.AvgPool1d(2, stride=2)

        self.flatten = nn.Flatten()

        self.fc1 = nn.Linear(384, 20)
        self.fc1_act = nn.SELU()
        self.fc2 = nn.Linear(20, 20)
        self.fc2_act = nn.SELU()
        self.fc3 = nn.Linear(20, 20)
        self.fc3_act = nn.SELU()
        self.predictions = nn.Linear(20, classes)

        self.init_weights()

    def forward(self, x):
        x = self.initial_pool(x)

        x = self.block1_conv(x)
        x = self.block1_bn(x)
        x = self.block1_act(x)
        x = self.block2_pool(x)

        x = self.block2_conv(x)
        x = self.block2_bn(x)
        x = self.block2_act(x)
        x = self.block3_pool(x)

        x = self.flatten(x)

        x = self.fc1(x)
        x = self.fc1_act(x)
        x = self.fc2(x)
        x = self.fc2_act(x)
        x = self.fc3(x)
        x = self.fc3_act(x)
        x = self.predictions(x)

        return x

    def init_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv1d) or isinstance(m, nn.Linear):
                nn.init.kaiming_uniform_(m.weight, mode='fan_in', nonlinearity='selu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm1d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

定义的train

    # 定义损失函数和优化器
    loss_function = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=0.005, weight_decay=0.001)
    scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.001, total_steps=train_steps * epochs)

    # 训练模型
    best_acc = 0
    for epoch in range(epochs):
        model.train()
        running_loss = 0.0
        correct1 = 0.0
        train_loss = 0.0
        train_bar = tqdm(train_loader, file=sys.stdout)
        for step, (traces, labels) in enumerate(train_bar):
            # 数据移动到 GPU 上
            tra_traces, tra_labels = traces.to(device), labels.to(device)
            # 梯度清零
            optimizer.zero_grad()
            # 将输入数据传入模型进行前向传播
            outputs = model(tra_traces)
            # 计算损失
            loss = loss_function(outputs, tra_labels)
            # 反向传播和优化
            loss.backward()
            optimizer.step()
            scheduler.step()
            # 计算预测值
            _, predicted = torch.max(outputs.data, 1)
            # 统计正确的预测次数
            correct1 += torch.eq(predicted, tra_labels).sum().item()
            running_loss += loss.item()

        # 计算准确率和平均损失
        train_acc = correct1 / len(train_loader.dataset) * 100  # len(train_loader.dataset) 样本总数
        train_loss = running_loss / len(train_loader)  # len(train_loader)         迭代次数

定义的test

    model.eval()
    predictions = []
    correct3 = 0.0
    with torch.no_grad():
        test_bar = tqdm(test_loader, file=sys.stdout)
        for (test_images, test_labels) in test_bar:
            text_trace, text_labels = test_images.to(device), test_labels.to(device)
            outputs = model(text_trace)

            outputs = F.softmax(outputs, dim=1)

            prediction = np.log(outputs.cpu().numpy() + 1e-40)
            predictions.append(prediction)

            _, predict_y = torch.max(outputs.data, 1)
            correct3 += torch.eq(predict_y, text_labels).sum().item()

        predictions = np.concatenate(predictions, axis=0)

 

posted @ 2024-01-14 14:17  学习记录本  阅读(164)  评论(0)    收藏  举报