• 카테고리

    질문 & 답변
  • 세부 분야

    딥러닝 · 머신러닝

  • 해결 여부

    미해결

LSTM 평가 코드

22.07.22 16:01 작성 조회수 352

1

LSTM 평가를 위해

교재의 4-1 Neural Networks 상 평가 코드(아래와 같음)을 붙여넣기 해서 출력한 결과  [can't convert cuda:0 device type to numpy. Use Tensor.cpu() to copy the tensor to host memory.]라는 오류가 뜹니다. 조치방법이 어떻게 되는지 궁금합니다.

 

def evaluation(dataloader):
    
    predictions = torch.tensor([], dtype=torch.float) # 예측값을 저장하는 텐서
    actual = torch.tensor([], dtype=torch.float) # 실제값을 저장하는 텐서
        
    with torch.no_grad():
        model.eval() # 평가를 할 때에는 .eval() 반드시 사용해야 한다.
        for data in dataloader:
            inputs, values = data
            outputs = model(inputs)

            predictions = torch.cat((predictions, outputs), 0) # cat을 통해 예측값을 누적
            actual = torch.cat((actual, values), 0) # cat을 통해 실제값을 누적

    rmse = np.sqrt(mean_squared_error(predictions, actual)) # sklearn을 이용하여 RMSE 계산
    
    return rmse  

평가 시 .eval()을 사용해야 하는 이유
# 평가 시에는 온전한 모델로 평가를 해야하는데 .eval()이 아닌 .train()인 경우 드랍아웃이 활성화 되어 있다.
# 따라서 드랍아웃이나 배치 정규화 등과 같이 학습 시에만 사용하는 기술들을 평가 시에는 비활성화 해야만 한다.

 

train_rmse = evaluation(trainloader) # 학습 데이터의 RMSE
test_rmse = evaluation(testloader) # 시험 데이터의 RMSE

print("Train RMSE: ",train_rmse)
print("Test RMSE: ",test_rmse)

# 예시를 위한 단순 비교입니다. 실제 연구에서는 디테일한 비교가 필요합니다.
# 20번의 평가 결과의 평균으로 결과값을 산정 했습니다.
# 데이터를 무작위로 나누고 모델의 초기값도 random initial parameter를 사용했기 때문에 학습을 할 때 마다 결과가 다르게 나올 수 있습니다.
# 이 강의에서는 학습의 흐름(for문)과 모델(Regressor) 부분을 주의 깊게 보시면 됩니다.

답변 3

·

답변을 작성해보세요.

0

메시림님의 프로필

메시림

질문자

2022.07.25

추가질문 하나 더 있습니다.

 

R2를 추가적으로 확인하고자 아래와 같이 evaluation에 추가로 R2score를 아래와 같이 넣고  print 를 하면 ['numpy.float32' object is not callable ]이라는 오류메시지가 뜹니다.

어떤 부분이 잘못되었는지 지도 부탁드립니다.

 

def evaluation(dataloader):

 

predictions = torch.tensor([], dtype=torch.float).to(device)

actual = torch.tensor([], dtype=torch.float).to(device)

 

with torch.no_grad():

model.eval()

for data in dataloader:

inputs, values = data

outputs = model(inputs)


predictions = torch.cat((predictions, outputs), 0)

actual = torch.cat((actual, values), 0)


rmse = np.sqrt(mean_squared_error(predictions.cpu(), actual.cpu()))

R2 = R2score(predictions.cpu(), actual.cpu())

 

return rmse, R2

R2score 는 함수가 무엇인가요? 아니면 라이브러리를 어떤 것을 쓰셨나요?

메시림님의 프로필

메시림

질문자

2022.07.25

torchmetrics에서 R2score를 불러왔습니다.

 

 R2score에 값을 넣는게 아니라 아래 예시처럼 사용하시면 될 것 같아요. 자세한 것은 아래 링크 참고하세요!

r2score = R2Score() r2score(predictions, actual)

https://torchmetrics.readthedocs.io/en/stable/regression/r2_score.html 

 

메시림님의 프로필

메시림

질문자

2022.07.26

감사합니다. 질문이 더 있습니다. 

 

아래 코딩 관련해서,  prediction과 actual을 위에서 이미 정의하고 있는데 다시 cat을 통해 데이터를 누적하는 것이 의미가 있는 것인지 이해가 잘 되지 않습니다.(설명을 들어도 제가 이해를 잘 못하고 있어요)

 

좀 더 상세히 알려주시면 감사하겠습니다.

 

predictions = torch.tensor([], dtype=torch.float).to(device)

actual = torch.tensor([], dtype=torch.float).to(device)
 
----------------------------------------------
 
predictions = torch.cat((predictions, outputs), 0)

actual = torch.cat((actual, values), 0)

데이터가 배치 형태로 사용되기 때문에 한 번에 평가가 불가능 합니다. 따라서 전체 결과를 누적하여 한 번에 평가하기 위해 cat으로 결과값을 모은 뒤 평가를 진행한 것입니다. 강의에서는 데이터를 cat으로 모을 수 있다는 것도 보여드리기 위함도 의도 된 것인데 결과값 누적없이 에러만 계산할 시에는 각 배치마다의 에러 값만 계산하여 처리하셔도 됩니다!

0

메시림님의 프로필

메시림

질문자

2022.07.25

감사합니다.

 

추가적으로, 

아래와 같이 코멘트 된 부분이 있는데, random initial parameter를 사용한 부분이 어떤 부분인가요?

결과값을 고정시키기 위해서 어떤 paramater를 써야되는지도 궁금합니다.

 

# 데이터를 무작위로 나누고 모델의 초기값도 random initial parameter를 사용했기 때문에 학습을 할 때 마다 결과가 다르게 나올 수 있습니다.

모델 파라메터, 데이터 분할이 랜덤하게 적용되는데 학습마다 다르게 나오는 것은 당연한 현상이므로 문제 되지 않습니다. 결과값을 고정하려면 seed라는 것을 고정해주면 되는데 seed를 고정하여 실험하지는 않습니다. 나중에 논문을 쓰시게 되면 학습, 평가를 여러 번 해서 얻는 결과를 바탕으로 표준편차나 신뢰구간 정보까지 보여주시면 됩니다. 

0

안녕하세요!

 

4.1강의 코드는 CPU연산을 활용하였고 7.1강의 코드는 GPU연산을 사용하였습니다.

따라서 두 코드의 연산 종류가 맞지 않아 해당 오류가 발생하게 됩니다.

1. evaluation 함수 내의 prediction과 actual에 .to(device)를 붙여 GPU 가능 텐서로 만들어 주시면 됩니다.

2. 또한 gpu용 텐서는 numpy 변환이 되지 않습니다. 따라서 gpu용 텐서를 cpu용 텐서로 변환를 해주셔야 합니다.

따라서 rmse 부분에 사용되는 입력값들에 .cpu()을 붙여 cpu용 텐서로 변환하시면 됩니다!

아래는 관련 코드입니다.

def evaluation(dataloader):
 
predictions = torch.tensor([], dtype=torch.float).to(device)
actual = torch.tensor([], dtype=torch.float).to(device)
 
with torch.no_grad():
model.eval()
for data in dataloader:
inputs, values = data
outputs = model(inputs)

predictions = torch.cat((predictions, outputs), 0)
actual = torch.cat((actual, values), 0)

rmse = np.sqrt(mean_squared_error(predictions.cpu(), actual.cpu()))
 
return rmse

 

감사합니다.