본문 바로가기

Upstage AI Lab 2기

Upstage AI Lab 2기 [Day059] 수강생 TODO #02 - Pytorch Data Loading - 수정작업

Upstage AI Lab 2기

2024년 3월 7일 (목) Day_059

수강생 TODO

https://hyj89han.tistory.com/133

 


오늘의 TODO

  1. .ipynb -> .py로
  2. local 에 data 저장후, data class 써서 불러오기 (torch.utils.data의 Dataset 상속받아서)
  3. 클래스가 일정하게 배분되었는지 확인하기    --------> 여기까지 1시 전까지 해결하기
  4. 클래스 데이터의 특성을 정확하게 파악하기
  5. early stopping 10은 너무 크다, 3도 너무 크다 (모델이 클 수록, 파라미터 튜닝이 잘 되어 있을 수록 3번까지 valid loss가 안 떨어지는 경우 많지 않음, 큰 모델에서도 epoch 100 넘어가는 경우 많지 않음)
  6. normalization 반드시 하기 -> 조금 애매하게 함
  7. 데이터 사이즈에 비해 conv2d 층이 너무 깊음 -> data input output을 잘 생각해라
  8. feature extraction layer와 classification layer 분리
  9. 꼭!!!! test 까지 돌려보기

 

질문 :

  • 왜 8:2로 train val 나눴는가
  • 왜 test까지 안 돌려 봤는가
  • 왜 valid max acc 0.65가 낮은 성능이라고 생각하였는가
  • 왜 LeakyReLU 를 썼는지, 음수 값을 보존하는 게 목적이었다면 더 좋은 대안 들이 있었을 텐데?
  • 시그모이드 함수는 선형인가요 비선형인가요~?
  • overfitting은 언제 일어나는가? - data 수과 feature수의 상대적 크기와 관련 있음
  • 손실함수와 활성화 함수 왜 쓰는지 알고 쓸 것!

 

숙제 :

  • 왜 pixel의 value를 normalize 해서 0~1 range로 scaling 하면 성능이 오르는지
  • 왜 Normalization 을 하면 성능이 올라갈까? - 가우시안 분포와 관련이 있음 (딥러닝에서 가우시안 분포 매우매우 중요)
  • 과거에는 이미지 처리에 activation function으로 sigmoid를 썼었는데 왜 지금은 relu 계열을 쓸까? -> vanishing gradient problem
    (그의 설명 : 층이 깊어지면서 시그모이드를 안 쓰게 됨. range 0~1로 제한 되니까 깊어질 수록 값의 차이가 옅어지니까. 시그모이드가 혁신적이었던 것은 비선형 함수이면서 미분이 가능해서 )
  • kernel size 를 3*3를 쓰는 이유가 있다. 이미지 인풋이 큰 모델에서도 3*3을 많이 씀. 왜 그럴까요~?

가능한 추가 작업 :

  • K-fold validations

 


TODO later :

  • 꼭 tabular data setting하는 것 연습하기
  • 모델의 구조화 작업
  • augumentation

data 개요

https://www.cs.toronto.edu/~kriz/cifar.html

10개 클래스로 구분되는 총 60000개의 32*32 color image(RGB 3channel) 데이터 셋 - tiny images dataset

training dataset은 50000개, test dataset 10000개

train, test 각각 batch당 10000개 이미지가 들어 있음

test 에는 10개 클래스에 대해 1000개씩 이미지가 들어가 있도록 randomly selected

training의 5개 batch는 random 구성이라 batch 내 클래스 분포가 균일하지  않을 수 있지만 training dataset 전체로 보면 각 클래스 별 5000개의 이미지가 들어가 있도록 구성되어있음 

10개 클래스 : 비행기, 자동차, 새, 고양이, 사슴, 강아지, 개구리, 말, 배, 트럭

 

Task는 무엇인가?

어떤 손실함수를 써야 하는가?

어떤 output이 나와야 하는가?

 


# Each row of the array stores a 32x32 colour image. The first 1024 entries contain the red channel values, the next 1024 the green, and the final 1024 the blue. The image is stored in row-major order, so that the first 32 entries of the array are the red channel values of the first row of the image.

 


def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding ='bytes')
    return dict

train_dataset1 = unpickle('./data/cifar-10-python/cifar-10-batches-py/data_batch_1')

print(torch.Tensor(train_dataset1[b'data'][0]).reshape(3, 32, 32))

# tensor([[[ 59.,  43.,  50.,  ..., 158., 152., 148.],
#          [ 16.,   0.,  18.,  ..., 123., 119., 122.],
#          [ 25.,  16.,  49.,  ..., 118., 120., 109.],
#          ...,
#          [208., 201., 198.,  ..., 160.,  56.,  53.],
#          [180., 173., 186.,  ..., 184.,  97.,  83.],
#          [177., 168., 179.,  ..., 216., 151., 123.]],

#         [[ 62.,  46.,  48.,  ..., 132., 125., 124.],
#          [ 20.,   0.,   8.,  ...,  88.,  83.,  87.],
#          [ 24.,   7.,  27.,  ...,  84.,  84.,  73.],
#          ...,
#          [170., 153., 161.,  ..., 133.,  31.,  34.],
#          [139., 123., 144.,  ..., 148.,  62.,  53.],
#          [144., 129., 142.,  ..., 184., 118.,  92.]],

