본문 바로가기

Hello MLop/DL

MLop_DL_손글씨 판단 예측

20221117

30일 차

 


이번에 할 예측은 손글씨 판단이다.

데이터는 torchvision의 datasets에서 MNIST를 가져왔다.

 


 

시각화를 도와줄 matplotlib.pyplotplt를 임포트 해주고

torchvision에서 MNIST, ToTensor 두 가지를 임포트 해준다.

 

학습용 데이터와 평가용 데이터로 분리해주는 과정은

각각의 변수에 MNIST(위치, 종류, 다운로드 여부, ToTensor로 변환)로 저장해준다.

 

그리고 샘플이미지는 pyplot을 이용해 3 X 3 형태로 출력시키는 코드를 입력하면?

위와 같은 MNIST에 저장된 손글씨 9개가 출력된다.

 

 


💡 DataLoader ?

 데이터셋을 불러온 뒤 필요에 따라 데이터셋을 순회(iterate)할 수 있다.

 

✔ 각 순회(iterate)는 # 각각 batch_size=64 의 특징(feature)과 정답(label)을 포함한다.

 

train_features(# train_loader) 와 train_labels(# test_loader) 의 묶음(batch)을 반환합니다. 

 

shuffle=True 로 지정했으므로, 모든 배치를 순회한 뒤 데이터가 섞인다.

 

우리의 목적은 어떤 글씨가 왔을때 이게  손글씨냐 아니냐를 판단해야한다.

그래서 가중치 또한 손글씨의 특징에 줄것이다.

 

그럼 모델에 손글씨의 특징들을 학습시켜 놓으면

다른 글씨가 들어왔을때 손글씨 특징이 있으면 손글씨로 분류할 것이고

없으면 버릴것이다.

 

위의  코드는 불러온 MNIST 데이터셋train_featurestrain_labels로 나눈것이다.

 

train_loader들은 32개씩 학습시킬것이고,  섞기 까지 할것이다.

test_loader 들은 시험이기에 가중치가 더해질 이유가 없다, 때문에 32개씩 학습만 시킨다.

 


모델을 학습 시키기 위해

pytorch신경망 nn을 임포트 해주고

오차역전파를 위해 Adam 또한 임포트 해준다.

 

그리고 최적화할시 epoch가 많으면 컴퓨터가 과부화될 수 있기 때문에

device 타입을 정해준다. # cuda = GPU, cpu = CPU

 


✨ 모델 정의

 

model은 Sequential로 만들어 줄것이며

nn.Linear(💡784, 64)

= 선형회귀방식으로 가중치를 주는 신경망.

= 즉, 우린 분류가 아니라 신경망의 출력()을 그대로 받겠다.

 

💡 784?

현재 MNIST에서 불러온 사진의 데이터는

28 # px * 28 # px * 1 # 흑백사진이기 때문에 채널이 1개  = 784

 

nn.ReLU() = 활성화 함수 렐루~

nn.Linear(64,64)

nn.ReLU()

nn.Linear(64,10)

 

model.to(device) # GPU or CPU

 


위의 코드를 출력하면?

 

설정한 모델의 정의가 나온다.

 


자 이제 학습률(learning rate)도 정의하고

Adam도 써서 가중치를 업데이트 해보자.

 


 

for문을 이용해 경사하강법을 진행하며

 

data = train_loader의 데이터

label = train_loader의 정답

 

optim.zero_grad() = 기울기를 초기화 시키고

 

 

💡 data = torch.reshape(data(-1,784)).to(device)

 

위의 코드를 해석하면

 

train_loader의 데이터torch타입으로 만들거야reshape해서  train_loader의 데이터(-1 # 개수를 상관하지 않겠다!,784) 모양으로

 

❗ 현 상황에서 우리는 배치가 32 이기 때문에사실상 32 * 28 *  28의 사이즈다.

 

.to(device) GPU와 CPU중 너가 사용한다고 한거

 

preds = model(data)

preds에 저장해줘~

 

loss라는 변수는

 

nn.CrossEntropyLoss() 라는 손실함수로  계산 할게

(preds, label.to(device)) predslabel = train_loader를 비교해서

 


💡 state_dict?

간단히 말해 각 계층을 매개변수 tensor로 매핑되는 Python 사전(dict) 객체이다.

 

쉽게 말하면 우리가 가장 중요시하는 가중치들이 다 tensor형태로 저장되어있다

 

그럼 model.load_state_dict(torch.load("MNIST.pth", map_location=device)) 코드는

모델가중치들을 불러왔다는 것이다. 어디로부터?

방금 저장한 MNIST.pth로부터 # MNIST.pth는 문자열이기 때문에 앞에 torch.load 필요

 

num_corr은 분류에 성공한 전체 개수를 저장하기 위해 = 0으로 저장해준다.

 

그럼 이제  모델에서 학습한 train데이터를 기반으로

test셋을 학습 시켜보자.

 

이미  최적의  가중치들이 나온것을 모델에 저장했기에

기울기를 계산하지 않는다. = 가중치를 주지 않는다. # 속도도 빨라진다

 

train셋을 학습했던것과 비슷하게 간다.

이미지를 백터로 배열 바꿔주고,

output 에 모델의 입력을 넣어주고

 

💡 preds = output.data.max(1)[1]

 

output은 모델의  예측값(기울기 + 데이터)이다.

 

데이터의 예측값 중에서💡 데이터의 현재 구조  = [[value1(사진1), 가중치][value2,가중치][value3, 가중치]·····] # 32개

 

그 중에서 max(최대값)를 뽑아라

 

(1) 💡 1차원의 방향으로

[1] 누가 제일 컸냐(max)가 필요하기 때문에 1번째 데이터

 

💡 1차원?

32개(배치 크기)의 0~9 (모델에서 마지막으로 분류된 10개의 텐서의 인덱스번호)까지의 확률 분포가 1차원에 존재함

 

corr이라는 변수에 label # 테스트 셋 preds.eq 같은 데이터의 합(.sum())을

.item() # tensor 형태로 저장해준다.

 

이제 num_corrcorr을 다 더해주고

정확도를 보기 위해 num_corr / test_data의 개수를 해준다.

 

 

 

'Hello MLop > DL' 카테고리의 다른 글

MLop_DL_ResNet 실습  (0) 2022.12.04
MLop_DL_CNN 실습  (0) 2022.11.30
MLop_DL_보스톤 집값 예측  (0) 2022.11.23
MLop_DL_사인함수 예측하기  (0) 2022.11.22
MLop_DL_Deep Learnig  (1) 2022.11.21