设计神经网络的一般步骤:
1. 设计框架
2. 设计骨干网络
Unet网络设计的步骤:
1. 设计Unet网络工厂模式
2. 设计编解码结构
3. 设计卷积模块
4. unet实例模块
Unet网络最重要的特征:
1. 编解码结构。
2. 解码结构,比FCN更加完善,采用连接方式。
3. 本质是一个框架,编码部分可以使用很多图像分类网络。
示例代码:
import torch import torch.nn as nn class Unet(nn.Module): #初始化参数:Encoder,Decoder,bridge #bridge默认值为无,如果有参数传入,则用该参数替换None def __init__(self,Encoder,Decoder,bridge = None): super(Unet,self).__init__() self.encoder = Encoder(encoder_blocks) self.decoder = Decoder(decoder_blocks) self.bridge = bridge def forward(self,x): res = self.encoder(x) out,skip = res[0],res[1,:] if bridge is not None: out = bridge(out) out = self.decoder(out,skip) return out #设计编码模块 class Encoder(nn.Module): def __init__(self,blocks): super(Encoder,self).__init__() #assert:断言函数,避免出现参数错误 assert len(blocks) > 0 #nn.Modulelist():模型列表,所有的参数可以纳入网络,但是没有forward函数 self.blocks = nn.Modulelist(blocks) def forward(self,x): skip = [] for i in range(len(self.blocks) - 1): x = self.blocks[i](x) skip.append(x) res = [self.block[i+1](x)] #列表之间可以通过+号拼接 res += skip return res #设计Decoder模块 class Decoder(nn.Module): def __init__(self,blocks): super(Decoder, self).__init__() assert len(blocks) > 0 self.blocks = nn.Modulelist(blocks) def ceter_crop(self,skips,x): _,_,height1,width1 = skips.shape() _,_,height2,width2 = x.shape() #对图像进行剪切处理,拼接的时候保持对应size参数一致 ht,wt = min(height1,height2),min(width1,width2) dh1 = (height1 - height2)//2 if height1 > height2 else 0 dw1 = (width1 - width2)//2 if width1 > width2 else 0 dh2 = (height2 - height1)//2 if height2 > height1 else 0 dw2 = (width2 - width1)//2 if width2 > width1 else 0 return skips[:,:,dh1:(dh1 + ht),dw1:(dw1 + wt)], x[:,:,dh2:(dh2 + ht),dw2 : (dw2 + wt)] def forward(self, skips,x,reverse_skips = True): assert len(skips) == len(blocks) - 1 if reverse_skips is True: skips = skips[: : -1] x = self.blocks[0](x) for i in range(1, len(self.blocks)): skip = skips[i-1] x = torch.cat(skip,x,1) x = self.blocks[i](x) return x #定义了一个卷积block def unet_convs(in_channels,out_channels,padding = 0): #nn.Sequential:与Modulelist相比,包含了forward函数 return nn.Sequential( nn.Conv2d(in_channels, out_channels, kernal_size = 3, padding = padding, bias = False), nn.BatchNorm2d(outchannels), nn.ReLU(inplace = True), nn.Conv2d(in_channels, out_channels, kernal_size=3, padding=padding, bias=False), nn.BatchNorm2d(outchannels), nn.ReLU(inplace=True), ) #实例化Unet模型 def unet(in_channels,out_channels): encoder_blocks = [unet_convs(in_channels, 64), nn.Sequential(nn.Maxpool2d(kernal_size = 2, stride = 2, ceil_mode = True), unet_convs(64,128)), nn.Sequential(nn.Maxpool2d(kernal_size=2, stride=2, ceil_mode=True), unet_convs(128, 256)), nn.Sequential(nn.Maxpool2d(kernal_size=2, stride=2, ceil_mode=True), unet_convs(256, 512)), ] bridge = nn.Sequential(unet_convs(512, 1024)) decoder_blocks = [nn.conTranpose2d(1024, 512), nn.Sequential(unet_convs(1024, 512), nn.conTranpose2d(512, 256)), nn.Sequential(unet_convs(512, 256), nn.conTranpose2d(256, 128)), nn.Sequential(unet_convs(512, 256), nn.conTranpose2d(256, 128)), nn.Sequential(unet_convs(256, 128), nn.conTranpose2d(128, 64)) ] return Unet(encoder_blocks,decoder_blocks,bridge)
补充知识:Pytorch搭建U-Net网络
U-Net: Convolutional Networks for Biomedical Image Segmentation
import torch.nn as nn import torch from torch import autograd from torchsummary import summary class DoubleConv(nn.Module): def __init__(self, in_ch, out_ch): super(DoubleConv, self).__init__() self.conv = nn.Sequential( nn.Conv2d(in_ch, out_ch, 3, padding=0), nn.BatchNorm2d(out_ch), nn.ReLU(inplace=True), nn.Conv2d(out_ch, out_ch, 3, padding=0), nn.BatchNorm2d(out_ch), nn.ReLU(inplace=True) ) def forward(self, input): return self.conv(input) class Unet(nn.Module): def __init__(self, in_ch, out_ch): super(Unet, self).__init__() self.conv1 = DoubleConv(in_ch, 64) self.pool1 = nn.MaxPool2d(2) self.conv2 = DoubleConv(64, 128) self.pool2 = nn.MaxPool2d(2) self.conv3 = DoubleConv(128, 256) self.pool3 = nn.MaxPool2d(2) self.conv4 = DoubleConv(256, 512) self.pool4 = nn.MaxPool2d(2) self.conv5 = DoubleConv(512, 1024) # 逆卷积,也可以使用上采样 self.up6 = nn.ConvTranspose2d(1024, 512, 2, stride=2) self.conv6 = DoubleConv(1024, 512) self.up7 = nn.ConvTranspose2d(512, 256, 2, stride=2) self.conv7 = DoubleConv(512, 256) self.up8 = nn.ConvTranspose2d(256, 128, 2, stride=2) self.conv8 = DoubleConv(256, 128) self.up9 = nn.ConvTranspose2d(128, 64, 2, stride=2) self.conv9 = DoubleConv(128, 64) self.conv10 = nn.Conv2d(64, out_ch, 1) def forward(self, x): c1 = self.conv1(x) crop1 = c1[:,:,88:480,88:480] p1 = self.pool1(c1) c2 = self.conv2(p1) crop2 = c2[:,:,40:240,40:240] p2 = self.pool2(c2) c3 = self.conv3(p2) crop3 = c3[:,:,16:120,16:120] p3 = self.pool3(c3) c4 = self.conv4(p3) crop4 = c4[:,:,4:60,4:60] p4 = self.pool4(c4) c5 = self.conv5(p4) up_6 = self.up6(c5) merge6 = torch.cat([up_6, crop4], dim=1) c6 = self.conv6(merge6) up_7 = self.up7(c6) merge7 = torch.cat([up_7, crop3], dim=1) c7 = self.conv7(merge7) up_8 = self.up8(c7) merge8 = torch.cat([up_8, crop2], dim=1) c8 = self.conv8(merge8) up_9 = self.up9(c8) merge9 = torch.cat([up_9, crop1], dim=1) c9 = self.conv9(merge9) c10 = self.conv10(c9) out = nn.Sigmoid()(c10) return out if __name__=="__main__": test_input=torch.rand(1, 1, 572, 572) model=Unet(in_ch=1, out_ch=2) summary(model, (1,572,572)) ouput=model(test_input) print(ouput.size())
---------------------------------------------------------------- Layer (type) Output Shape Param # ================================================================ Conv2d-1 [-1, 64, 570, 570] 640 BatchNorm2d-2 [-1, 64, 570, 570] 128 ReLU-3 [-1, 64, 570, 570] 0 Conv2d-4 [-1, 64, 568, 568] 36,928 BatchNorm2d-5 [-1, 64, 568, 568] 128 ReLU-6 [-1, 64, 568, 568] 0 DoubleConv-7 [-1, 64, 568, 568] 0 MaxPool2d-8 [-1, 64, 284, 284] 0 Conv2d-9 [-1, 128, 282, 282] 73,856 BatchNorm2d-10 [-1, 128, 282, 282] 256 ReLU-11 [-1, 128, 282, 282] 0 Conv2d-12 [-1, 128, 280, 280] 147,584 BatchNorm2d-13 [-1, 128, 280, 280] 256 ReLU-14 [-1, 128, 280, 280] 0 DoubleConv-15 [-1, 128, 280, 280] 0 MaxPool2d-16 [-1, 128, 140, 140] 0 Conv2d-17 [-1, 256, 138, 138] 295,168 BatchNorm2d-18 [-1, 256, 138, 138] 512 ReLU-19 [-1, 256, 138, 138] 0 Conv2d-20 [-1, 256, 136, 136] 590,080 BatchNorm2d-21 [-1, 256, 136, 136] 512 ReLU-22 [-1, 256, 136, 136] 0 DoubleConv-23 [-1, 256, 136, 136] 0 MaxPool2d-24 [-1, 256, 68, 68] 0 Conv2d-25 [-1, 512, 66, 66] 1,180,160 BatchNorm2d-26 [-1, 512, 66, 66] 1,024 ReLU-27 [-1, 512, 66, 66] 0 Conv2d-28 [-1, 512, 64, 64] 2,359,808 BatchNorm2d-29 [-1, 512, 64, 64] 1,024 ReLU-30 [-1, 512, 64, 64] 0 DoubleConv-31 [-1, 512, 64, 64] 0 MaxPool2d-32 [-1, 512, 32, 32] 0 Conv2d-33 [-1, 1024, 30, 30] 4,719,616 BatchNorm2d-34 [-1, 1024, 30, 30] 2,048 ReLU-35 [-1, 1024, 30, 30] 0 Conv2d-36 [-1, 1024, 28, 28] 9,438,208 BatchNorm2d-37 [-1, 1024, 28, 28] 2,048 ReLU-38 [-1, 1024, 28, 28] 0 DoubleConv-39 [-1, 1024, 28, 28] 0 ConvTranspose2d-40 [-1, 512, 56, 56] 2,097,664 Conv2d-41 [-1, 512, 54, 54] 4,719,104 BatchNorm2d-42 [-1, 512, 54, 54] 1,024 ReLU-43 [-1, 512, 54, 54] 0 Conv2d-44 [-1, 512, 52, 52] 2,359,808 BatchNorm2d-45 [-1, 512, 52, 52] 1,024 ReLU-46 [-1, 512, 52, 52] 0 DoubleConv-47 [-1, 512, 52, 52] 0 ConvTranspose2d-48 [-1, 256, 104, 104] 524,544 Conv2d-49 [-1, 256, 102, 102] 1,179,904 BatchNorm2d-50 [-1, 256, 102, 102] 512 ReLU-51 [-1, 256, 102, 102] 0 Conv2d-52 [-1, 256, 100, 100] 590,080 BatchNorm2d-53 [-1, 256, 100, 100] 512 ReLU-54 [-1, 256, 100, 100] 0 DoubleConv-55 [-1, 256, 100, 100] 0 ConvTranspose2d-56 [-1, 128, 200, 200] 131,200 Conv2d-57 [-1, 128, 198, 198] 295,040 BatchNorm2d-58 [-1, 128, 198, 198] 256 ReLU-59 [-1, 128, 198, 198] 0 Conv2d-60 [-1, 128, 196, 196] 147,584 BatchNorm2d-61 [-1, 128, 196, 196] 256 ReLU-62 [-1, 128, 196, 196] 0 DoubleConv-63 [-1, 128, 196, 196] 0 ConvTranspose2d-64 [-1, 64, 392, 392] 32,832 Conv2d-65 [-1, 64, 390, 390] 73,792 BatchNorm2d-66 [-1, 64, 390, 390] 128 ReLU-67 [-1, 64, 390, 390] 0 Conv2d-68 [-1, 64, 388, 388] 36,928 BatchNorm2d-69 [-1, 64, 388, 388] 128 ReLU-70 [-1, 64, 388, 388] 0 DoubleConv-71 [-1, 64, 388, 388] 0 Conv2d-72 [-1, 2, 388, 388] 130 ================================================================ Total params: 31,042,434 Trainable params: 31,042,434 Non-trainable params: 0 ---------------------------------------------------------------- Input size (MB): 1.25 Forward/backward pass size (MB): 3280.59 Params size (MB): 118.42 Estimated Total Size (MB): 3400.26 ---------------------------------------------------------------- torch.Size([1, 2, 388, 388])
以上这篇使用pytorch实现论文中的unet网络就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]