#         [[ 63.,  45.,  43.,  ..., 108., 102., 103.],
#          [ 20.,   0.,   0.,  ...,  55.,  50.,  57.],
#          [ 21.,   0.,   8.,  ...,  50.,  50.,  42.],
#          ...,
#          [ 96.,  34.,  26.,  ...,  70.,   7.,  20.],
#          [ 96.,  42.,  30.,  ...,  94.,  34.,  34.],
#          [116.,  94.,  87.,  ..., 140.,  84.,  72.]]])

 

 

 

Exception has occurred: TypeError
pic should be PIL Image or ndarray. Got <class 'torch.Tensor'>
  File "G:\내 드라이브\009_AI공부\09_Upstage Lab AI 2기\##_upstage lab\2주차\code\dataloading.py", line 73, in __getitem__
    img_tensor = self.transform(img_tensor)
  File "G:\내 드라이브\009_AI공부\09_Upstage Lab AI 2기\##_upstage lab\2주차\code\dataloading.py", line 87, in <module>
    first_train_data, first_train_target = cifar10_train_dataset[0]
TypeError: pic should be PIL Image or ndarray. Got <class 'torch.Tensor'>

 

 

 

 

Exception has occurred: RuntimeError
shape '[3, 32, 32]' is invalid for input of size 30720000
  File "G:\내 드라이브\009_AI공부\09_Upstage Lab AI 2기\##_upstage lab\2주차\code\dataloading.py", line 60, in __init__
    self.data.extend(torch.Tensor(batch_data[b'data']).reshape(3, 32, 32))
  File "G:\내 드라이브\009_AI공부\09_Upstage Lab AI 2기\##_upstage lab\2주차\code\dataloading.py", line 74, in <module>
    cifar10_train_dataset = CustomCIFAR10Dataset(root_dir = base_path, is_train = True, transform=cifar10_trasform)
RuntimeError: shape '[3, 32, 32]' is invalid for input of size 30720000

 

 

 

 

https://notebook.community/CUFCTL/DLBD/Fall2017/DataLoading

 

 

 

 

torch.utils.data.Dataset

https://pytorch.org/docs/stable/data.html#torch.utils.data.Dataset

 

 

 

kernel 3*3 이 성능이 좋다는 결과를 증명한 논문으로 예측되는 것들

VGG와 ResNet?

 

 

 

# extend와 append의 차이는?

https://m.blog.naver.com/wideeyed/221541104629

 

 

 

def random_split(dataset: Dataset[T], lengths: Sequence[Union[int, float]],
                 generator: Optional[Generator] = default_generator) -> List[Subset[T]]:
    r"""
    Randomly split a dataset into non-overlapping new datasets of given lengths.

    If a list of fractions that sum up to 1 is given,
    the lengths will be computed automatically as
    floor(frac * len(dataset)) for each fraction provided.

    After computing the lengths, if there are any remainders, 1 count will be
    distributed in round-robin fashion to the lengths
    until there are no remainders left.

    Optionally fix the generator for reproducible results, e.g.:

    Example:
        >>> # xdoctest: +SKIP
        >>> generator1 = torch.Generator().manual_seed(42)
        >>> generator2 = torch.Generator().manual_seed(42)
        >>> random_split(range(10), [3, 7], generator=generator1)
        >>> random_split(range(30), [0.3, 0.3, 0.4], generator=generator2)

    Args:
        dataset (Dataset): Dataset to be split
        lengths (sequence): lengths or fractions of splits to be produced
        generator (Generator): Generator used for the random permutation.
    """
    if math.isclose(sum(lengths), 1) and sum(lengths) <= 1:
        subset_lengths: List[int] = []
        for i, frac in enumerate(lengths):
            if frac < 0 or frac > 1:
                raise ValueError(f"Fraction at index {i} is not between 0 and 1")
            n_items_in_split = int(
                math.floor(len(dataset) * frac)  # type: ignore[arg-type]
            )
            subset_lengths.append(n_items_in_split)
        remainder = len(dataset) - sum(subset_lengths)  # type: ignore[arg-type]
        # add 1 to all the lengths in round-robin fashion until the remainder is 0
        for i in range(remainder):
            idx_to_add_at = i % len(subset_lengths)
            subset_lengths[idx_to_add_at] += 1
        lengths = subset_lengths
        for i, length in enumerate(lengths):
            if length == 0:
                warnings.warn(f"Length of split at index {i} is 0. "
                              f"This might result in an empty dataset.")

    # Cannot verify that dataset is Sized
    if sum(lengths) != len(dataset):    # type: ignore[arg-type]
        raise ValueError("Sum of input lengths does not equal the length of the input dataset!")

    indices = randperm(sum(lengths), generator=generator).tolist()  # type: ignore[call-overload]
    return [Subset(dataset, indices[offset - length : offset]) for offset, length in zip(_accumulate(lengths), lengths)]

 

 

 

 

No additional activation function is required after self.fclayer if you are using CrossEntropyLoss. The CrossEntropyLoss will take care of applying the softmax activation internally during the training process.

 

 

 

CIFAR-10 Dataset CNN Model achieving 85.97% accuracy with regularization and data augmentation. 

https://www.kaggle.com/code/sid2412/cifar10-cnn-model-85-97-accuracy

 

data augumentation과 normalization으로 성능고도화 해보기!

 

 

 

 

 

 

 

 

Early stopping at epoch 58

Valid max accuracy : 0.5828 

Custom CNN test accuracy : 0.5781

 

Early stopping at epoch 58

Valid max accuracy : 0.5828

Custom CNN test accuracy : 0.5781