일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- ssh
- docker exec
- aiffel exploration
- cocre
- Jupyter notebook
- 사회조사분석사2급
- logistic regression
- Decision Boundary
- 티스토리챌린지
- HookNet
- cs231n
- 기초확률론
- airflow
- vscode
- 오블완
- GIT
- Pull Request
- docker
- Multi-Resolution Networks for Semantic Segmentation in Whole Slide Images
- 백신후원
- 도커
- WSSS
- 히비스서커스
- docker attach
- CellPin
- 코크리
- 프로그래머스
- IVI
- numpy
- AIFFEL
- Today
- Total
히비스서커스의 블로그
[Numpy] numpy로 이미지 처리하기 2 본문
binary semantic segmentation을 keras framework로 이미지 처리를 numpy로 진행할 시 마주친 여러 문제들을 정리해보았다. 개인적인 견해와 상황이므로 정확하지 않을 수 있으니 참고만 해주길 바란다.
keras semantic segmentation 시 generator에서 주의해야 할 사항
먼저 이미지 데이터 타입으로 unit8, uint16, uint32, float32 등 여러 가지 타입이 존재하지만 가장 많이 쓰는 것은 unit8 (min=0, max=255)과 float32(8bit의 지수, 23bit의 소수)인 듯 하다. 주어진 이미지와 마스크는 데이터 타입이 uint8이었다. 또한, binary segmentation을 시도하는 중이었기에 mask의 최대값은 1이었다.
1. numpy 데이터 타입을 float 32로 해줄 것
2. 이미지 데이터는 255로 나누어줄 것
class generator(keras.utils.Sequence):
def __init__(self, batch_size, img_size, zip_path_list, is_train):
self.batch_size = batch_size
self.img_size = img_size
self.zip_path_list = zip_path_list
self.augment = train_aug() if is_train == True else test_aug()
def __len__(self):
return len(self.zip_path_list) // self.batch_size
def __getitem__(self, idx):
i = idx * self.batch_size
batch_patch_pairs = self.zip_path_list[i : i + self.batch_size]
batch_x = np.zeros((self.batch_size,) + self.img_size + (3,), dtype='float32')
batch_y = np.zeros((self.batch_size,) + self.img_size + (1,), dtype='float32')
for j, path in enumerate(batch_patch_pairs):
img_path = path[0]
mask_path = path[1]
batch_x[j] = cv2.imread(img_path)
batch_y[j] = np.expand_dims(cv2.imread(mask_path, 0),2)
batch_aug = self.augment(image=batch_x[j], mask=batch_y[j])
batch_x[j] = batch_aug['image']/255
batch_y[j] = batch_aug['mask']
return batch_x, batch_y
먼저 dtype=float32로 해주어야 하는 이유는 keras의 segmentation model을 쓰기 위해서는 데이터 타입이 float32이어야 한다. uint8로 그대로 해주었을 경우 에러가 발생하였다.
이미지 데이터를 255로 나누어주는 이유는 데이터 자체를 matplotlib.pyplot에서 불러올 때 imshow에서 바로 볼 수 있게 하기 위함이다.
loss function이 negative로 나오는 경우
loss function을 분명 양의 값만을 가질 수 밖에 없는 diceloss와 binarycrossentropy를 사용하였음에도 불구하고 에러가 음의 값을 가진 경우가 나오게 되었다. 이유를 찾아보니 mask의 값이 0에서 1의 값을 가지는지 다시 확인을 해보라고 stackoverflow에 나와있었다.
Keras: Dice coefficient loss function is negative and increasing with epochs
According to this Keras implementation of Dice Co-eff loss function, the loss is minus of calculated value of dice coefficient. Loss should decrease with epochs but with this implementation I am ,
stackoverflow.com
따라서, 이때 다시 점검해봐야할 사항은 데이터와 이미지 generator를 거치고 나온 데이터 두 가지이다.
데이터 점검
데이터에서 이미지와 마스크의 값을 다시 한 번 점검해보아야 한다.
이때 주로 점검할 때 유용한 방법은 먼저 shape과 dtype 한번 더 살펴보고 numpy의 값들을 딕셔너리로 변환하여 값을 카운트 해보는 것이다.
import numpy as np
import glob
import cv2
mask_path_list = sorted(glob.glob('mask_path/*.png')) # mask path를 변경
for mask_path in mask_path_list:
mask = cv2.imread(mask_path)
print(f'mask_path : {mask_path}')
print(f'mask shape : {mask.shape}, mask dtype : {mask.dtype}')
unique, counts = np.unique(cv2.imread(mask_path, 0), return_counts = True)
uniq_cnt_dict = dict(zip(unique, counts))
print(f'mask element count : {uniq_cnt_dict}', '\n')
generator 나온 데이터 점검
generator를 거치며 __getitem__에서 새로운 numpy 배열을 만들고 기존의 값을 삽입하는데 이 과정에서 데이터의 값이 달라질 수 있다. 이를 유념하여 generator를 거친 후 만들어진 데이터를 __getitem__으로 몇 개만 가져와서 위와 동일한 작업을 해주면 이상이 있는지 확인하면 용이하다.
# BATCH_SIZE, INPUT_SHAPE, TRAIN_ZIP은 미리 설정해줄 것
train_gen = generator(BATCH_SIZE, INPUT_SHAPE, TRAIN_ZIP, is_train=True)
batch_x, batch_y = train_gen.__getitem__(0)
for idx in range(0, 4):
print('mask shape : ', batch_y[idx].shape, 'mask dtype : ', batch_y[idx].dtype)
unique, counts = np.unique(batch_y[idx], return_counts = True)
uniq_cnt_dict = dict(zip(unique, counts))
print(f'mask element count : {uniq_cnt_dict}', '\n')
이와 같이 점검을 통해 이미지, 마스크 numpy의 shape과 dtype, 그리고 내부 원소들의 값들을 확인하여 에러가 발생할 만한 요소가 있는지 확인하고 수정해주면 해결이 될 것이다.
-히비스서커스-
'Programming > Python' 카테고리의 다른 글
[Python] python으로 xml파일 parsing 및 저장 (feat. findall) (0) | 2021.10.05 |
---|---|
[Numpy] numpy로 이미지 처리하기 3 (2) | 2021.09.09 |
[Python] 한 줄 코드 및 GPU 분산처리 코드 (0) | 2021.08.26 |
[Numpy] numpy로 이미지 처리하기 (2) | 2021.06.30 |
[Python] python으로 multiprocessing 해보기 (2) | 2021.06.30 |