Бинарная сегментация в изображениях - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь выполнить аномалию сегментации в изображениях так, чтобы это была проблема двоичной сегментации. Набор данных, который я использовал, - это набор данных DAGM.

Описание набора данных https://resources.mpi -inf.mpg.de / conference / dagm / 2007 / prizes.html

Неискаженная часть изображения - это фон (значение пикселя 0), а дефектная часть изображения - это передний план (значение 255 пикселя). Я использовал сеть FCN для сегментирования своих изображений. Архитектура модели ниже. Для последнего слоя в модели я использовал функцию активации «sigmoid», а потери - «binary_crossentropy». Маски наземных изображений истинности имеют значения от 0 до 255. Маски были предварительно обработаны, поэтому значения пикселей лежат в диапазоне от 0 до 1.

1) Я беру количество классов = 2 или классы = 1?

2) Почему я получаю acc как 0.0000e + 04, когда я использую model.fit_generator и что-то вроде 90%, когда я использую model.fit?

3) Получение всех прогнозов в виде черных изображений (т.е. без дефектной области). Что-то не так я делаю в приведенном ниже коде?

Код для загрузки, предварительной обработки, разделения данных.

def load_train_data():
  with open(train_image_file,'r') as f:
    lines=f.readlines()
    lines=lines[1:]
    for line in lines:
      line=line.split("\t")
      defected=line[1]
      train_image=cv2.imread(dataset_path+folder+"/Train/"+line[2],0)
#       train_image=cv2.resize(train_image,(img_resize,img_resize))
      label_name=line[4].rstrip()
      mask_img_path=dataset_path+folder+"/Train/Label/"+label_name
      if defected=="0":
        a=np.zeros((img_resize,img_resize),dtype=np.uint8)
        ndi.append(train_image)
        ndm.append(a)
      else:
        a=cv2.imread(mask_img_path,0)
        a=cv2.resize(a,(img_resize,img_resize))
        di.append(train_image)
        dm.append(a)

  with open(test_image_file,'r') as f:
    lines=f.readlines()
    lines=lines[1:]
    for line in lines:
      line=line.split("\t")
      defected=line[1]
      test_image=cv2.imread(dataset_path+folder+"/Test/"+line[2],0)
#       test_image=cv2.resize(test_image,(img_resize,img_resize))
      label_name=line[4].rstrip()
      mask_img_path=dataset_path+folder+"/Test/Label/"+label_name
      if defected=="0":
        a=np.zeros((img_resize,img_resize),dtype=np.uint8)
        ndi.append(test_image)
        ndm.append(a)
      else:
        a=cv2.imread(mask_img_path,0)
        a=cv2.resize(a,(img_resize,img_resize))
        di.append(test_image)
        dm.append(a)

  print("Len of Non defected Images and Masks")
  print(len(ndi),len(ndm))
  print("Len of defected Images and Masks")
  print(len(di),len(dm))

  print("Oversampling Defected Data")
  from sklearn.utils import resample
  rdi = resample(di,replace=True,n_samples=len(ndi),random_state=27) 
  rdm = resample(dm,replace=True,n_samples=len(ndm),random_state=27) 

  print("Len after resampling")
  print(len(rdi),len(rdm))
  data=ndi+rdi
  labels=ndm+rdm
  data=np.array(data)
  labels=np.array(labels)
  return data,labels

def preprocess(imgs):
  imgs_p = imgs.reshape(imgs.shape[0], img_rows, img_cols,1)
  # for i in range(imgs.shape[0]):
  #     imgs_p[i] = resize(imgs[i], (img_cols, img_rows), preserve_range=True)

  # imgs_p = imgs_p[..., np.newaxis]
  return imgs_p


print('-'*30)
print('Loading and preprocessing train data...')
print('-'*30)
imgs_train, imgs_mask_train = load_train_data()

print("Train Images Shape {}".format(imgs_train.shape))
print("Train Images Mask Shape {}".format(imgs_mask_train.shape))

# imgs_train = preprocess(imgs_train)
imgs_train=imgs_train.reshape(imgs_train.shape[0],512,512,1)
imgs_mask_train = preprocess(imgs_mask_train)

print("Train Images Shape {}".format(imgs_train.shape))
print("Train Images Mask Shape {}".format(imgs_mask_train.shape))
imgs_train = imgs_train.astype('float32')
mean = np.mean(imgs_train)  # mean for data centering
std = np.std(imgs_train)  # std for data normalization

imgs_train -= mean
imgs_train /= std

imgs_mask_train = imgs_mask_train.astype('float32')
imgs_mask_train /=255.  # scale masks to [0,1]

imgs_train,imgs_test,imgs_mask_train,imgs_id_test=train_test_split(imgs_train,imgs_mask_train,test_size=0.10,random_state=42)
imgs_train,imgs_val,imgs_mask_train,imgs_mask_val=train_test_split(imgs_train,imgs_mask_train,test_size=0.10,random_state=42)

print("Train Images Shape {}".format(imgs_train.shape))
print("Train Images Mask Shape {}".format(imgs_mask_train.shape))

print("Val Images Shape {}".format(imgs_val.shape))
print("Val Images Mask Shape {}".format(imgs_mask_val.shape))

print("Test Images Shape {}".format(imgs_test.shape))
print("Test Images Mask Shape {}".format(imgs_id_test.shape))

