全卷积网络(FCN)实战:使用FCN实现语义分割,2024年最新简单python五子棋代码

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Python全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Python知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注Python)
img

正文

Indoor: bottle, chair, dining table, potted plant, sofa, tv/monitor

img

下载地址:The PASCAL Visual Object Classes Challenge 2012 (VOC2012) (ox.ac.uk)

数据集的结构:

VOCdevkit

└── VOC2012

├── Annotations 所有的图像标注信息(XML文件)

├── ImageSets

│ ├── Action 人的行为动作图像信息

│ ├── Layout 人的各个部位图像信息

│ │

│ ├── Main 目标检测分类图像信息

│ │ ├── train.txt 训练集(5717)

│ │ ├── val.txt 验证集(5823)

│ │ └── trainval.txt 训练集+验证集(11540)

│ │

│ └── Segmentation 目标分割图像信息

│ ├── train.txt 训练集(1464)

│ ├── val.txt 验证集(1449)

│ └── trainval.txt 训练集+验证集(2913)

├── JPEGImages 所有图像文件

├── SegmentationClass 语义分割png图(基于类别)

└── SegmentationObject 实例分割png图(基于目标)

数据集包含物体检测和语义分割,我们只需要语义分割的数据集,所以可以考虑把多余的图片删除,删除的思路:

1、获取所有图片的name。

2、获取所有语义分割mask的name。

3、求二者的差集,然后将差集的name删除。

代码如下:

import glob

import os

