卷积神经网络认证训练:防御卷积扰动的PyTorch实战指南
在深度学习模型的安全性和鲁棒性研究领域对抗性攻击一直是开发者面临的重要挑战。最近在ICLR 2024会议上提出的Certified Training for Convolutional Perturbations方法为卷积神经网络提供了一种全新的认证训练框架能够有效防御各种卷积扰动攻击。本文将深入解析这一技术的核心原理并提供完整的PyTorch实现方案帮助开发者从理论到实践全面掌握这一前沿技术。1. 卷积扰动攻击的背景与挑战1.1 什么是卷积扰动攻击卷积扰动攻击是一种新型的对抗性攻击方式与传统像素级扰动不同它通过在输入图像上应用卷积核来生成扰动。这种攻击方式更加符合现实世界中的图像退化情况如运动模糊、镜头失焦等自然现象因此具有更强的实际威胁性。卷积扰动的数学表达式为import torch import torch.nn as nn def apply_convolutional_perturbation(x, kernel): 应用卷积扰动到输入图像 Args: x: 输入图像张量 [batch, channels, height, width] kernel: 卷积核 [out_channels, in_channels, kernel_size, kernel_size] Returns: 扰动后的图像 # 确保卷积核与输入通道数匹配 if kernel.size(1) ! x.size(1): kernel kernel.repeat(1, x.size(1)//kernel.size(1), 1, 1) # 应用卷积操作 perturbed_x nn.functional.conv2d(x, kernel, paddingkernel.size(-1)//2) return perturbed_x1.2 传统防御方法的局限性传统的对抗训练方法主要针对像素级的Lp范数有界扰动如FGSM、PGD等攻击。然而这些方法在面对卷积扰动时往往效果有限因为卷积扰动改变了图像的整体结构特征而不仅仅是局部像素值。主要局限性包括无法有效建模卷积操作的全局影响认证保证仅限于特定类型的扰动计算复杂度随扰动空间维度指数增长2. Certified Training的核心原理2.1 认证训练的基本概念认证训练的目标是为神经网络提供可证明的鲁棒性保证即在特定的扰动范围内模型对任何扰动都能保持正确的预测结果。对于卷积扰动认证训练需要确保模型对任何满足约束条件的卷积核扰动都具有鲁棒性。2.2 卷积扰动的数学建模卷积扰动可以表示为对输入图像的线性变换。设原始图像为x∈R^(H×W×C)卷积核为k∈R^(k×k)则扰动后的图像为x x ∗ k其中∗表示卷积操作。认证训练的关键在于约束卷积核的可行空间class ConvolutionalPerturbationSet: def __init__(self, kernel_size, norm_bound, input_size): self.kernel_size kernel_size self.norm_bound norm_bound # 卷积核的范数约束 self.input_size input_size def sample_valid_kernels(self, batch_size): 采样满足约束的卷积核 kernels torch.randn(batch_size, 1, self.kernel_size, self.kernel_size) # 归一化到满足范数约束 kernel_norms torch.norm(kernels.view(batch_size, -1), dim1) scale self.norm_bound / torch.clamp(kernel_norms, min1e-8) kernels kernels * scale.view(-1, 1, 1, 1) return kernels2.3 认证鲁棒性的形式化定义对于分类任务认证鲁棒性要求对于所有满足约束的卷积扰动模型的预测结果保持一致∀k ∈ K: argmax f(x ∗ k) argmax f(x)其中K表示满足约束的卷积核集合f为分类模型。3. 环境准备与依赖配置3.1 硬件和软件要求实现认证训练需要适当的计算资源建议配置GPU: NVIDIA GPU with ≥8GB VRAMRAM: ≥16GBPython: 3.8PyTorch: 1.93.2 依赖库安装pip install torch1.9.0 pip install torchvision0.10.0 pip install numpy1.21.0 pip install matplotlib3.5.0 pip install tqdm4.62.03.3 项目结构规划certified_conv_training/ ├── src/ │ ├── models/ # 模型定义 │ ├── perturbations/ # 扰动生成 │ ├── training/ # 训练逻辑 │ └── certification/ # 认证计算 ├── configs/ # 配置文件 ├── data/ # 数据集 └── scripts/ # 训练脚本4. 认证训练算法实现4.1 核心算法框架认证训练的核心思想是在训练过程中考虑最坏情况下的扰动从而提升模型的鲁棒性。算法流程如下import torch import torch.nn as nn from torch.utils.data import DataLoader class CertifiedConvTrainer: def __init__(self, model, perturbation_set, optimizer, criterion): self.model model self.perturbation_set perturbation_set self.optimizer optimizer self.criterion criterion def compute_certified_loss(self, x, y): 计算认证损失 batch_size x.size(0) # 采样多个卷积核 kernels self.perturbation_set.sample_valid_kernels(batch_size) # 应用扰动并计算最坏情况损失 worst_case_loss 0 for i in range(kernels.size(0)): perturbed_x apply_convolutional_perturbation(x, kernels[i:i1]) outputs self.model(perturbed_x) loss self.criterion(outputs, y) worst_case_loss torch.max(worst_case_loss, loss) return worst_case_loss def train_epoch(self, dataloader): 训练一个epoch self.model.train() total_loss 0 for batch_idx, (data, target) in enumerate(dataloader): data, target data.cuda(), target.cuda() self.optimizer.zero_grad() loss self.compute_certified_loss(data, target) loss.backward() self.optimizer.step() total_loss loss.item() if batch_idx % 100 0: print(fBatch {batch_idx}, Loss: {loss.item():.6f}) return total_loss / len(dataloader)4.2 高效的扰动采样策略为了降低计算复杂度需要设计高效的采样策略class EfficientPerturbationSampler: def __init__(self, kernel_size, num_samples, norm_bound): self.kernel_size kernel_size self.num_samples num_samples self.norm_bound norm_bound def generate_orthogonal_basis(self): 生成正交基向量用于高效采样 # 使用随机正交矩阵构建基向量 basis torch.randn(self.num_samples, self.kernel_size * self.kernel_size) q, r torch.linalg.qr(basis) # QR分解得到正交基 return q * self.norm_bound def sample_on_sphere(self, center, radius): 在球面上均匀采样 # 使用高斯分布归一化得到球面均匀分布 samples torch.randn(self.num_samples, self.kernel_size * self.kernel_size) samples samples / torch.norm(samples, dim1, keepdimTrue) return center radius * samples5. 模型架构设计与优化5.1 鲁棒性增强的CNN架构针对卷积扰动特性需要设计特殊的网络架构class RobustCNN(nn.Module): def __init__(self, num_classes10): super(RobustCNN, self).__init__() # 使用更大的卷积核增强空间不变性 self.conv1 nn.Conv2d(3, 64, kernel_size7, stride2, padding3) self.bn1 nn.BatchNorm2d(64) # 残差连接增强梯度流动 self.resblock1 ResidualBlock(64, 128) self.resblock2 ResidualBlock(128, 256) # 全局平均池化替代全连接层 self.global_avg_pool nn.AdaptiveAvgPool2d((1, 1)) self.fc nn.Linear(256, num_classes) # 激活函数选择 self.activation nn.ReLU(inplaceTrue) def forward(self, x): x self.activation(self.bn1(self.conv1(x))) x self.resblock1(x) x self.resblock2(x) x self.global_avg_pool(x) x x.view(x.size(0), -1) x self.fc(x) return x class ResidualBlock(nn.Module): def __init__(self, in_channels, out_channels): super(ResidualBlock, self).__init__() self.conv1 nn.Conv2d(in_channels, out_channels, 3, padding1) self.bn1 nn.BatchNorm2d(out_channels) self.conv2 nn.Conv2d(out_channels, out_channels, 3, padding1) self.bn2 nn.BatchNorm2d(out_channels) self.activation nn.ReLU(inplaceTrue) # shortcut连接 if in_channels ! out_channels: self.shortcut nn.Conv2d(in_channels, out_channels, 1) else: self.shortcut nn.Identity() def forward(self, x): residual self.shortcut(x) out self.activation(self.bn1(self.conv1(x))) out self.bn2(self.conv2(out)) out residual return self.activation(out)5.2 训练策略优化class AdaptiveTrainingScheduler: def __init__(self, initial_norm_bound, final_norm_bound, total_epochs): self.initial_norm_bound initial_norm_bound self.final_norm_bound final_norm_bound self.total_epochs total_epochs def get_norm_bound(self, epoch): 随着训练进度调整扰动范数边界 progress epoch / self.total_epochs # 线性衰减策略 current_bound self.initial_norm_bound - progress * ( self.initial_norm_bound - self.final_norm_bound) return max(current_bound, self.final_norm_bound)6. 完整训练流程实现6.1 数据预处理与加载import torchvision import torchvision.transforms as transforms def get_cifar10_dataloaders(batch_size128): 获取CIFAR-10数据加载器 transform_train transforms.Compose([ transforms.RandomCrop(32, padding4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) transform_test transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) trainset torchvision.datasets.CIFAR10( root./data, trainTrue, downloadTrue, transformtransform_train) trainloader DataLoader(trainset, batch_sizebatch_size, shuffleTrue, num_workers4) testset torchvision.datasets.CIFAR10( root./data, trainFalse, downloadTrue, transformtransform_test) testloader DataLoader(testset, batch_sizebatch_size, shuffleFalse, num_workers4) return trainloader, testloader6.2 主训练循环def main_training_loop(): # 初始化配置 device torch.device(cuda if torch.cuda.is_available() else cpu) batch_size 128 epochs 200 initial_norm_bound 2.0 final_norm_bound 0.5 # 准备数据 train_loader, test_loader get_cifar10_dataloaders(batch_size) # 初始化模型和优化器 model RobustCNN(num_classes10).to(device) optimizer torch.optim.SGD(model.parameters(), lr0.1, momentum0.9, weight_decay5e-4) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_maxepochs) criterion nn.CrossEntropyLoss() # 初始化训练器 norm_scheduler AdaptiveTrainingScheduler(initial_norm_bound, final_norm_bound, epochs) # 训练循环 for epoch in range(epochs): current_norm_bound norm_scheduler.get_norm_bound(epoch) perturbation_set ConvolutionalPerturbationSet( kernel_size5, norm_boundcurrent_norm_bound, input_size32) trainer CertifiedConvTrainer(model, perturbation_set, optimizer, criterion) # 训练一个epoch train_loss trainer.train_epoch(train_loader) # 评估模型 test_acc evaluate_model(model, test_loader, device) # 调整学习率 scheduler.step() print(fEpoch {epoch1}/{epochs}, Loss: {train_loss:.4f}, Test Acc: {test_acc:.2f}%) # 保存最佳模型 if test_acc best_acc: torch.save(model.state_dict(), best_model.pth) best_acc test_acc def evaluate_model(model, test_loader, device): 评估模型性能 model.eval() correct 0 total 0 with torch.no_grad(): for data, target in test_loader: data, target data.to(device), target.to(device) outputs model(data) _, predicted torch.max(outputs.data, 1) total target.size(0) correct (predicted target).sum().item() return 100 * correct / total7. 认证鲁棒性评估7.1 认证准确率计算认证准确率是指在最坏扰动下模型仍能保持正确预测的比例def compute_certified_accuracy(model, test_loader, perturbation_set, device): 计算认证准确率 model.eval() certified_correct 0 total 0 for data, target in test_loader: data, target data.to(device), target.to(device) batch_size data.size(0) # 对每个样本测试多个扰动 for i in range(batch_size): sample data[i:i1] label target[i:i1] # 生成多个扰动版本 kernels perturbation_set.sample_valid_kernels(100) all_correct True for j in range(kernels.size(0)): perturbed_sample apply_convolutional_perturbation(sample, kernels[j:j1]) output model(perturbed_sample) pred output.argmax(dim1) if pred ! label: all_correct False break if all_correct: certified_correct 1 total 1 return 100 * certified_correct / total7.2 可视化分析工具import matplotlib.pyplot as plt import numpy as np def visualize_perturbation_effects(original_img, perturbed_imgs, kernels): 可视化扰动效果 fig, axes plt.subplots(2, 5, figsize(15, 6)) # 显示原始图像 axes[0, 0].imshow(original_img.permute(1, 2, 0).cpu().numpy()) axes[0, 0].set_title(Original Image) axes[0, 0].axis(off) # 显示扰动后的图像 for i in range(4): axes[0, i1].imshow(perturbed_imgs[i].permute(1, 2, 0).cpu().numpy()) axes[0, i1].set_title(fPerturbed {i1}) axes[0, i1].axis(off) # 显示使用的卷积核 for i in range(5): kernel_vis kernels[i].squeeze().cpu().numpy() axes[1, i].imshow(kernel_vis, cmapcoolwarm) axes[1, i].set_title(fKernel {i1}) axes[1, i].axis(off) plt.tight_layout() plt.show()8. 实际应用与性能优化8.1 大规模数据集上的扩展当处理更大规模的数据集如ImageNet时需要考虑计算效率的优化class DistributedCertifiedTraining: def __init__(self, model, perturbation_set, num_gpus4): self.model model self.perturbation_set perturbation_set self.num_gpus num_gpus def parallel_perturbation_computation(self, x): 并行计算多个扰动版本 batch_size x.size(0) # 将批次数据分配到多个GPU x_split torch.chunk(x, self.num_gpus, dim0) results [] for i, x_part in enumerate(x_split): device fcuda:{i} x_part x_part.to(device) model_part self.model.to(device) # 在每个GPU上计算扰动损失 kernels self.perturbation_set.sample_valid_kernels(x_part.size(0)) perturbed_x apply_convolutional_perturbation(x_part, kernels) outputs model_part(perturbed_x) results.append(outputs.to(cuda:0)) return torch.cat(results, dim0)8.2 内存优化技巧class MemoryEfficientCertification: def __init__(self, model, gradient_checkpointingTrue): self.model model self.gradient_checkpointing gradient_checkpointing def compute_loss_with_checkpointing(self, x, y, kernels): 使用梯度检查点减少内存使用 def create_custom_forward(module): def custom_forward(*inputs): return module(*inputs) return custom_forward total_loss 0 for i in range(kernels.size(0)): perturbed_x apply_convolutional_perturbation(x, kernels[i:i1]) if self.gradient_checkpointing: # 使用梯度检查点 outputs torch.utils.checkpoint.checkpoint( create_custom_forward(self.model), perturbed_x) else: outputs self.model(perturbed_x) loss nn.functional.cross_entropy(outputs, y) total_loss loss return total_loss / kernels.size(0)9. 常见问题与解决方案9.1 训练不收敛问题问题现象损失函数震荡或持续上升准确率不提升。可能原因扰动范数边界设置过大学习率设置不合理模型容量不足解决方案def adaptive_hyperparameter_tuning(): 自适应超参数调整策略 # 动态调整学习率 optimizer torch.optim.SGD(model.parameters(), lr0.1) scheduler torch.optim.lr_scheduler.ReduceLROnPlateau( optimizer, modemin, patience5, factor0.5) # 渐进式增加扰动强度 def get_adaptive_norm_bound(epoch, max_epochs): if epoch max_epochs * 0.3: return 0.5 # 初始阶段使用较小扰动 elif epoch max_epochs * 0.6: return 1.0 # 中期适度增加 else: return 2.0 # 后期使用完整扰动9.2 认证准确率过低问题现象标准准确率尚可但认证准确率显著下降。可能原因扰动空间采样不足模型架构不适合认证训练训练时间不足优化策略增加扰动采样数量使用更鲁棒的模型架构延长训练时间并配合适当的数据增强10. 生产环境最佳实践10.1 模型部署考虑在将认证训练模型部署到生产环境时需要注意class ProductionCertifiedModel: def __init__(self, model_path, perturbation_constraints): self.model torch.load(model_path) self.model.eval() self.perturbation_constraints perturbation_constraints def predict_with_certification(self, x, num_samples1000): 带认证保证的预测 predictions [] certifications [] with torch.no_grad(): for i in range(x.size(0)): sample x[i:i1] original_pred self.model(sample).argmax() # 测试多个扰动 kernels self.sample_valid_kernels(num_samples) certified True for kernel in kernels: perturbed apply_convolutional_perturbation(sample, kernel.unsqueeze(0)) perturbed_pred self.model(perturbed).argmax() if perturbed_pred ! original_pred: certified False break predictions.append(original_pred.item()) certifications.append(certified) return predictions, certifications10.2 监控与维护建立完整的监控体系定期评估模型在最新攻击下的表现监控认证准确率的变化趋势建立模型更新和回滚机制认证训练为卷积神经网络提供了可证明的安全保证特别是在面对现实世界的图像退化问题时表现出色。通过本文的完整实现方案开发者可以快速将这一前沿技术应用到实际项目中提升模型的鲁棒性和可靠性。