plt.title("Train Image")
img=imgs_train[0]
img=img.reshape(img.shape[0],img.shape[1])
plt.imshow(img,cmap='gray')
plt.show()
plt.title("Train Image Mask")
img=imgs_mask_train[0]
img=img.reshape(img.shape[0],img.shape[1])
plt.imshow(img,cmap='gray')
plt.show()
plt.title("Val Image")
img=imgs_val[0]
img=img.reshape(img.shape[0],img.shape[1])
plt.imshow(img,cmap='gray')
plt.show()
plt.title("Val Image Mask")
img=imgs_mask_val[0]
img=img.reshape(img.shape[0],img.shape[1])
plt.imshow(img,cmap='gray')
plt.show()
plt.title("Test Image")
img=imgs_test[0]
img=img.reshape(img.shape[0],img.shape[1])
plt.imshow(img,cmap='gray')
plt.show()
plt.title("Test Image Mask")
img=imgs_id_test[0]
img=img.reshape(img.shape[0],img.shape[1])
plt.imshow(img,cmap='gray')
plt.show()



print('-'*30)
print('Creating and compiling model...')
print('-'*30)
model = get_model() 
print(model.summary())
model_checkpoint = ModelCheckpoint('weights.h5', monitor='val_loss', save_best_only=True)

print('-'*30)
print('Fitting model...')
print('-'*30)

data_gen=dict(featurewise_center=True,
      featurewise_std_normalization=True,
      rescale=1./255,
      rotation_range=180,
      width_shift_range=0.2,
      height_shift_range=0.2,
      horizontal_flip=True,
      vertical_flip=True,
      zoom_range=0.2,
      shear_range=0.2)

tid=ImageDataGenerator(**data_gen)
tmd=ImageDataGenerator(**data_gen)

vid=ImageDataGenerator(**data_gen)
vmd=ImageDataGenerator(**data_gen)


seed = 1
tid.fit(imgs_train,augment=True,seed=seed)
tmd.fit(imgs_mask_train,augment=True,seed=seed)

vid.fit(imgs_val,augment=True,seed=seed)
vmd.fit(imgs_mask_val,augment=True,seed=seed)

train_batchsize=16
val_batchsize=16

tid=tid.flow(imgs_train,batch_size=train_batchsize,seed=seed)
tmd=tmd.flow(imgs_mask_train,batch_size=train_batchsize,seed=seed)

vid=vid.flow(imgs_val,batch_size=val_batchsize,seed=seed)
vmd=vmd.flow(imgs_mask_val,batch_size=val_batchsize,seed=seed)

train_generator = zip(tid, tmd)
validation_generator = zip(vid, vmd)

trained_model=model.fit(imgs_train,imgs_mask_train,validation_data=(imgs_val,imgs_mask_val),batch_size=16,epochs=EPOCHS,callbacks=[model_checkpoint])

# trained_model=model.fit_generator(train_generator,
#                             validation_data=validation_generator,
#                             validation_steps=imgs_val.shape[0]//val_batchsize,
#                 steps_per_epoch=imgs_train.shape[0]//train_batchsize, epochs=EPOCHS,callbacks=[model_checkpoint])




print('-'*30)
print('Loading and preprocessing test data...')
print('-'*30)

print('-'*30)
print('Loading saved weights...')
print('-'*30)
model.load_weights('weights.h5')

print('-'*30)
print('Predicting masks on test data...')
print('-'*30)
imgs_mask_test = model.predict(imgs_test, verbose=1)
np.save('imgs_mask_test.npy', imgs_mask_test)

print('-' * 30)
print('Saving predicted masks to files...')
print('-' * 30)
pred_dir = 'preds'
if not os.path.exists(pred_dir):
    os.mkdir(pred_dir)
i=0
for image in imgs_mask_test:
    print(np.unique(image))
    image*=255
    imsave(os.path.join(pred_dir, str(i) + '_pred.png'), image)
    i+=1

loss = trained_model.history['loss']
val_loss = trained_model.history['val_loss']
epochs = range(EPOCHS)
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss for Segmentation in {}'.format(folder))


plt.legend()
plt.show()
plt.savefig(folder+"LossPlot")

код для модели

def get_model():
  classes=1
  img_input = Input(shape=(512,512,1))
  #First Block
  conv1 = Conv2D(32, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(img_input)
  bn1 = BatchNormalization()(conv1)
  conv2 = Conv2D(32, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(bn1)
  bn2 = BatchNormalization()(conv2)
  pool1 = MaxPooling2D(pool_size=(2, 2))(bn2)

  #Second Block
  conv3 = Conv2D(64, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)
  bn3 = BatchNormalization()(conv3)
  conv4 = Conv2D(64, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(bn3)
  bn4 = BatchNormalization()(conv4)
  conv5 = Conv2D(64, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(bn4)
  bn5 = BatchNormalization()(conv5)
  pool2 = MaxPooling2D(pool_size=(2, 2))(bn5)

  #Third Block
  conv6 = Conv2D(64, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2)
  bn6 = BatchNormalization()(conv6)
  conv7 = Conv2D(64, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(bn6)
  bn7 = BatchNormalization()(conv7)
  conv8 = Conv2D(64, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(bn7)
  bn8 = BatchNormalization()(conv8)
  conv9 = Conv2D(64, (5,5), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(bn8)
  bn9 = BatchNormalization()(conv9)
  pool3 = MaxPooling2D(pool_size=(2, 2))(bn9)

  #Fourth Block
  conv10 = Conv2D(1024, (15,15), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3)
  bn10 = BatchNormalization()(conv10)

  #Fifth Block
  conv11 = Conv2D(classes, (1,1), activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(bn10)
  bn11 = BatchNormalization()(conv11)

  model = Model(img_input, bn11)
  INIT_LR = 1e-4
  opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
  model.compile(loss="binary_crossentropy", optimizer=opt, metrics=["accuracy"])
  return model
...