
PyTorch框架隧道裂缝识别 隧道结构健康监测、基础设施自动化巡检、AI辅助土木工程评估 UNET模型如何训练隧道裂缝分割数据集111**隧道裂缝图像数据集 含约1000张256×256像素的隧道裂缝图像附带对应的像素级标签。标签有三种格式裂缝为1像素背景为0像素裂缝为255像素背景为0像素裂缝为0像素背景为255像素【模型支持】适用于FCN、U-Net、SegNet、DeepLab、SegFormer等深度学习语义分割模型。**以下是隧道裂缝图像数据集的详细表格化描述 一、数据集总体信息项目描述数据集名称隧道裂缝语义分割数据集Tunnel Crack Segmentation Dataset任务类型像素级语义分割Binary Semantic Segmentation图像总数约 1,000 张图像尺寸256 × 256 像素统一尺寸便于批量训练图像格式.png或.jpg通常为灰度或RGB标签类型像素级二值掩膜Binary Mask适用模型FCN、U-Net、SegNet、DeepLabv3、SegFormer、PSPNet 等主流语义分割架构应用场景隧道结构健康监测、基础设施自动化巡检、AI辅助土木工程评估️ 二、标签格式说明三种可选格式编号裂缝像素值背景像素值说明格式 110适用于 PyTorch 默认的LongTensor 类别标签类别 ID0背景1裂缝格式 22550兼容 OpenCV / PIL 可视化标准白色裂缝黑色背景常用于传统图像处理流程格式 30255“反色”格式黑色裂缝白色背景部分旧系统使用需注意转换使用建议若用于深度学习训练如 PyTorch/TensorFlow推荐统一转换为格式 10/1若用于可视化或与 OpenCV 工具链集成可保留格式 20/255。 三、典型数据组织结构【博主建议】tunnel_crack_dataset/ ├── images/# 原始图像1000张│ ├── img_0001.png │ ├── img_0002.png │ └──... └── masks/# 对应掩膜三种格式之一或提供多版本子目录├── mask_0001.png ├── mask_0002.png └──...⚙️ 四、预处理与训练适配建议框架/模型推荐标签格式注意事项PyTorch (U-Net等)格式 10/1损失函数用CrossEntropyLoss或BCEWithLogitsLossTensorFlow/Keras格式 1 或 格式 2归一化后若用sigmoid输出标签需为 0/1若用softmax需 one-hotOpenCV 可视化格式 20/255直接cv2.imshow()显示清晰裂缝LabelMe / 数据标注工具导出可能为格式 2 或 3需脚本统一标准化该数据集结构规范、尺寸统一、标注明确是开展基础设施智能检测研究和工业级裂缝识别系统开发的理想基准数据集。基于U-Net模型对隧道裂缝图像数据集进行训练的详细代码示例。假设你已经按照上述结构组织好了数据集并选择了标签格式1裂缝为1像素背景为0像素适用于PyTorch框架。 一、推荐项目结构tunnel_crack_unet/ ├── dataset.py# 数据集加载与预处理├── train.py# 主训练脚本├── model.py# U-Net模型定义├── predict_demo.py# 推理演示└── data/ ├── images/# 原始图像1000张└── masks/# 对应掩膜裂缝为1像素背景为0像素 二、数据集加载与预处理dataset.py# dataset.pyimportosfromtorch.utils.dataimportDataset,DataLoaderfromPILimportImageimportnumpyasnpimporttorchvision.transformsastransformsclassCrackSegmentationDataset(Dataset):def__init__(self,image_dir,mask_dir,transformNone):self.image_pathssorted([os.path.join(image_dir,img)forimginos.listdir(image_dir)])self.mask_pathssorted([os.path.join(mask_dir,mask)formaskinos.listdir(mask_dir)])assertlen(self.image_paths)len(self.mask_paths),Mismatched number of images and masksself.transformtransformdef__len__(self):returnlen(self.image_paths)def__getitem__(self,idx):image_pathself.image_paths[idx]mask_pathself.mask_paths[idx]imageImage.open(image_path).convert(RGB)maskImage.open(mask_path).convert(L)ifself.transform:imageself.transform(image)masktransforms.ToTensor()(mask)# 裂缝为1像素背景为0像素return{image:image,mask:mask}defget_loader(image_dir,mask_dir,batch_size8,num_workers4):transformtransforms.Compose([transforms.Resize((256,256)),# 统一尺寸transforms.ToTensor(),])datasetCrackSegmentationDataset(image_dir,mask_dir,transformtransform)loaderDataLoader(dataset,batch_sizebatch_size,shuffleTrue,num_workersnum_workers)returnloader 三、U-Net模型定义model.py# model.pyimporttorchimporttorch.nnasnnclassUNet(nn.Module):def__init__(self,in_channels3,out_channels1):super(UNet,self).__init__()defconv_block(in_channels,out_channels):returnnn.Sequential(nn.Conv2d(in_channels,out_channels,kernel_size3,padding1),nn.ReLU(inplaceTrue),nn.Conv2d(out_channels,out_channels,kernel_size3,padding1),nn.ReLU(inplaceTrue))# Encoderself.enc1conv_block(in_channels,64)self.pool1nn.MaxPool2d(kernel_size2,stride2)self.enc2conv_block(64,128)self.pool2nn.MaxPool2d(kernel_size2,stride2)self.enc3conv_block(128,256)self.pool3nn.MaxPool2d(kernel_size2,stride2)self.enc4conv_block(256,512)self.pool4nn.MaxPool2d(kernel_size2,stride2)self.bottleneckconv_block(512,1024)# Decoderself.upconv4nn.ConvTranspose2d(1024,512,kernel_size2,stride2)self.dec4conv_block(1024,512)self.upconv3nn.ConvTranspose2d(512,256,kernel_size2,stride2)self.dec3conv_block(512,256)self.upconv2nn.ConvTranspose2d(256,128,kernel_size2,stride2)self.dec2conv_block(256,128)self.upconv1nn.ConvTranspose2d(128,64,kernel_size2,stride2)self.dec1conv_block(128,64)self.final_convnn.Conv2d(64,out_channels,kernel_size1)defforward(self,x):enc1self.enc1(x)enc2self.enc2(self.pool1(enc1))enc3self.enc3(self.pool2(enc2))enc4self.enc4(self.pool3(enc3))bottleneckself.bottleneck(self.pool4(enc4))dec4self.upconv4(bottleneck)dec4torch.cat((dec4,enc4),dim1)dec4self.dec4(dec4)dec3self.upconv3(dec4)dec3torch.cat((dec3,enc3),dim1)dec3self.dec3(dec3)dec2self.upconv2(dec3)dec2torch.cat((dec2,enc2),dim1)dec2self.dec2(dec2)dec1self.upconv1(dec2)dec1torch.cat((dec1,enc1),dim1)dec1self.dec1(dec1)returntorch.sigmoid(self.final_conv(dec1))# 输出概率图defget_model():modelUNet()returnmodel 四、主训练代码train.py# train.pyimporttorchimporttorch.optimasoptimfromtorch.utils.tensorboardimportSummaryWriterfrommodelimportget_modelfromdatasetimportget_loaderimporttorch.nn.functionalasFdeftrain(model,dataloader,optimizer,criterion,device,epochs50):writerSummaryWriter(runs/crack_segmentation_experiment)model.train()forepochinrange(epochs):epoch_loss0fori,sampleinenumerate(dataloader):imagessample[image].to(device)maskssample[mask].to(device)optimizer.zero_grad()outputsmodel(images)losscriterion(outputs,masks)loss.backward()optimizer.step()epoch_lossloss.item()ifi%109:# Print every 10 batchesprint(fEpoch [{epoch1}/{epochs}], Batch [{i1}/{len(dataloader)}], Loss:{loss.item():.4f})avg_lossepoch_loss/len(dataloader)print(fEpoch [{epoch1}/{epochs}], Average Loss:{avg_loss:.4f})writer.add_scalar(Training Loss,avg_loss,epoch)torch.save(model.state_dict(),crack_segmentation_model.pth)if__name____main__:image_dirdata/imagesmask_dirdata/masksdevicetorch.device(cudaiftorch.cuda.is_available()elsecpu)modelget_model().to(device)dataloaderget_loader(image_dir,mask_dir)optimizeroptim.Adam(model.parameters(),lr0.001)criterionnn.BCELoss()# 使用Binary Cross Entropy Losstrain(model,dataloader,optimizer,criterion,device) 五、推理演示predict_demo.py# predict_demo.pyfrommodelimportget_modelfromdatasetimportCrackSegmentationDataset,transformsimporttorchfromPILimportImageimportmatplotlib.pyplotaspltdefmain():modelget_model()model.load_state_dict(torch.load(crack_segmentation_model.pth))model.eval()image_pathdata/images/sample.pngmask_pathdata/masks/sample.pngtransformtransforms.Compose([transforms.Resize((256,256)),transforms.ToTensor(),])imageImage.open(image_path).convert(RGB)maskImage.open(mask_path).convert(L)tensor_imagetransform(image).unsqueeze(0)withtorch.no_grad():outputmodel(tensor_image)output(output0.5).float()plt.figure(figsize(12,4))plt.subplot(1,3,1)plt.imshow(image)plt.title(Input Image)plt.axis(off)plt.subplot(1,3,2)plt.imshow(mask,cmapgray)plt.title(Ground Truth Mask)plt.axis(off)plt.subplot(1,3,3)plt.imshow(output.squeeze().cpu().numpy(),cmapgray)plt.title(Predicted Mask)plt.axis(off)plt.show()if__name____main__:main()⚙️ 六、训练优化建议问题解决方案小目标漏检细小裂缝使用多尺度特征融合如DeepLabv3中的ASPP模块或增加数据增强策略旋转、缩放等类别不平衡背景远多于裂缝使用加权交叉熵损失函数BCEWithLogitsLoss(pos_weight...)或Focal Loss过拟合引入正则化Dropout、L2正则、早停机制使用预训练模型初始化权重