본문 바로가기
회고 🤔/네부캠 AI Tech

[네부캠 AI Tech] 2주차 학습 정리 🤓

by judy@ 2023. 11. 17.

회고보다는 학습 정리가 좀 더 어울리는 제목인 것 같아 바꿔봤다. 지난 주는 적응 + 기초 강의였다면 이번 주는 PyTorch의 기초와 구현 과제로 구성되어 있었고, 촘촘한 설명에 재미있게 따라가보았다..🏃🏻‍♂️

 

목차


    학습 정리 & 배운점

    # 231113 좀 할 만 한가?

    학습 정리 🤭

     

    [ PyTorch Basics ]

    - 파이토치의 기본적인 연산자
       - 텐서는 list, numpy를 통해 만들 수 있음. dims, shape, size() 사용 가능.
       - 동일 모양 텐서 간 덧셈, 뺄셈, 스칼라곱 가능. 

       - 곱 가능한 행렬 간 mm() 메서드 사용, 곱 가능한 벡터 간 dot() 메서드 사용. broadcasting 지원하는 메서드는 matmul()
       - 텐서에는 squeeze, unsqueeze(=expand_dims)가 있음
       - view()와 reshape() 메서드가 있는데, view는 원본의 메모리 주소 사용하고 형태만 바뀐, reshape은 유지 불가능할 때 객체를 복제함.
       - w를 텐서로 직접 선언하기보다는 linear 객체를 사용하는 편
    - 파이토치의 딥러닝 함수
       - torch.nn.functional에서 임포트하여 사용 가능. softmax, loss function 등이 있음.
    - 파이토치의 자동 미분
       - 연산.backward() 를 통해 미분하고, 여러 개의 파라미터 업데이트 시, external_dim에 필요한 차원만큼의 파라미터를 전달하여 미분계수를 전달받을 수 있음.

     

    [ PyTorch Projects ]

    - init_obj 라는 메서드로 필요한 모듈에 대한 컨피그를 dictionary 형태로 불러올 수 있음
    - getattr은 특정 모듈 내 'abc'라는 함수를 불러오고 싶을 때, getattr(module, 'abc')를 호출하면 module.abc가 반환되는 파이썬 내장 함수.

    - git에는 PyTorch 템플릿이 많음. data_loader 부터 train.py, test.py 까지 낱낱이 살펴보고 구현할 줄 알아야 함.

     

    배운점 📚

    - view 메서드에 대해서는 처음 알았음.
    - matmul에서 브로드캐스팅에 대해서는 추가로 알아봐야 할 필요가 있음
    - 자동 미분 시 여러 개의 변수를 업데이트하려면 인자를 추가해주어야 함.

    - 주피터 보다는 프로젝트 단위로 코딩하는 것이 실력 향상을 위해서도, 이해를 위해서도 좋을 듯. 대부분 CP & PASTE 하게 된다고 해도, 지금 단계에서는 하나하나 다 알아보자.

     

    # 231114 과..제만 하다가 하루가 다 갔네..?

    학습 정리 🤭

    - hook 함수의 실행 전후에 실행할 수 있도록 개발자들이 미리 구현해둔다고 함

       - PyTorch의 모듈에는 forward 전후에 관한 hook이 있어, forward 함수 실행 전후에 값을 변경하거나, weight를 초기화하거나 하는 등의 개입이 가능함. backward 도 마찬가지고, 훅을 사용하여 Backpropagation의 데이터를 변경할 수도 있음.

    - module을 출력할 때, 추가로 인자 정보 등을 출력하고 싶다면, expr_repr 함수를 오버라이팅하여 넣어주면 됨. ex) name

    ... (과제에 흔적이 남아있다..)...

     

    배운점 📚

    - 🐤 곽곽 부덕이와 함께하는 과제 타임 ! Pytorch의 도큐먼트를 하나하나 파헤치는 시간을 가졌고, PyTorch가 Python OOP 를 충실하게 따라 잘 만들어두어 더 편리한 것 같다.

    - 블로그, stackoverflow, GPT, .. 하지만 뭐니뭐니해도 근본인 도큐먼트. 익숙해질 기간 동안에는 블로그 기반 코딩보다는 공식 도큐먼트를 참고하는 아주 클래식한 방법으로 접근하여 문제를 해결해보아야겠다 !

    - 피어세션 때 벡터의 내적과 유사도, 그리고 선형대수를 공부해야 하는 이유에 대해서 두런두런 이야기를 나눠보았다. (의견을 하나씩 정리해올려봐야지..)

     

     

    # 231115 기본과제 1 마무리 후 4강, 5강 수강 두런두런

    학습 정리 🤭

     

    [ 과제하며 정리 ]

    - 파이썬 클래스에 setattr 을 사용하여 함수나 속성 등의 객체를 추가해줄 수 있음. 단, 함수를 추가할 때에는, 자기자신을 의미하는 self를 전달해야하므로, partial(func, obj) 를 사용하여 추가해주어야 함.
    - PyTorch 에서는 expr_repr 이라는 함수가 이미 있으므로 동일한 이름으로 함수를 추가해주면 오버라이딩이 되는 듯함. 단, 이는 해당 객체에만 제한적으로 적용되며, 다른 객체나 클래스에서는 사용 불가. ❣️ 클래스로 객체를 만들고, 클래스에 함수를 추가 정의하면, 객체들에도 알아서 그 메서드가 할당된다는 신기한 사실도 알게됨 ❣️

    - 딥러닝 모델은 층의 반복으로 구성되어 있다.
    - 토치에서 층은 torch.nn.Module을 상속하여 생성할 수 있다. 이 때는 주로 파라미터와 forward를 정의하고, 필요한 경우 backward에 직접 미분식을 작성할 수도 있다. 그리고 대체로 층은 우리가 직접 구현하기 보다는 미리 구현된 층 클래스들 Linear 등을 사용하는 것이 일반적이다.
    - nn.Parameter는 nn.Module 내에 선언되면 자동으로 require_grad=True 가 되는 Tensor 의 자식 클래스이며, 모듈에서 자동미분이 지원되므로 가중치 등 학습할 대상들은 Parameter 로 선언한다.
    - optimizer로는 GD 외에 다른 모듈도 지원하며, optimizer를 사용할 때에는 zero_grad()를 사용해 매 학습마다 초기화해주고, loss.backward() 이후에 optimizer.step()을 통해서 가중치를 미분값으로 업데이트 해준다.

    배운점 📚

    케라스로 구현할 때만 해도 벡터의 차원 등을 꼼꼼하게 따져보지 않고 끼워맞추기 식으로 했는데, 이렇게 토치의 로우 레벨로 직접 구현해보니 디버깅 측면에서 많이 도움될 것 같다는 생각이 들었다. 어디서 왜, 무엇때문에 오류가 났는지 파악하기 더 쉬울 듯하다.

     

    # 231116 6, 7강 듣고 기본과제 2

     

    학습 정리 🤭

    [ print(Dataset.__doc__) 의 결과로 얻은 것 ]
    - 데이터셋은 키와 데이터 샘플들을 매핑하는 추상 클래스. 
    - 키 하나를 받아 데이터 샘플을 반환하는 `__getitem__` 을 무조건 오버라이트해야 함.
    - `__len__` 도 선택적으로 오버라이트하면 됨. 
    - 또 `__getitems__` 도 배치 샘플 로딩의 속도를 높이기 위해 구현해두면 좋음.
    - 하지만 데이터셋에는 데이터가 들어있어야 하므로, 데이터를 세팅하는 생성자 또한 필수불가결함.
    - 따라서 생성자, len, getitem은 필요하다.

    [ `CustomDataset` 을 만들어본 결과 ]
    - init, len, getitem 필수
    - iter는 반복 가능한 객체에서 반복자인 iterator를 생성하는 내장함수이며, `__next__`를 사용하여 컨테이너 요소에 차례대로 접근 가능하게 함. 이러면 for 룹 없이도 요소를 하나씩 가져올 수 있음.
    - Dataloader로 묶어서 데이터로더를 iteration하면, batch 크기에 따라 저절로 getitem에서 구현한 사전에서 text, label 이 list 형태로 나오게 됨.
    - @property 는 마치 getter의 역할을 하는 메서드로, obj.attribute 에서 self.attribute 가 없어도 @property를 통해 self._attribute를 리턴하도록 구현해둔다면 getter를 실행하는 것과 같이 반환됨. 주로, 캡슐화된 속성에 대한 getter 대신 사용되는 듯함. @attribute.setter 이렇게 데코레이터를 걸어주고 동일한 이름 그러니까 def attribute를 통해 함수를 선언하면, obj.attribute = another_value 를 입력하였을 때에 캡슐화된 속성의 값을 변경하는 역할을 할 수 있는 것. 이렇게 돌아왔지만 아직도 모르는 게 있다 !!

     

    [ Pytorch의 Dataset ]
    - torch.utils.data: 데이터셋 표준 정의, 자르고 섞는데 쓰는 도구가 들어있음. 대표적으로 Dataset, Dataloader가 있고 데이터셋은 모델 학습을 위한 데이터셋의 표준을 정의, 로더는 학습에 필요한 데이터를 로딩하며, Dataset 을 상속하는 파생 클래스의 인스턴스를 입력으로 받음.
    - torchvision or torchtext.dataset: 위 데이터셋을 상속하며, MNIST, CIFAR-10, IMDb, AG_NEWS 같은 데이터 제공.
    - torchvision.transforms: 이미지 데이터 변환 필터 포함. 크기 조절, 잘라내기, 밝기, 수정 등.
    - torchvision.utils: 데이터 저장. 시각화 도구 !

    [ Dataset ]
    - 데이터셋의 경우 map-style 로 되어있는 데이터일 때만 가능함.
    - init에서는 데이터 위치, 파일명과 같은 초기화 작업. csv, xml은 이 때 불러옴.
    - len은 최대 요소수 반환. 인덱스가 적절 범위인지 확인하는 데 사용.
    - getitem 메서드. 원본 데이터를 가져와 전처리, 증강하는 데 사용.
    - 그 외에도 label 가져오는 메서드 등 정의해도 됨.

    [ Iris Flower Dataset ]
    - 1936년 통계학자 Fisher가 소개한 데이터셋. from UCI ml repo
    - 붓꽃의 세 종류마다 50개씩 샘플. 총 150개.
    - 꽃받침(sepal), 꽃잎(petal), 길이, 너비 4개의 특성이 포함.
    - sklearn의 load_iris를 통해 데이터를 불러온 것 때문인지는 모르겠지만, 데이터프레임을 호출하였을 시, 그래프로도 제공이 됨.

    [ DatasetLoader ]
    - shuffle과 sampler의 차이점은? shuffle은 배치크기만큼 무작위로 뽑아 전달하는 것이고, sampler는 정해준 sampler 인스턴스의 룰(`__iter__`)을 데이터를 반환해준다는 차이가 있음.
    - `collate_fn`: map-style 데이터셋에서 샘플 리스트를 배치 단위로 바꾸기 위해 필요한 기능. 데이터 사이즈를 맞추기 위해 자주 사용. collate란 함께 합치다 라는 뜻. 뭐.. 대충 length 맞추는 건 알겠는데, 그건 오히려 transform으로도 할 수 있는 것 아닌가?
    - pin_memory 이건 아직도 잘 모르겠다.
    - drop_last: 길이가 다른 마지막 배치의 데이터를 가져오지 않는 것. loss 구하는 데에 추가 노력이 필요한 경우가 있어 빼도 됨. 길이가 같으면 리턴, 다르면 drop함.

    [ transform ]
    - torchvision은 이미지를 항상 PIL로 받아와야 함.
    - Resize, RandomRotation, RandomCrop. RandomHorizontalFlip(p=0.5) 좌우반전, RandomVerticalFlip 상하반전
    - torchvision.transforms.Compose는 위 함수들을 하나로 묶어주는 역할을 함
    - imgaug라는 라이브러리를 활용하면 바운딩박스나 anotation 을 같이 옮겨주는 것도 가능.

     

    [ 데이터셋 ]
    - MNIST: 이미지를 numpy로 변환한 뒤 pd.DataFrame에 넣어 색다르게 보여줄 수도 있음.
    - CIFAR-10
       - torchvision.transforms.Compose([다양한인스턴스들])을 넣어 데이터셋 transform 인자로 전달 가능.
       - CIFAR10에는 동물과 교통수단 10개에 대한 32x32 이미지가 있었음.
       - torchvision.datasets.CIFAR10() 을 가져올 때에는 root, download, transforms 정도를 넣어줘야 함.

    - AG_NEWS
       - 백만개 넘는 뉴스 기사 데이터
       - vocab은 `torchtext.data.utils.get_tokenizer('basic_english')`을 통해 얻은 토크나이저로 잘라 결과를 Counter 에 넣고 그 Counter를 전달하여 생성함. torchtext.vocab.vocab을 사용할 수 있음. 그러나, 텍스트 데이터 전처리 시에는 허깅페이스를 많이 사용할 듯.

     

    배운점 📚

    - 여러 종류의 데이터를 읽어 Dataset과 DataLoader를 직접 구현해 본 경험이 매우 인상적. 다른 어떤 게 와도 할 수 있을 것 같은 느낌?

    - 딱 2-3개월 전에 HuggingFace 학습을 위해 PyTorch Dataset을 만드는 경험을 했는데, 뭣도 모르고 클론 코딩했을 때는 다음에 또 하라고 해도 못할 것 같은 느낌이었으나, 지금은 뭐든 해보고 싶어 안달이...😖

     

    # 231117 많은 이벤트, 강의 몰아듣기, 새로운 분들과 인사!

    학습 정리 🤭

    - MultiGPU 학습은 모델을 잘라 학습하는 방법과 데이터를 잘라 학습하는 방법 두 가지가 있음. 모델을 자른다는 것은 전반적으로  Alexnet을 떠올리면 되는데, 현재는 이보다 훨씬 효율적인 방법을 쓴다고... 데이터를 잘라 학습하는 방법은 토치로 구현 시에 DataParallel과 DistributedDataParallel이 있고, 전자는 멀티 쓰레딩, 후자는 멀티 프로세싱으로 구현된 것. 파이썬은 Global Interpreter Lock 이라고 파이썬 객체에 한 번에 하나의 쓰레드만 접근하는 제한이 있어 Multi-GPU를 사용하는 경우 후자인 멀티프로세싱 기법을 활용하는 것이 더 권장된다고 함.

    - Multi-node란 컴퓨터 개수가 2개 이상인 것, Multi-GPU는 컴퓨터 관계 없이 GPU 개수가 2개 이상인 것. 대부분 한 대의 컴퓨터에 GPU가 최대 8개 정도 연결 가능함. Single Node Multi GPU 환경은 나도 회사에서 경험해본 기억이 있으나, Multi-Node Multi-GPU 환경은 현업에서도 경험하기 드물다고 함. 예전에 뭣도 모르고 MLOps 할거다 라면서 Kubernetes, Kubeflow 에 대해 뛰어든 적이 있는데, 이런 툴은 진짜로 Multi-node 환경에서나 쓸 법한 것...이었던 것....

     

    배운점 📚

    - 이번주에는 변성윤 마스터님의 두런두런 시간이 있었는데, 잠시 시간을 가지고 나아가기 위한 준비를 하는 나의 이 시간을 Gap Year라는 멋진 말과, 마스터님의 훌륭한 성과로 공유해주셔서 감동적이고 위로가 됐었다..🤓

    - 최성철 마스터님의 사회, 문화, 경제를 포괄한 재치만점 클래스도 나와 세상이 긴밀하게 연결되어 있고, 이 세상에서 내가 할 수 있는 일은 치킨집 말고도 있다..!! 라는 것을 마지막에는 깨닫게 되어 재미지고 에너지를 얻는 시간이 되었다!

    - 스페셜 세션 덕에 동일 과정 내 다른 캠퍼들과 인사하고 이야기 나눌 수 있어 새롭고 기분 좋은 시간이었다.

    - 급히 들은 감이 없지 않아 있지만, 심화 과제도 끝내고, 강의도 완강한 보람차고 뿌듯한 하루였다 🥰


    2주차 총평 🤔

    인간은 적응의 동물 🦒🦓 벌써 이 라이프에 적응해버렸다. 적응은 했지만 마냥 편안한 시점은 아니기에 아직까지는 루틴을 지켜보는 게 그리 힘들지는 않았다. 이번 주는 그야말로, 개념보다는 코드와 툴에 집중한 한 주였는데, 지난 주보다 덜 조금하고, 뿌듯한 시간이었다. 현업에서는 뭐가 그리 급했는지, 코드 한 줄 한 줄 뜯어보지 못하고 스륵 읽고, 아 이거면 되겠네. 주먹구구식으로 달려왔는데, 내가 나 스스로를 조절하며 한 글자씩 읽고, 이해하며 내려가는 순간 매우 소중하고 감격스러웠다. 앞으로도 이 마음 잃지 말고 5개월을 달려봐야지!! 한 김에 칭찬 타임을 좀 더 가지면, 이번 주에는 부끄러움은 살짝 내려두고, 모르는 것을 팀원들과 전체 채널에서 약 70% 펼쳐보았다. 멍청한 질문은 없다고 했으니까, 이것도 매우 잘한 일이라고 생각한다. 그럼 다음주도 화이팅 🏋️‍♂️

     

     

    반응형