相关新闻

AI生成内容检测:三维度定向爆破技术解析

AI生成内容检测:三维度定向爆破技术解析

1. 项目概述:当AI生成内容遇上定向爆破 最近在内容安全审核领域,一个叫"三维度定向爆破降AI"的技术方案突然火了。这本质上是一套针对AI生成内容的检测与干预系统,通过句法、语义、逻辑三个维度的联合分析,实现对机器生…

2026/7/24 15:03:24阅读更多 →
TI ADS7851EVM-PDK评估套件:同步采样ADC性能验证与设计实战

TI ADS7851EVM-PDK评估套件:同步采样ADC性能验证与设计实战

1. 项目概述与核心价值 在嵌入式系统、工业自动化或者精密仪器设计领域,我们常常会遇到一个核心挑战:如何精准、同步地捕获来自多个传感器的模拟信号,并将其转换为可供处理器分析的数字数据。无论是三相电机的电流电压监控、多通道振动分析&a…

2026/7/24 15:03:24阅读更多 →
TPS65981 USB-C PD控制器在扩展坞中的电源管理与PCB设计实战

TPS65981 USB-C PD控制器在扩展坞中的电源管理与PCB设计实战

1. 项目概述与核心价值 如果你最近在折腾一个基于USB Type-C接口的扩展坞或者显示器项目,尤其是那种需要同时给笔记本充电、传输视频信号,还要挂载一堆USB外设的“全能型”设备,那你大概率绕不开一个核心问题:电源管理。USB Type-…

