본문 바로가기
대학원 시험 공부

데이터분석 프로젝트 (파이썬 Covid-19 사진 학습(분류) 2)

by code2772 2023. 3. 27.

[ 목차 ]

    728x90
    반응형

    5. 데이터 로더 구현하기

    def build_dataloader(train_data_dir, val_data_dir):
        dataloaders = {}
        train_dset = Chest_dataset(train_data_dir, transformer)
        # {'train': 데이터...}
        dataloaders['train'] = DataLoader(train_dset, batch_size=4, shuffle=True, drop_last=True)
         # 트레인 데이터를 4개 씩 섞고 ,drop_last=True 마지막거를 버려라 
        # {'train' : 데이터...} 담긴 모습
        # 각각의 데이터의 특징(웨이트)을 분류하기 위해 4개로 분류하였고 한번에 전부를 돌리는것보단 조금씩 분석을 하면
        # 얼마만큼 틀렸거나 최적의 경로를 더 빨리 알 수 있기 때문에 적은 수인 4개 정도로 데이터를 분류하는것이 좋다.
        # 251개를 한번에 돌리면 시간이 오래걸리고 반복시에도 시간 문제가 발생한다.
        
        val_dset = Chest_dataset(val_data_dir, transformer)
        dataloaders['val'] = DataLoader(val_dset, batch_size=1, shuffle=False, drop_last=False)
        
        return dataloaders

     

         # 트레인 데이터를 4개 씩 섞고 ,drop_last=True 마지막거를 버려라 
        # {'train' : 데이터...} 담긴 모습
        # 각각의 데이터의 특징(웨이트)을 분류하기 위해 4개로 분류하였고 한번에 전부를 돌리는것보단 조금씩 분석을 하면
        # 얼마만큼 틀렸거나 최적의 경로를 더 빨리 알 수 있기 때문에 적은 수인 4개 정도로 데이터를 분류하는것이 좋다.
        # 251개를 한번에 돌리면 시간이 오래걸리고 반복시에도 시간 문제가 발생한다.
     

    train_data_dir = './Covid19-dataset/train/' # 학습 데이타
    val_data_dir = './Covid19-dataset/test/' # 테스트 데이타
    dataloaders = build_dataloader(train_data_dir, val_data_dir)
    
    
    
    
    for i, d in enumerate(dataloaders['train']): # 반복 인덱스 값과 데이터 값을 출력을 해보자
        print(i, d)
        if i == 0:
            break
            
            # 출력 결과 한번 반복을 돌경우 4개로 나눴기 때문데 4개의 이미지가 있다.
            # target을 최하단부에 보면 섞인 타겟이 4개인것을 알 수 있다.

    ✔ 결과

    0 {'image': tensor([[[[-0.8308, -0.8916, -0.8677,  ..., -0.6797, -0.6646, -0.6471],
              [-0.8873, -0.8942, -0.9002,  ..., -0.6770, -0.6627, -0.6460],
              [-0.8754, -0.9074, -0.9250,  ..., -0.6893, -0.6627, -0.6432],
              ...,
              [-0.8985, -0.8763, -0.8768,  ..., -0.8388, -0.7755, -0.7307],
              [-0.8009, -0.8575, -0.8137,  ..., -0.8462, -0.9196, -0.7088],
              [-0.7368, -0.7897, -0.8608,  ..., -0.8182, -0.8737, -0.7346]],
    
             [[-0.8308, -0.8916, -0.8677,  ..., -0.6797, -0.6646, -0.6471],
              [-0.8873, -0.8942, -0.9002,  ..., -0.6770, -0.6627, -0.6460],
              [-0.8754, -0.9074, -0.9250,  ..., -0.6893, -0.6627, -0.6432],
              ...,
              [-0.8985, -0.8763, -0.8768,  ..., -0.8388, -0.7755, -0.7307],
              [-0.8009, -0.8575, -0.8137,  ..., -0.8462, -0.9196, -0.7088],
              [-0.7368, -0.7897, -0.8608,  ..., -0.8182, -0.8737, -0.7346]],
    
             [[-0.8308, -0.8916, -0.8677,  ..., -0.6797, -0.6646, -0.6471],
              [-0.8873, -0.8942, -0.9002,  ..., -0.6770, -0.6627, -0.6460],
              [-0.8754, -0.9074, -0.9250,  ..., -0.6893, -0.6627, -0.6432],
              ...,
              [-0.8985, -0.8763, -0.8768,  ..., -0.8388, -0.7755, -0.7307],
              [-0.8009, -0.8575, -0.8137,  ..., -0.8462, -0.9196, -0.7088],
              [-0.7368, -0.7897, -0.8608,  ..., -0.8182, -0.8737, -0.7346]]],
    
    
            [[[-1.0000, -1.0000, -1.0000,  ...,  0.9282,  0.5004, -0.9459],
              [-1.0000, -1.0000, -1.0000,  ..., -0.9413, -0.5848, -0.9731],
              [-1.0000, -1.0000, -1.0000,  ...,  0.9393, -0.5843, -0.9447],
              ...,
              [-0.9922, -1.0000, -0.9997,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9870,  0.5032,  0.9987,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9613, -0.6391, -0.9975,  ..., -1.0000, -1.0000, -1.0000]],
    
             [[-1.0000, -1.0000, -1.0000,  ...,  0.9282,  0.5004, -0.9459],
              [-1.0000, -1.0000, -1.0000,  ..., -0.9413, -0.5848, -0.9731],
              [-1.0000, -1.0000, -1.0000,  ...,  0.9393, -0.5843, -0.9447],
              ...,
              [-0.9922, -1.0000, -0.9997,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9870,  0.5032,  0.9987,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9613, -0.6391, -0.9975,  ..., -1.0000, -1.0000, -1.0000]],
    
             [[-1.0000, -1.0000, -1.0000,  ...,  0.9282,  0.5004, -0.9459],
              [-1.0000, -1.0000, -1.0000,  ..., -0.9413, -0.5848, -0.9731],
              [-1.0000, -1.0000, -1.0000,  ...,  0.9393, -0.5843, -0.9447],
              ...,
              [-0.9922, -1.0000, -0.9997,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9870,  0.5032,  0.9987,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9613, -0.6391, -0.9975,  ..., -1.0000, -1.0000, -1.0000]]],
    
    
            [[[-0.5189, -0.5431, -0.5126,  ...,  0.9880, -0.9370, -0.9115],
              [-0.6902, -0.6732, -0.6734,  ..., -0.9116,  0.1379, -0.9497],
              [-0.6745, -0.6796, -0.6734,  ..., -0.9188, -0.8106, -0.8681],
              ...,
              [-0.9923, -0.9955, -1.0000,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9619,  0.0067,  0.9732,  ..., -1.0000, -0.9765, -0.9882],
              [ 0.2605,  0.9916, -0.9529,  ..., -1.0000, -0.9609,  0.2557]],
    
             [[-0.5189, -0.5431, -0.5126,  ...,  0.9880, -0.9370, -0.9115],
              [-0.6902, -0.6732, -0.6734,  ..., -0.9116,  0.1379, -0.9497],
              [-0.6745, -0.6796, -0.6734,  ..., -0.9188, -0.8106, -0.8681],
              ...,
              [-0.9923, -0.9955, -1.0000,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9619,  0.0067,  0.9732,  ..., -1.0000, -0.9765, -0.9882],
              [ 0.2605,  0.9916, -0.9529,  ..., -1.0000, -0.9609,  0.2557]],
    
             [[-0.5189, -0.5431, -0.5126,  ...,  0.9880, -0.9370, -0.9115],
              [-0.6902, -0.6732, -0.6734,  ..., -0.9116,  0.1379, -0.9497],
              [-0.6745, -0.6796, -0.6734,  ..., -0.9188, -0.8106, -0.8681],
              ...,
              [-0.9923, -0.9955, -1.0000,  ..., -1.0000, -1.0000, -1.0000],
              [-0.9619,  0.0067,  0.9732,  ..., -1.0000, -0.9765, -0.9882],
              [ 0.2605,  0.9916, -0.9529,  ..., -1.0000, -0.9609,  0.2557]]],
    
    
            [[[-0.7783, -0.7805, -0.7696,  ..., -0.6707, -0.5907, -0.6562],
              [-0.5511, -0.6574, -0.7635,  ..., -0.6582, -0.6038, -0.6745],
              [-0.2294, -0.2396, -0.3251,  ..., -0.7919, -0.7370, -0.7647],
              ...,
              [-0.9373, -0.9578, -0.9716,  ..., -0.9294, -0.9294, -0.9137],
              [-0.9460, -0.9205, -0.9686,  ..., -0.9294, -0.8933, -0.8900],
              [ 0.2520, -0.9582, -0.9716,  ..., -0.9294, -0.9289,  0.2413]],
    
             [[-0.7783, -0.7805, -0.7696,  ..., -0.6707, -0.5907, -0.6562],
              [-0.5511, -0.6574, -0.7635,  ..., -0.6582, -0.6038, -0.6745],
              [-0.2294, -0.2396, -0.3251,  ..., -0.7919, -0.7370, -0.7647],
              ...,
              [-0.9373, -0.9578, -0.9716,  ..., -0.9294, -0.9294, -0.9137],
              [-0.9460, -0.9205, -0.9686,  ..., -0.9294, -0.8933, -0.8900],
              [ 0.2520, -0.9582, -0.9716,  ..., -0.9294, -0.9289,  0.2413]],
    
             [[-0.7783, -0.7805, -0.7696,  ..., -0.6707, -0.5907, -0.6562],
              [-0.5511, -0.6574, -0.7635,  ..., -0.6582, -0.6038, -0.6745],
              [-0.2294, -0.2396, -0.3251,  ..., -0.7919, -0.7370, -0.7647],
              ...,
              [-0.9373, -0.9578, -0.9716,  ..., -0.9294, -0.9294, -0.9137],
              [-0.9460, -0.9205, -0.9686,  ..., -0.9294, -0.8933, -0.8900],
              [ 0.2520, -0.9582, -0.9716,  ..., -0.9294, -0.9289,  0.2413]]]]), 'target': tensor([[0],
            [2],
            [2],
            [2]])}

    # 이제 어떤 모델을 선택해서 데이타를 넣어볼 것인가?!
    # 모델을 직접 만들기도 하지만 기존 공개된 모델을 활용을 많이 한다.
    # 여러 모델을 여러번 돌려보고 성능이 괜찮은걸 사용한다...
     

    6. VGG19(classification) 모델 불러오기

     

    # pretrained=True: 미리 학습된 weight들을 가지고 옮
    # torchvision 의 models 사용...
    model = models.vgg19(pretrained=True)
    
    
    # pytorch 모델을 summary 해주는 모듈
    !pip install torchsummary
    
    
    from torchsummary import summary
    # 세이프, 배치사이즈, 디바이스
    # param 가중치
    
    
    summary(model, (3, 224, 224), batch_size=1, device='cuda') # 채널, 세로, 가로, device: cuda or cpu

    7. CNN(Convolutional Neural Network)

    • 합성곱 인공 신경망
    • 전통적인 뉴럴 네트워크 컨볼루셔널 계층을 붙인 형태
    • 컨볼루셔널 계층을 통해서 입력 받은 이미지에 대한 특징(Feature)을 추출(전처리)하게 되고 추출한 특징을 기반으로 기존의 뉴럴 네트워크에 이용하여 분류

    7-1. CNN을 사용하는 이유

    • 영상을 분류할 때 DNN(Deep Neural Network)의 문제점
      • 일반적인 DNN은 1차원 형태의 데이터를 사용
      • 2차원의 형태의 이미지가 입력되는 경우, flatten 시켜서 한줄로 데이터를 넣음
      • 이미지의 공간적/지역적 정보가 손실됨
    • DNN의 문제점을 해결하기 위해 고안한 해결책 -> 이미지를 날것(raw input) 그대로 받음으로 공간적/지역적 정보를 유지

    7-2. 컨볼루셔널 레이어(Convolutional Layer)

    • 입력 데이터로 부터 특징을 추출하는 역할
    • 특징을 추출하는 필터(Filter)를 사용함(https://setosa.io/ev/image-kernels/)
    • 필터의 값을 비선형 값으로 바꿔주는 액티베이션(Activationi) 함수를 사용

    7-3. 풀링

    • Feature map의 사이즈를 줄이는 방법
    • 데이터의 크기를 줄이고 싶을 때 선택적으로 사용
    • max pooling: 사이즈를 점진적으로 줄이는 방법, 선명한 정보만 남겨서 판단과 학습이 쉬워지고 노이즈가 줄어듦

    7-4. 패딩(padding)

    • CNN 네트워크 특징중 여러 단계에 걸쳐서 계속 필터를 연속적으로 적용하면 필터 적용 후 결과값이 처음에 비해 작아지게 됨 -> 특징이 유실 될 수 있음
    • 충분히 특징이 추출되기 전에 결과 값이 작아지지 않도록 패딩 기법을 사용
    • 입력값 주위로 0을 넣어서 입력 값의 크기를 인위적으로 키워 결과값이 작아지는 것을 방지

    7-5. 스트라이드(Stride)

    • 필터를 적용하는 간격(예: 우측으로 한칸씩 아래로 한칸씩 적용)을 설정
    • 필터를 적용해서 얻어낸 결과를 Feature map 또는 activation map이라고 부름

    7-6. 드룹아웃 레이어(Dropout Layer)

    • 오버피팅을 막기 위한 방법
    • 뉴럴 네트워크가 학습중일때 랜덤하게 값을 발생하여 학습을 방해함으로 학습용 데이터에 결과가 치우치는 것을 방지함

    7-7. FC Layer(Fully Connected Layer)

    • 이미지를 분류/설명하기 위해 예측하는 구간

    8. 데이터에 맞게 모델 Head 부분을 수정하기

     
     
     
    def build_vgg19_based_model(device_name='cpu'):
        device = torch.device(device_name)
        model = models.vgg19(pretrained=True)
        model.avgpool = nn.AdaptiveAvgPool2d(output_size=(1, 1))
        model.classifier = nn.Sequential(
            nn.Flatten(),
            nn.Linear(512, 256),
            nn.ReLU(),
            nn.Linear(256, len(class_list)),
            nn.Softmax(dim=1)
        )
        return model.to(device)
        
        
        
        model = build_vgg19_based_model(device_name='cpu')
        
        
        
        
        summary(model, (3, 224, 224), batch_size=1, device='cuda')
     
    ✔ 결과
    ----------------------------------------------------------------
            Layer (type)               Output Shape         Param #
    ================================================================
                Conv2d-1          [1, 64, 224, 224]           1,792
                  ReLU-2          [1, 64, 224, 224]               0
                Conv2d-3          [1, 64, 224, 224]          36,928
                  ReLU-4          [1, 64, 224, 224]               0
             MaxPool2d-5          [1, 64, 112, 112]               0
                Conv2d-6         [1, 128, 112, 112]          73,856
                  ReLU-7         [1, 128, 112, 112]               0
                Conv2d-8         [1, 128, 112, 112]         147,584
                  ReLU-9         [1, 128, 112, 112]               0
            MaxPool2d-10           [1, 128, 56, 56]               0
               Conv2d-11           [1, 256, 56, 56]         295,168
                 ReLU-12           [1, 256, 56, 56]               0
               Conv2d-13           [1, 256, 56, 56]         590,080
                 ReLU-14           [1, 256, 56, 56]               0
               Conv2d-15           [1, 256, 56, 56]         590,080
                 ReLU-16           [1, 256, 56, 56]               0
               Conv2d-17           [1, 256, 56, 56]         590,080
                 ReLU-18           [1, 256, 56, 56]               0
            MaxPool2d-19           [1, 256, 28, 28]               0
               Conv2d-20           [1, 512, 28, 28]       1,180,160
                 ReLU-21           [1, 512, 28, 28]               0
               Conv2d-22           [1, 512, 28, 28]       2,359,808
                 ReLU-23           [1, 512, 28, 28]               0
               Conv2d-24           [1, 512, 28, 28]       2,359,808
                 ReLU-25           [1, 512, 28, 28]               0
               Conv2d-26           [1, 512, 28, 28]       2,359,808
                 ReLU-27           [1, 512, 28, 28]               0
            MaxPool2d-28           [1, 512, 14, 14]               0
               Conv2d-29           [1, 512, 14, 14]       2,359,808
                 ReLU-30           [1, 512, 14, 14]               0
               Conv2d-31           [1, 512, 14, 14]       2,359,808
                 ReLU-32           [1, 512, 14, 14]               0
               Conv2d-33           [1, 512, 14, 14]       2,359,808
                 ReLU-34           [1, 512, 14, 14]               0
               Conv2d-35           [1, 512, 14, 14]       2,359,808
                 ReLU-36           [1, 512, 14, 14]               0
            MaxPool2d-37             [1, 512, 7, 7]               0
    AdaptiveAvgPool2d-38             [1, 512, 1, 1]               0
              Flatten-39                   [1, 512]               0
               Linear-40                   [1, 256]         131,328
                 ReLU-41                   [1, 256]               0
               Linear-42                     [1, 3]             771
              Softmax-43                     [1, 3]               0
    ================================================================
    Total params: 20,156,483
    Trainable params: 20,156,483
    Non-trainable params: 0
    ----------------------------------------------------------------
    Input size (MB): 0.57
    Forward/backward pass size (MB): 238.31
    Params size (MB): 76.89
    Estimated Total Size (MB): 315.78
    ----------------------------------------------------------------
    

    9. 손실함수 불러오기

    • input x에 대한 예측값과 실제값 사이의 오차를 계산하는 함수
    • cost function: 모든 input dataset에 대하여 계산하는 함수
    loss_func = nn.CrossEntropyLoss(reduction='mean')
     
     
     

    10. Gradient 최적화 함수 불러오기

    optimizer = torch.optim.SGD(model.parameters(), lr=1E-3, momentum=0.9)

    10-1. 경사 하강법의 종류

    • 배치 경사 하강법
      • 가장 기본적인 경사 하강법으로 Vanilla Gradient Descent 라고 부름
      • 데이터셋 전체를 고려하여 손실함수를 계산
      • 한 번의 Epoch에 모든 파라미터 업데이터를 단 한번만 수행
      • Batch의 개수와 lteration은 1이고 Batch size는 전체 데이터의 갯수
      • 파라미터 업데이트할 때 전체 데이터셋을 고려하기 때문에 모델 학습시 많은 시간과 메모리가 필요하다는 단점
    • 확률적 경사 하강법(Stochastic Gradient Descent)
      • 배치 경사 하강법이 모델 학습시 많은 시간과 메모리가 필요하다는 단점을 개선하기 위해 제안된 기법
      • Batch size를 1로 설정하여 파라미터를 덥데이트하기 때문에 배치 경사 하강법보다 빠르고 적은 메모리로 학습이 진행
      • 중복 데이터를 뽑을 가능성이 있음
      • 파라미터 값의 업데이트 폭이 불안정
    • 미니 배치 경사 하강법
      • Batch size가 1도 아니고 전체 데이터 갯수도 아닌 경우
      • 배치 경사 하강법보다 모델 학습 속도가 빠르고, 확률적 경사 하강법보다 안정적인 장점이 있음
      • 일반적으로 Batch size를 2의 n제곱에 해당하는 값으로 설정

    10-2. 경사 하강법의 알고리즘

    • GD(Gradient Descent)
      • 모든 데이터를 사용하여 계산하는 방법으로 학습시간이 오래 걸림
    • SGD(Stochastic Gradient Descent)
      • 확률적 경사 하강법으로 모든 데이터에 대해 가중치를 조절하는 것이 아닌 랜덤으로 일부를 추출해서 가중치를 조절하는 방법
    • Momentum
      • 관성을 사용하는 방법으로 local minima를 해결하기 위해 고안
      • 이전의 방향을 기억하여 관성처럼 추가적인 이동을 하며 local minima 문제를 해결할 확률을 높임
    • Adagrad
      • 학습률과 관련된 옵티마이저로, Adagrad라는 방식은 변수의 업데이트가 잦을수록 학습률을 조정하는 방식
    • RMSprop
      • Adagrad은 학습률이 작아지는 문제가 발생
      • 위 문제를 해결하기 위해 만들어진 옵티마이저로, 기울기를 단순히 누적하는 것이 아닌 가중이동평균을 사용하여 최근의 기울기에 더 높은 가중치를 두는 방식을 적용한 방법
    • Adam(Adaptive Moment Estimation)
      • Momentum을 사용
      • RMSprop처럼 지수이동평균을 사용하며 학습률을 조정

    SGD와 Adam 두개를 최근 많이 사용한다...

    반응형