ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 데이터 분석_파이토치 : Pytorch2
    DATA_STUDY 2024. 1. 22. 15:33

    파이토치 (상편)   https://datawithu.tistory.com/58 

     

    데이터 분석_라이브러리_함수_모음_2탄 : Pytorch1

    해당 자료는 이수안 컴퓨터 연구소의 유튜브에 올라와있는 자료입니다. ! 유튜브에 이수안 컴퓨터 연구소 검색하고 보세요!. 자료 좋아요!! 문제가 있을 시에 알려주시면, 빛 삭제 혹은 수정하겠

    datawithu.tistory.com


    파이토치(하편)

    모델 정의

    nn.Module 상속 클래스 정의

    • nn.Module을 상속받는 클래스 정의
    • __init__(): 모델에서 사용될 모듈과 활성화 함수 등을 정의
    • forward(): 모델에서 실행되어야 하는 연산을 정의
      • 위의 init와 forward가 둘다 꼭 있어야합니다 !
    # 단순한 Linear 클래스 만들기
    class Model(nn.Module):                    # 모듈 받기
        def __init__(self, inputs):
            super(Model, self).__init__()      #모델 상속
            self.layer = nn.Linear(inputs, 1 ) # 레이어  정의
            self.activation = nn.Sigmoid()    # 활성 함수 정의
    
        def forward(self, x):          # 정의된 레이와/활수함수가 어떻게 연산이 되는지
            x = self.layer()
            x = self.activation(x)
            return x
    model = Model(1)
    print(list(model.children())) # 계층 구성 보기
    # 리니어와, 시그모이드 계층이 들어가 있음
    print('----')
    print(list(model.modules()))

    nn.Sequential을 이용한 신경망 정의

    • nn.Sequential 객체로 그 안에 각 모듈을 순차적으로 실행
    • __init__()에서 사용할 네트워크 모델들을 nn.Sequential로 정의 가능
    • forward()에서 실행되어야 할 계산을 가독성 높게 작성 가능
    class Model(nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            # 레이어 1번
            self.layer1 = nn.Sequential(
                nn.Conv2d(in_channels=3, out_channels=64, kernel_size=5),
                nn.ReLU(inplace=True), #내부적으로 알아서
                nn.MaxPool2d(2)
            )
            # 레이어 2번
            self.layer2 = nn.Sequential(
                nn.Conv2d(in_channels=64, out_channels=30, kernel_size=5),
                nn.ReLU(inplace=True), #내부적으로 알아서
                nn.MaxPool2d(2)
            )
    
            # 레이어 3번
            self.layer3 = nn.Sequential(
                nn.Linear(in_features=30*5*5, out_features=10, bias=True),
                nn.ReLU(inplace=True) #내부적으로 알아서
            )
    
            def forward(self, x) :
                x = self.layer1(x)
                x = self.layer2(x) # 레이어 3번은 linear레이어이므로 이전에 Flatten작업이 필요함
                x = x.view(x.shape[0], -1 ) #첫번째것 기준[0]으로 나머지는 알아서(-1의 의미)
                x = self.layer3(x)  #레이어 3번 `
                return x

    클래스 확인하기 

    #클래스 확인하기
    model = Model()
    print(list(model.children()))
    print(list(model.modules()))

    파이토치 사전학습 모델


    모델 파라미터

     

    손실 함수(Loss function)

    • 예측 값과 실제 값 사이의 오차 측정
    • 학습이 진행되면서 해당 과정이 얼마나 잘 되고 있는지 나타내는 지표
    • 모델이 훈련되는 동안 최소화될 값으로 주어진 문제에 대한 성공 지표
    • 손실 함수에 따른 결과를 통해 학습 파라미터를 조정
    • 최적화 이론에서 최소화 하고자 하는 함수
    • 미분 가능한 함수 사용
    • 파이토치의 주요 손실 함수
      • torch.nn.BCELoss: 이진 분류를 위해 사용
      • torch.nn.CrossEntropyLoss: 다중 클래스 분류를 위해 사용
      • torch.nn.MSELoss: 회귀 모델에서 사용
    criterion = nn.MSELoss()
    criterion = nn.CrossEntropyLoss()

    옵티마이저(Optimizer)

    • 손실 함수를 기반으로 모델이 어떻게 업데이트되어야 하는지 결정 (특정 종류의 확률적 경사 하강법 구현)
    • optimizer는 step()을 통해 전달받은 파라미터를 모델 업데이트
    • 모든 옵티마이저의 기본으로 torch.optim.Optimizer(params, defaults) 클래스 사용
    • zero_grad()를 이용해 옵티마이저에 사용된 파라미터들의 기울기를 0으로 설정
    • torch.optim.lr_scheduler를 이용해 에포크(epochs)에 따라 학습률(learning rate) 조절
    • 파이토치의 주요 옵티마이저: optim.Adadelta, optim.Adagrad, optim.Adam, optim.RMSprop, optim.SGD

     

    학습률 스케줄러(Learning rate scheduler)

    • 학습시 특정 조건에 따라 학습률을 조정하여 최적화 진행
    • 일정 횟수 이상이 되면 학습률을 감소(decay)시키거나 전역 최소점(global minimum) 근처에 가면 학습률을 줄이는 등
    • 파이토치의 학습률 스케줄러 종류
      • optim.lr_scheduler.LambdaLR: 람다(lambda) 함수를 이용해 그 결과를 학습률로 설정
      • optim.lr_scheduler.StepLR: 단계(step)마다 학습률을 감마(gamma) 비율만큼 감소
      • optim.lr_scheduler.MultiStepLR: StepLR과 비슷하지만 특정 단계가 아니라 지정된 에포크에만 감마 비율로 감소
      • optim.lr_scheduler.ExponentialLR: 에포크마다 이전 학습률에 감마만큼 곱함
      • optim.lr_scheduler.CosineAnnealingLR: 학습률을 코사인(cosine) 함수의 형태처럼 변화시켜 학습률일 커지기도 하고 작아지기도 함
      • optim.lr_scheduler.ReduceLROnPlateau: 학습이 잘되는지 아닌지에 따라 동적으로 학습률 변화

     

    지표(Metrics)

    • 모델의 학습과 테스트 단계를 모니터링
    • 정확도는 몇인지 계선은 되고 있는지
    !pip install torchmetrics
    
    import torchmetrics
    
    preds = torch.randn(10,5).softmax(dim = -1) #예측값
    target = torch.randint(5, (10, )) #실제값
    print(preds, target )
    
    acc = torchmetrics.functional.accuracy(preds, target, task="multiclass", num_classes=5) #정확도
    print(acc)
    metric = torchmetrics.Accuracy(task='multiclass',num_classes=5)
    n_batches = 10
    for i in range(n_batches):
        preds = torch.randn(10, 5).softmax(dim=-1)
        target = torch.randint(5, (10,))
    
        acc = metric(preds, target )
        print(acc)
    
    acc = metric.compute()
    print(acc)

    선형 회귀 모델

    데이터 생성

    x = torch.rand(200, 1) * 10
    y = x + 3 * torch.randn(200,1)
    plt.scatter(x.numpy(), y.numpy())
    
    plt.ylabel('y')
    plt.xlabel('x')
    plt.grid()
    plt.show()
    #비교적 선형 스러운 데이터를 만들었음

    모델 정의 및 파라미터

    class LinearRegressionModel(nn.Module) :
        def __init__(self):
            super(LinearRegressionModel, self).__init__()
            self.linear = nn.Linear(in_features=1, out_features=1)
    
        def forward(self, x):
            pred = self.linear(x)
            return pred

     

    model = LinearRegressionModel()
    print(model)
    print(list(model.parameters()))

    # 현재 초기 파라미터값을 확인

    #현재 초기 파라미터값을 확인
    weight, bias = model.parameters()
    
    w1, b1 = weight[0][0].item(), bias[0].item() #값 뽑기
    x1 = np.array([-30, 30]) #범위 지정
    y1 = w1 * x1 + b1  # y = wx + b 인 기본적인 리니어모델
    
    plt.plot(x1, y1,'r') # 초기 값을 빨간색으로 표현
    plt.scatter(x,y)
    plt.grid()
    plt.show()

    손실 함수 및 옵티마이저

    #학습을 하기 위한 손실 함수 정의하기
    import torch.optim as optim
    
    criterion = nn.MSELoss()
    optimizer = optim.SGD(model.parameters(), lr=0.001)

    모델 학습

    epochs = 100
    losses = []
    
    for epoch in range(epochs):
        optimizer.zero_grad() # 초기 기울값은 0으로 초기
    
        y_pred = model(x) # 모델이 예측하는 prediction값
        loss = criterion(y_pred, y) #모델 예측값과 실제값의 차이
        losses.append(loss.item())
        loss.backward() # 예측한 것에 자동미분 + 업데이트
    
        optimizer.step()

    Loss값 확인

    # loss 값확인
    plt.plot(range(epochs), losses)
    plt.ylabel('Loss')
    plt.xlabel('Epochs')
    plt.show() # 100번 돌린값 확인

     학습 결과 확인 : 파라미터 

    #학습후의 결과값을 확인해보자
    weight, bias = model.parameters()
    
    w1, b1 = weight[0][0].item(), bias[0].item() #값 뽑기
    x1 = np.array([-30, 30]) #범위 지정
    y1 = w1 * x1 + b1  # y = wx + b 인 기본적인 리니어모델
    
    plt.plot(x1, y1,'r') # 초기 값을 빨간색으로 표현
    plt.scatter(x,y)
    plt.grid()
    plt.show()
Designed by Tistory.