Upstage AI Lab 2기
2024년 3월 7일 (목) Day_059
수강생 TODO
https://hyj89han.tistory.com/133
오늘의 TODO
.ipynb -> .py로local 에 data 저장후, data class 써서 불러오기 (torch.utils.data의 Dataset 상속받아서)클래스가 일정하게 배분되었는지 확인하기 --------> 여기까지 1시 전까지 해결하기클래스 데이터의 특성을 정확하게 파악하기early stopping 10은 너무 크다, 3도 너무 크다 (모델이 클 수록, 파라미터 튜닝이 잘 되어 있을 수록 3번까지 valid loss가 안 떨어지는 경우 많지 않음, 큰 모델에서도 epoch 100 넘어가는 경우 많지 않음)- normalization 반드시 하기 -> 조금 애매하게 함
데이터 사이즈에 비해 conv2d 층이 너무 깊음 -> data input output을 잘 생각해라feature extraction layer와 classification layer 분리꼭!!!! 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
'Upstage AI Lab 2기' 카테고리의 다른 글
Upstage AI Lab 2기 [Day060] (0) | 2024.03.08 |
---|---|
Upstage AI Lab 2기 [Day060] 수강생 TODO #02 - Pytorch Data Loading - 수정작업 #2 (4) | 2024.03.08 |
Upstage AI Lab 2기 [Day058] 수강생 TODO #02 - Pytorch Data Loading (0) | 2024.03.06 |
Upstage AI Lab 2기 [Day058] 수강생 TODO #01 - MNIST CNN (0) | 2024.03.06 |
Upstage AI Lab 2기 [Day058] CNN 구현 (0) | 2024.03.06 |