โมเดล Keras - การแบ่งส่วนรูปภาพ Unet

ฉันกำลังพยายามสร้าง UNet ขึ้นใหม่โดยใช้ Keras model API ฉันได้รวบรวมรูปภาพของเซลล์ และเวอร์ชันที่แบ่งส่วนแล้ว และฉันกำลังพยายามฝึกโมเดลด้วย ในการทำเช่นนั้น ฉันสามารถอัปโหลดเซลล์อื่นและรับรูปภาพที่แบ่งส่วนเป็นการคาดการณ์ได้

https://github.com/JamilGafur/Unet

from __future__ import print_function

from matplotlib import pyplot as plt
from keras import losses
import os
from keras.models import Model
from keras.layers import Input, concatenate, Conv2D, MaxPooling2D, Conv2DTranspose
from keras.optimizers import Adam
import cv2
import numpy as np
# training data 
image_location = "C:/Users/JamilG-Lenovo/Desktop/train/"
image = image_location+"image"
label = image_location +"label"


class train_data():

    def __init__(self, image, label):
        self.image = []
        self.label = []
        for file in os.listdir(image):
            if file.endswith(".tif"):
                self.image.append(cv2.imread(image+"/"+file,0))

        for file in os.listdir(label):
            if file.endswith(".tif"):
                #print(label+"/"+file)
                self.label.append(cv2.imread(label+"/"+file,0))

    def get_image(self):
        return np.array(self.image)

    def get_label(self):
        return np.array(self.label)



def get_unet(rows, cols):
    inputs = Input((rows, cols, 1))
    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)
    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv1)
    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)

    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(pool1)
    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv2)
    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)

    conv3 = Conv2D(128, (3, 3), activation='relu', padding='same')(pool2)
    conv3 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv3)
    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)

    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool3)
    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv4)
    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)

    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool4)
    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv5)

    up6 = concatenate([Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(conv5), conv4], axis=3)
    conv6 = Conv2D(256, (3, 3), activation='relu', padding='same')(up6)
    conv6 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv6)

    up7 = concatenate([Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(conv6), conv3], axis=3)
    conv7 = Conv2D(128, (3, 3), activation='relu', padding='same')(up7)
    conv7 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv7)

    up8 = concatenate([Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(conv7), conv2], axis=3)
    conv8 = Conv2D(64, (3, 3), activation='relu', padding='same')(up8)
    conv8 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv8)

    up9 = concatenate([Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same')(conv8), conv1], axis=3)
    conv9 = Conv2D(32, (3, 3), activation='relu', padding='same')(up9)
    conv9 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv9)

    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)

    model = Model(inputs=[inputs], outputs=[conv10])
    model.compile(optimizer=Adam(lr=1e-5), loss = losses.mean_squared_error)

    return model



def main():
    # load all the training images
    train_set = train_data(image, label)
    # get the training image
    train_images = train_set.get_image()
    # get the segmented image
    train_label = train_set.get_label()
    print("type of train_images" + str(type(train_images[0])))
    print("type of train_label" + str(type(train_label[0])))
    print('\n')
    print("shape of train_images" + str(train_images[0].shape))
    print("shape of train_label" + str(train_label[0].shape))


    plt.imshow(train_images[0], interpolation='nearest')
    plt.title("actual image")
    plt.show()

    plt.imshow(train_label[0], interpolation='nearest')
    plt.title("segmented image")
    plt.show()
    # create a UNet (512,512)
    unet = get_unet(train_label[0].shape[0],
                    train_label[0].shape[1])

    # look at the summary of the unet
    unet.summary()
    #-----------errors start here-----------------

    # fit the unet with the actual image, train_images
    # and the output, train_label
    unet.fit(train_images, train_label, batch_size=16, epochs=10)

main()

เมื่อฉันพยายามเรียกใช้ ฉันคาดหวังว่ามันจะเหมาะสมมากกว่า 10 ยุค แต่กลับแสดงข้อผิดพลาดต่อไปนี้:

File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", 
line 144, in _standardize_input_data str(array.shape))

ValueError: Error when checking input: expected input_5 to have shape (None, 
512, 512, 1) but got array with shape (1, 30, 512, 512)

หากมีใครสามารถบอกฉันว่าฉันทำอะไรผิด รหัสควรเป็นอย่างไร หรือชี้ทิศทางที่ถูกต้องให้ฉัน ฉันจะขอบคุณมาก

ขอบคุณ!


person user3233991    schedule 05.12.2017    source แหล่งที่มา


คำตอบ (3)


ฉันคิดว่า Keras คาดว่าจะมี "ช่องสุดท้าย" ในขณะที่คุณกำลังส่งภาพใน "โหมดแรกของช่อง"

มีวิธีต่างๆ ในการเปลี่ยนการตั้งค่านี้ โปรดดูที่: https://keras.io/backend/

person lorenzori    schedule 29.12.2017

คุณต้องปรับรูปร่างข้อมูลอินพุตของคุณใหม่ตามที่ keras คาดหวัง: (จำนวนรูปภาพ, แถว, คอลัมน์, 1)

เพิ่มการพิมพ์รูปร่างของภาพเพื่อให้มีความชัดเจนมากขึ้น

ฉันคิดว่าชั้นเรียนที่นี่ซ้ำซ้อน แค่ใช้ฟังก์ชั่นก็แก้จุดบกพร่องได้ง่ายขึ้น บางทีคุณอาจอ่านรูปภาพเป็นรายการ จากนั้นเมื่อคุณแปลงมันเป็นอาร์เรย์ คุณจะได้ 1 นี้เป็นรูปร่างศูนย์