2026/7/24 15:03:24阅读更多 →
【Linux】用户管理和配置免密登陆

【Linux】用户管理和配置免密登陆

【Linux】用户管理和配置免密登陆【一】用户管理【1】新增用户(1)检查用户是否存在(2)如果用户不存在,创建用户(3)设置密码(修改密码)【3】删除用户【4】权限管理&#x…

2026/7/24 22:30:56阅读更多 →
剑网三终极智能助手:5分钟快速配置的完整游戏伴侣方案

剑网三终极智能助手:5分钟快速配置的完整游戏伴侣方案

剑网三终极智能助手:5分钟快速配置的完整游戏伴侣方案 【免费下载链接】mini_jx3_bot 女生自用剑网三机器人 项目地址: https://gitcode.com/gh_mirrors/mi/mini_jx3_bot 在剑网三的武侠世界中,每日繁琐的任务查询、装备属性分析和金价波动监控是…

2026/7/24 22:30:56阅读更多 →
实战教程:SpringBoot3+Vue3实现JWT认证与动态路由管理

实战教程:SpringBoot3+Vue3实现JWT认证与动态路由管理

项目介绍 基于SpringBoot3、SpringSecurity、MybatisPlus、Vue3、TypeScript、Vite、ElementPlus、MySQL等技术栈实现的单体前后端分离后台管理系统;后端基于Java语言采用SpringBoot3、SpringSecurity、MybatisPlus、MySQL等主流技术栈,前端基于Vue3、T…

