小黑的Python日記:Unet簡(jiǎn)單實(shí)現(xiàn)裂縫分割

大噶好帖努,我系小黑喵

裂縫數(shù)據(jù)集

數(shù)據(jù)集地址:https://github.com/cuilimeng/CrackForest-dataset
結(jié)構(gòu):

  --project
    main.py
     --image
        --train
           --data
           --groundTruth
        --val
           --data
           --groundTruth

我手動(dòng)將數(shù)據(jù)集做成這個(gè)格式地梨,其中trian84張蛋逾,val34張程储,都保存為了jpg圖像。

Unet

論文地址:http://www.arxiv.org/pdf/1505.04597.pdf
代碼來(lái)源:https://github.com/JavisPeng/u_net_liver
上面代碼中,作者將Unet運(yùn)用于liver識(shí)別,和裂縫一樣,都只有一個(gè)mask偏化,因而我們可以直接使用上述代碼。

Unet結(jié)構(gòu)

需要修改dataset.py為自己的數(shù)據(jù)集镐侯,其他小小改動(dòng)即可侦讨。

#dataset.py
import torch.utils.data as data
import PIL.Image as Image
import os


def make_dataset(rootdata,roottarget):#獲取img和mask的地址
    imgs = []
    filename_data = [x for x in os.listdir(rootdata)]
    for name in filename_data:
        img = os.path.join(rootdata, name)
        mask = os.path.join(roottarget, name)
        imgs.append((img, mask))#作為元組返回
    return imgs


class MyDataset(data.Dataset):
    def __init__(self, rootdata, roottarget, transform=None, target_transform=None):
        imgs = make_dataset(rootdata,roottarget)
        self.imgs = imgs
        self.transform = transform
        self.target_transform = target_transform

    def __getitem__(self, index):
        x_path, y_path = self.imgs[index]
        img_x = Image.open(x_path).convert('L')#讀取并轉(zhuǎn)換為二值圖像
        img_y = Image.open(y_path).convert('L')
        if self.transform is not None:
            img_x = self.transform(img_x)
        if self.target_transform is not None:
            img_y = self.target_transform(img_y)
        return img_x, img_y

    def __len__(self):
        return len(self.imgs)
#main.py
import numpy as np
import torch
import argparse
from torch.utils.data import DataLoader
from torch import autograd, optim
from torchvision.transforms import transforms
from unet import Unet
from dataset import MyDataset

# 是否使用cuda
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

x_transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize([0.5], [0.5])  # 復(fù)活了,這里修改就沒錯(cuò)誤了
])

# mask只需要轉(zhuǎn)換為tensor
y_transforms = transforms.ToTensor()


def train_model(model, criterion, optimizer, dataload, num_epochs=10):
    for epoch in range(0,num_epochs):
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)
        dt_size = len(dataload.dataset)
        epoch_loss = 0
        step = 0
        for x, y in dataload:
            step += 1
            inputs = x.to(device)
            labels = y.to(device)
            # zero the parameter gradients
            optimizer.zero_grad()
            # forward
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            epoch_loss += loss.item()
            print("%d/%d,train_loss:%0.3f" %
                  (step,
                   (dt_size - 1) // dataload.batch_size + 1, loss.item()))
        print("epoch %d loss:%0.3f" % (epoch, epoch_loss))
    torch.save(model.cpu().state_dict(), 'weights_%d.pth' % epoch)
    return model


#訓(xùn)練模型
def train():
    batch_size = 1
    liver_dataset = MyDataset(
        "image/train/data", "image/train/gt",transform=x_transforms, target_transform=y_transforms)
    dataloaders = DataLoader(
        liver_dataset, batch_size=batch_size, shuffle=True, num_workers=4)
    train_model(model, criterion, optimizer, dataloaders)


#顯示模型的輸出結(jié)果
def test():
    liver_dataset = MyDataset(
        "image/val/data", "image/val/gt", transform=x_transforms, target_transform=y_transforms)
    dataloaders = DataLoader(liver_dataset, batch_size=1)
    import matplotlib.pyplot as plt
    plt.ion()
    with torch.no_grad():
        for x, _ in dataloaders:
            y = model(x)
            img_y = torch.squeeze(y).numpy()
            plt.imshow(img_y)
            plt.pause(0.01)
        plt.show()


if __name__ == '__main__':
    pretrained = False
    model = Unet(1, 1).to(device)
    if pretrained:
        model.load_state_dict(torch.load('./weights_4.pth'))
    criterion = torch.nn.BCELoss()
    optimizer = optim.Adam(model.parameters())
    train()
    test()

unet.py不需要變動(dòng)

結(jié)果

訓(xùn)練了10個(gè)epoch后:累加loss大概到3
前幾張預(yù)測(cè)圖片:


上為預(yù)測(cè)苟翻,下為groundTruth

對(duì)于100多張的數(shù)據(jù)集韵卤,這個(gè)效果還行。
也算是填了一個(gè)以前的坑崇猫。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沈条,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子诅炉,更是在濱河造成了極大的恐慌蜡歹,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涕烧,死亡現(xiàn)場(chǎng)離奇詭異月而,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)议纯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門父款,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說我怎么就攤上這事铛漓∷菹悖” “怎么了鲫构?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵浓恶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我结笨,道長(zhǎng)包晰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任炕吸,我火速辦了婚禮伐憾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赫模。我一直安慰自己树肃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布瀑罗。 她就那樣靜靜地躺著胸嘴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪斩祭。 梳的紋絲不亂的頭發(fā)上劣像,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音摧玫,去河邊找鬼耳奕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛诬像,可吹牛的內(nèi)容都是我干的屋群。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼坏挠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谓晌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起癞揉,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纸肉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后喊熟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柏肪,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年芥牌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了烦味。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谬俄,靈堂內(nèi)的尸體忽然破棺而出柏靶,到底是詐尸還是另有隱情,我是刑警寧澤溃论,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布屎蜓,位于F島的核電站,受9級(jí)特大地震影響钥勋,放射性物質(zhì)發(fā)生泄漏炬转。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一算灸、第九天 我趴在偏房一處隱蔽的房頂上張望扼劈。 院中可真熱鬧,春花似錦菲驴、人聲如沸荐吵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)先煎。三九已至,卻和暖如春森逮,著一層夾襖步出監(jiān)牢的瞬間榨婆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工褒侧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留良风,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓闷供,卻偏偏與公主長(zhǎng)得像烟央,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歪脏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345