image = []
label = []
for file in os.listdir(image):
    if file.endswith(".tif"):
        image.append(cv2.imread(image+"/"+file,0).reshape((row,col,1))

for file in os.listdir(label):
    if file.endswith(".tif"):
        label.append(cv2.imread(label+"/"+file,0)).reshape((row,col,1))

แล้ว

unet.fit(images, label, batch_size=16, epochs=10)
person Naomi Fridman    schedule 12.11.2019

ฉันรู้ว่าคำถามนี้ค่อนข้างเก่า แต่ฉันก็ยังอยากจะให้ 2 เซ็นต์กับมัน ก่อนอื่น ฉันจะต้องชี้ให้เห็นว่าสถาปัตยกรรมที่คุณอ้างถึงที่นี่ไม่ใช่ของ U-Net

U-Net เริ่มต้นด้วยเลเยอร์ Convolutional 2 ชั้น โดยแต่ละชั้นมีตัวกรอง 64 ตัว ในตัวอย่างข้างต้น สถาปัตยกรรมแบบจำลองของคุณเริ่มต้นด้วยขนาดตัวกรอง 32 ช่องว่างภายในไม่ควรเหมือนกันแต่ถูกต้องและมีปัญหาอื่นๆ เล็กน้อย เช่น คุณไม่ได้ครอบตัดเอาต์พุตของเลเยอร์ที่ทำสัญญาก่อนที่จะต่อเข้ากับส่วนที่ขยาย

คุณจะต้องมีเลเยอร์อินพุตดังนี้

inputs = layers.Input(shape=(512, 512, 1))

และคุณจะต้องสร้างโมเดลตามรูปแบบดังต่อไปนี้

model.build(input_shape=(None, 1, 512, 512))

นั่นหมายความว่าคุณจะต้องปรับทิศทางการป้อนข้อมูลของคุณในลักษณะที่กล่าวมาข้างต้น ลิงก์ Github ของคุณใช้งานไม่ได้และฉันไม่สามารถดูขนาดอินพุตของรูปภาพได้เนื่องจากคุณใช้ตัวแปรแทนตัวเลข นี่คือการเดาของฉันที่นี่

หากคุณสนใจที่จะรู้ว่าโมเดล U-net จริงควรมีลักษณะอย่างไร คุณสามารถดูโค้ดด้านล่างนี้

def unet_model():
# declaring the input layer
# Input layer expects an RGB image, in the original paper the network consisted of only one channel.
inputs = layers.Input(shape=(572, 572, 3))
# first part of the U - contracting part
c0 = layers.Conv2D(64, activation='relu', kernel_size=3)(inputs)
c1 = layers.Conv2D(64, activation='relu', kernel_size=3)(c0)  # This layer for concatenating in the expansive part
c2 = layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid')(c1)

c3 = layers.Conv2D(128, activation='relu', kernel_size=3)(c2)
c4 = layers.Conv2D(128, activation='relu', kernel_size=3)(c3)  # This layer for concatenating in the expansive part
c5 = layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid')(c4)

c6 = layers.Conv2D(256, activation='relu', kernel_size=3)(c5)
c7 = layers.Conv2D(256, activation='relu', kernel_size=3)(c6)  # This layer for concatenating in the expansive part
c8 = layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid')(c7)

c9 = layers.Conv2D(512, activation='relu', kernel_size=3)(c8)
c10 = layers.Conv2D(512, activation='relu', kernel_size=3)(c9)  # This layer for concatenating in the expansive part
c11 = layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid')(c10)

c12 = layers.Conv2D(1024, activation='relu', kernel_size=3)(c11)
c13 = layers.Conv2D(1024, activation='relu', kernel_size=3, padding='valid')(c12)

# We will now start the second part of the U - expansive part
t01 = layers.Conv2DTranspose(512, kernel_size=2, strides=(2, 2), activation='relu')(c13)
crop01 = layers.Cropping2D(cropping=(4, 4))(c10)

concat01 = layers.concatenate([t01, crop01], axis=-1)

c14 = layers.Conv2D(512, activation='relu', kernel_size=3)(concat01)
c15 = layers.Conv2D(512, activation='relu', kernel_size=3)(c14)

t02 = layers.Conv2DTranspose(256, kernel_size=2, strides=(2, 2), activation='relu')(c15)
crop02 = layers.Cropping2D(cropping=(16, 16))(c7)

concat02 = layers.concatenate([t02, crop02], axis=-1)

c16 = layers.Conv2D(256, activation='relu', kernel_size=3)(concat02)
c17 = layers.Conv2D(256, activation='relu', kernel_size=3)(c16)

t03 = layers.Conv2DTranspose(128, kernel_size=2, strides=(2, 2), activation='relu')(c17)
crop03 = layers.Cropping2D(cropping=(40, 40))(c4)

concat03 = layers.concatenate([t03, crop03], axis=-1)

c18 = layers.Conv2D(128, activation='relu', kernel_size=3)(concat03)
c19 = layers.Conv2D(128, activation='relu', kernel_size=3)(c18)

t04 = layers.Conv2DTranspose(64, kernel_size=2, strides=(2, 2), activation='relu')(c19)
crop04 = layers.Cropping2D(cropping=(88, 88))(c1)

concat04 = layers.concatenate([t04, crop04], axis=-1)

c20 = layers.Conv2D(64, activation='relu', kernel_size=3)(concat04)
c21 = layers.Conv2D(64, activation='relu', kernel_size=3)(c20)

# This is based on our dataset. The output channels are 3, think of it as each pixel will be classified
# into three classes, but I have written 4 here, as I do padding with 0, so we end up have four classes.
outputs = layers.Conv2D(4, kernel_size=1)(c21)  

model = tf.keras.Model(inputs=inputs, outputs=outputs, name="u-netmodel")
return model
person pratsbhatt    schedule 04.07.2020