2026/7/24 22:30:56阅读更多 →
杰理之2dp解码 叠加IIS IN 输入音频【篇】

杰理之2dp解码 叠加IIS IN 输入音频【篇】

同时以 IIS out 输出

2026/7/24 22:30:56阅读更多 →
NoSleep防休眠工具:告别Windows自动休眠的智能解决方案

NoSleep防休眠工具:告别Windows自动休眠的智能解决方案

NoSleep防休眠工具:告别Windows自动休眠的智能解决方案 【免费下载链接】NoSleep Lightweight Windows utility to prevent screen locking 项目地址: https://gitcode.com/gh_mirrors/nos/NoSleep 你是否经历过这些令人沮丧的时刻?😫…

2026/7/24 22:30:56阅读更多 →
让你的桌面活起来:呆啵宠物DyberPet打造个性化AI陪伴体验

让你的桌面活起来:呆啵宠物DyberPet打造个性化AI陪伴体验

让你的桌面活起来:呆啵宠物DyberPet打造个性化AI陪伴体验 【免费下载链接】DyberPet Desktop Cyber Pet Framework based on PySide6 项目地址: https://gitcode.com/GitHub_Trending/dy/DyberPet 你是否曾梦想过让你喜爱的动漫角色、游戏伙伴或原创角色真正…

2026/7/24 22:28:56阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 0:58:53阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 0:58:53阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 0:58:53阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:06阅读更多 →
【LeetCode 54】螺旋矩阵

【LeetCode 54】螺旋矩阵

问题描述: 解法: 1、模拟(参考自【LeetCode 54】螺旋矩阵-CSDN博客) int *spiralOrder(int **matrix, int matrixSize, int *matrixColSize, int *returnSize) {static const int dirs[4][2] {{0, 1}, {1, 0}, {0, -1}, {-1, …

2026/7/24 0:00:06阅读更多 →
2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

知春路不相信模型领先今年WAIC大会,昔日AI六小龙来了五家,分别是Kimi、阶跃星辰、Minimax、百川智能、零一万物。连放弃基模的百川和零一万物都来了,唯一缺席的竟是近几个月来风光无限的智谱。(DeepSeek一直不参加)WAI…

2026/7/24 0:00:06阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/23 22:58:43阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/24 19:00:40阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/24 19:00:40阅读更多 →