image_all = glob.glob(‘data/VOCdevkit/VOC2012/JPEGImages/*.jpg’)

image_all_name = [image_file.replace(‘\’, ‘/’).split(‘/’)[-1].split(‘.’)[0] for image_file in image_all]

image_SegmentationClass = glob.glob(‘data/VOCdevkit/VOC2012/SegmentationClass/*.png’)

image_se_name= [image_file.replace(‘\’, ‘/’).split(‘/’)[-1].split(‘.’)[0] for image_file in image_SegmentationClass]

image_other=list(set(image_all_name) - set(image_se_name))

print(image_other)

for image_name in image_other:

os.remove(‘data/VOCdevkit/VOC2012/JPEGImages/{}.jpg’.format(image_name))

代码链接

===============================================================

本例选用的代码来自deep-learning-for-image-processing/pytorch_segmentation/fcn at master · WZMIAOMIAO/deep-learning-for-image-processing (github.com)

其他的代码也有很多,这篇比较好理解!

其实还有个比较好的图像分割库:https://github.com/qubvel/segmentation_models.pytorch

这个图像分割集合由俄罗斯的程序员小哥Pavel Yakubovskiy一手打造。在后面的文章,我也会使用这个库演示。

项目结构

===============================================================

├── src: 模型的backbone以及FCN的搭建

├── train_utils: 训练、验证以及多GPU训练相关模块

├── my_dataset.py: 自定义dataset用于读取VOC数据集

├── train.py: 以fcn_resnet50(这里使用了Dilated/Atrous Convolution)进行训练

├── predict.py: 简易的预测脚本,使用训练好的权重进行预测测试

├── validation.py: 利用训练好的权重验证/测试数据的mIoU等指标,并生成record_mAP.txt文件

└── pascal_voc_classes.json: pascal_voc标签文件

由于代码很多不能一一讲解,所以,接下来对重要的代码做剖析。

自定义数据集读取

===================================================================

my_dataset.py自定义数据读取的方法,代码如下:

import os

import torch.utils.data as data

from PIL import Image

class VOCSegmentation(data.Dataset):

def init(self, voc_root, year=“2012”, transforms=None, txt_name: str = “train.txt”):

super(VOCSegmentation, self).init()

assert year in [“2007”, “2012”], “year must be in [‘2007’, ‘2012’]”

root = os.path.join(voc_root, “VOCdevkit”, f"VOC{year}")

root=root.replace(‘\’,‘/’)

assert os.path.exists(root), “path ‘{}’ does not exist.”.format(root)

image_dir = os.path.join(root, ‘JPEGImages’)

mask_dir = os.path.join(root, ‘SegmentationClass’)

txt_path = os.path.join(root, “ImageSets”, “Segmentation”, txt_name)

txt_path=txt_path.replace(‘\’,‘/’)

assert os.path.exists(txt_path), “file ‘{}’ does not exist.”.format(txt_path)

with open(os.path.join(txt_path), “r”) as f:

file_names = [x.strip() for x in f.readlines() if len(x.strip()) > 0]

self.images = [os.path.join(image_dir, x + “.jpg”) for x in file_names]

self.masks = [os.path.join(mask_dir, x + “.png”) for x in file_names]

assert (len(self.images) == len(self.masks))

self.transforms = transforms

导入需要的包。

定义VOC数据集读取类VOCSegmentation。在init方法中,核心是读取image列表和mask列表。

def getitem(self, index):

img = Image.open(self.images[index]).convert(‘RGB’)

target = Image.open(self.masks[index])

if self.transforms is not None:

img, target = self.transforms(img, target)

return img, target

__getitem__方法是获取单张图片和图片对应的mask,然后对其做数据增强。

def collate_fn(batch):

images, targets = list(zip(*batch))

batched_imgs = cat_list(images, fill_value=0)

batched_targets = cat_list(targets, fill_value=255)

return batched_imgs, batched_targets

collate_fn方法是对一个batch中数据调用cat_list做数据对齐。

在train.py中torch.utils.data.DataLoader调用

train_loader = torch.utils.data.DataLoader(train_dataset,

batch_size=batch_size,

num_workers=num_workers,

shuffle=True,

pin_memory=True,

collate_fn=train_dataset.collate_fn)

val_loader = torch.utils.data.DataLoader(val_dataset,

batch_size=1,

num_workers=num_workers,

pin_memory=True,

collate_fn=val_dataset.collate_fn)

训练

=============================================================

重要参数


打开train.py,我们先认识一下重要的参数:

def parse_args():

import argparse

parser = argparse.ArgumentParser(description=“pytorch fcn training”)

数据集的根目录(VOCdevkit)所在的文件夹

parser.add_argument(“–data-path”, default=“data/”, help=“VOCdevkit root”)

parser.add_argument(“–num-classes”, default=20, type=int)

parser.add_argument(“–aux”, default=True, type=bool, help=“auxilier loss”)

parser.add_argument(“–device”, default=“cuda”, help=“training device”)

parser.add_argument(“-b”, “–batch-size”, default=32, type=int)

parser.add_argument(“–epochs”, default=30, type=int, metavar=“N”,

help=“number of total epochs to train”)

parser.add_argument(‘–lr’, default=0.0001, type=float, help=‘initial learning rate’)

parser.add_argument(‘–momentum’, default=0.9, type=float, metavar=‘M’,

help=‘momentum’)

parser.add_argument(‘–wd’, ‘–weight-decay’, default=1e-4, type=float,

metavar=‘W’, help=‘weight decay (default: 1e-4)’,

dest=‘weight_decay’)

parser.add_argument(‘–print-freq’, default=10, type=int, help=‘print frequency’)

parser.add_argument(‘–resume’, default=‘’, help=‘resume from checkpoint’)

parser.add_argument(‘–start-epoch’, default=0, type=int, metavar=‘N’,

help=‘start epoch’)

是否使用混合精度训练

parser.add_argument(“–amp”, default=False, type=bool,

help=“Use torch.cuda.amp for mixed precision training”)

args = parser.parse_args()

return args

data-path:定义数据集的根目录(VOCdevkit)所在的文件夹

num-classes:检测目标类别数(不包含背景)。

aux:是否使用aux_classifier。

device:使用cpu还是gpu训练,默认是cuda。

batch-size:BatchSize设置。

epochs:epoch的个数。

lr:学习率。

resume:继续训练时候,选择用的模型。

start-epoch:起始的epoch,针对再次训练时,可以不需要从0开始。

amp:是否使用torch的自动混合精度训练。

数据增强


增强调用transforms.py中的方法。

训练集的增强如下:

class SegmentationPresetTrain:

def init(self, base_size, crop_size, hflip_prob=0.5, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):

随机Resize的最小尺寸

min_size = int(0.5 * base_size)

随机Resize的最大尺寸

max_size = int(2.0 * base_size)

随机Resize增强。

trans = [T.RandomResize(min_size, max_size)]

if hflip_prob > 0:

#随机水平翻转

trans.append(T.RandomHorizontalFlip(hflip_prob))

trans.extend([

#随机裁剪

T.RandomCrop(crop_size),

T.ToTensor(),

T.Normalize(mean=mean, std=std),

])

self.transforms = T.Compose(trans)

def call(self, img, target):

return self.transforms(img, target)

训练集增强,包括随机Resize、随机水平翻转、随即裁剪。

验证集增强:

class SegmentationPresetEval:

def init(self, base_size, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):

self.transforms = T.Compose([

T.RandomResize(base_size, base_size),

T.ToTensor(),

T.Normalize(mean=mean, std=std),

])

def call(self, img, target):

return self.transforms(img, target)

验证集的增强比较简单,只有随机Resize。

Main方法


对Main方法,我做了一些修改,修改的代码如下:

#定义模型,并加载预训练

model = fcn_resnet50(pretrained=True)

默认classes是21,如果不是21,则要修改类别。

if num_classes != 21:

model.classifier[4] = torch.nn.Conv2d(512, num_classes, kernel_size=(1, 1), stride=(1, 1))

model.aux_classifier[4] = torch.nn.Conv2d(256, num_classes, kernel_size=(1, 1), stride=(1, 1))

print(model)

model.to(device)

如果有多张显卡,则使用多张显卡

if torch.cuda.device_count() > 1:

print(“Let’s use”, torch.cuda.device_count(), “GPUs!”)

model = torch.nn.DataParallel(model)

模型,我改为pytorch官方的模型了,如果能使用官方的模型尽量使用官方的模型。

默认类别是21,如果不是21,则要修改类别。

检测系统中是否有多张卡,如果有多张卡则使用多张卡不能浪费资源。

如果不想使用所有的卡,而是指定其中的几张卡,可以使用:

os.environ[‘CUDA_VISIBLE_DEVICES’] = ‘0,1’

也可以在DataParallel方法中设定:

model = torch.nn.DataParallel(model,device_ids=[0,1])

如果使用了多显卡,再使用模型的参数就需要改为model.module.xxx,例如:

params = [p for p in model.module.aux_classifier.parameters() if p.requires_grad]

params_to_optimize.append({“params”: params, “lr”: args.lr * 10})

上面的都完成了就可以开始训练了,如下图:

image-20220303230535077测试

=====================================================================================================================================================================

在开始测试之前,我们还要获取到调色板,新建脚本get_palette.py,代码如下:

import json

import numpy as np

from PIL import Image

读取mask标签

target = Image.open(“./2007_001288.png”)

获取调色板

palette = target.getpalette()

palette = np.reshape(palette, (-1, 3)).tolist()

print(palette)

转换成字典子形式

pd = dict((i, color) for i, color in enumerate(palette))

json_str = json.dumps(pd)

with open(“palette.json”, “w”) as f:

f.write(json_str)

选取一张mask,然后使用getpalette方法获取,然后将其转为字典的格式保存。

接下来,开始预测部分,新建predict.py,插入以下代码:

import os

import time

import json

import torch
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

五、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
adow_50,text_Q1NETiBA56iL5bqP5aqb56eD56eD,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)

五、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
[外链图片转存中…(img-A2yFZxi1-1713465223599)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值