Pytorch 를 사용 하여 모델 을 만 드 는 절차

원래 Tenorflow 만 사용 하 는 것 이 었 지만 TF 의 일부 Numpy 특성 은 지원 되 지 않 았 습 니 다.예 를 들 어 배열 사용 목록 을 자 르 기 때문에 Pytorch 로 전환 할 수 밖 에 없 었 습 니 다(pytorch 는 지원 합 니 다).다행히 Pytorch 는 손 에 넣 기 쉬 워 서 Numpy 의 특성 을 거의 완벽 하 게 복 제 했 습 니 다.(그러나 일부 특성 은 지원 하지 않 습 니 다)어쩐지 열 이 이렇게 빨리 올 라 가 더 라 니.
1  모델 정의
TF 와 비슷 하 게 Pytorch 도 부 류 를 계승 해 사용자 정의 모델 을 만 드 는 것 도 두 가지 방법 이다.TF 에 서 는init__()콜()과 Pytorch 에 서 는init__()와 forward().기능 이 유사 한데 모두 모델 내부 구 조 를 초기 화하 고 추 리 를 하 는 것 이다.다른 기능,예 를 들 어 loss 와 훈련 함 수 를 계산 하 는 것 도 그 안에 계승 할 수 있 습 니 다.물론 이것 은 선택 할 수 있 습 니 다.다음은 MNIST 의 손 글 씨 를 판별 하 는 데 모 를 만 들 고 먼저 모델 코드 를 드 리 겠 습 니 다.

import numpy as np
import matplotlib.pyplot as plt 
import torch 
from torch import nn,optim 
from torchsummary import summary 
from keras.datasets import mnist
from keras.utils import to_categorical
device = torch.device('cuda') #――――――1――――――
 
class ModelTest(nn.Module):
 def __init__(self,device):
  super().__init__() 
  self.layer1 = nn.Sequential(nn.Flatten(),nn.Linear(28*28,512),nn.ReLU())#――――――2――――――
  self.layer2 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) 
  self.layer3 = nn.Sequential(nn.Linear(512,512),nn.ReLU())
  self.layer4 = nn.Sequential(nn.Linear(512,10),nn.Softmax()) 

  self.to(device) #――――――3――――――
  self.opt = optim.SGD(self.parameters(),lr=0.01)#――――――4――――――
 def forward(self,inputs): #――――――5――――――
  x = self.layer1(inputs)
  x = self.layer2(x)
  x = self.layer3(x)
  x = self.layer4(x)
  return x 
 def get_loss(self,true_labels,predicts): 
  loss = -true_labels * torch.log(predicts) #――――――6――――――
  loss = torch.mean(loss)
  return loss
 def train(self,imgs,labels): 
  predicts = model(imgs) 
  loss = self.get_loss(labels,predicts)
  self.opt.zero_grad()#――――――7――――――
  loss.backward()#――――――8――――――
  self.opt.step()#――――――9――――――
model = ModelTest(device)
summary(model,(1,28,28),3,device='cuda') #――――――10――――――
\#1:장 치 를 가 져 와 서 뒤의 모델 과 변 수 를 편리 하 게 메모리 이전 할 수 있 습 니 다.장치 이름 은 두 가지 밖 에 없습니다.'cuda'와'cpu'입 니 다.일반적으로 GPU 가 있 는 상황 에서 장치 설정 을 명시 적 으로 해 야 하기 때문에 필요 할 때 변 수 를 메 인 저장 소 에서 디 스 플레이 로 옮 길 수 있 습 니 다.GPU 가 없 으 면 가 져 오지 않 아 도 됩 니 다.pytorch 는 기본 값 으로 메 인 저장 소 에 인 자 를 저장 합 니 다.
\#2:모델 중층 의 정 의 는 Sequential 을 사용 하여 통일 적 으로 관리 하고 자 하 는 층 을 한 층 으로 표시 할 수 있 습 니 다.
\#3:모델 매개 변 수 를 GPU 메모리 로 초기 화하 고 연산 을 가속 화 합 니 다.물론 필요 할 때 외부 에서 model.to(device)를 실행 하여 이전 할 수 있 습 니 다.
\#4:모델 의 최적화 기 를 정의 합 니 다.TF 와 달리 pytorch 는 정의 할 때 경사도 가 떨 어 지 는 매개 변 수 를 입력 해 야 합 니 다.즉,self.parameters()는 현재 모델 의 모든 매개 변 수 를 표시 합 니 다.실제로 최적화 기와 모델 매개 변 수 를 정의 하 는 순서 문 제 는 걱정 하지 않 아 도 됩 니 다.self.parameters()의 출력 은 모델 매개 변수의 인 스 턴 스 가 아니 라 전체 모델 매개 변수 대상 의 지침 이기 때문에 최적화 기 를 정의 한 후에 도 한 층 을 정의 하 더 라 도 최적화 할 수 있 습 니 다.물론 유 틸 리 티 도 외부 에서 정의 할 수 있 습 니 다.model.parameters()에 들 어가 면 됩 니 다.무 작위 경사도 하강 을 정의 합 니 다.
\#5:모델 의 전방 향 전 파 는 TF 의 call()과 유사 하 며,model()이 실행 하 는 함 수 를 정의 합 니 다.
\#6:저 는 loss 를 가 져 온 함 수 를 모델 에 통합 시 켰 습 니 다.여 기 는 실제 태그 와 예측 태그 간 의 교차 엔트로피 를 계산 합 니 다.
\#7/8/9:TF 에 서 는 매개 변수 경사도 가 경사도 대 에 저장 되 어 있 으 며,pytorch 에 서 는 매개 변수 경사도 가 각각 해당 하 는 매개 변수 에 통합 되 어 있 으 며,tensor.grad 를 사용 하여 볼 수 있 습 니 다.loss 에 backward()를 실행 할 때마다 pytorch 는 loss 계산 에 참여 하 는 모든 훈련 가능 한 매개 변 수 를 loss 의 경사도 에 중첩 합 니 다(직접 추가).따라서 우리 가 경사도 를 중첩 할 의사 가 없다 면 백 워드()전에 이전의 경사도 를 삭제 해 야 한다.또한 우리 앞 에 훈련 을 기다 리 는 매개 변 수 를 모두 최적화 기 에 전 달 했 기 때문에 최적화 기 에 zero 를 사용 합 니 다.grad()는 모든 훈련 대기 매개 변수 에 존재 하 는 경사도 를 제거 할 수 있 습 니 다.그럼 경사도 중첩 은 언제 사용 하나 요?예 를 들 어 대량의 경사도 가 떨 어 지면 메모리 가 전체 수량의 경사도 를 직접 계산 하지 못 할 때 우 리 는 대량으로 일부분 으로 나 누 어 계산 할 수 밖 에 없다.한 부분 을 계산 할 때마다 loss 를 받 으 면 backward()를 한 번 씩 받 아서 전체 수량의 경사도 를 얻 을 수 있다.경사도 계산 이 끝 난 후에 최적화 기의 step()를 실행 하고 최적화 기 는 훈련 가능 한 매개 변수의 경사도 에 따라 한 단계 최적화 합 니 다.
\#10:torchsummary 함수 로 모델 구 조 를 표시 합 니 다.이상 하 게 도 이 걸 torch 에 계승 하지 않 고 torchsummary 라 이브 러 리 를 다시 설치 해 야 합 니 다.
2  훈련 및 시각 화
다음은 모델 을 사용 하여 훈련 을 진행 합 니 다.pytorch 가 가지 고 있 는 MNIST 데이터 세트 가 좋 지 않 기 때문에 저 는 Keras 가 가지 고 있 는 것 을 사용 하여 데 이 터 를 얻 는 생 성 기 를 정 의 했 습 니 다.다음은 완전한 훈련 및 그래 픽 코드(50 회 교체 기록 1 회 정확도)입 니 다.

import numpy as np
import matplotlib.pyplot as plt 
import torch 
from torch import nn,optim 
from torchsummary import summary 
from keras.datasets import mnist
from keras.utils import to_categorical
device = torch.device('cuda') #――――――1――――――
 
class ModelTest(nn.Module):
 def __init__(self,device):
  super().__init__() 
  self.layer1 = nn.Sequential(nn.Flatten(),nn.Linear(28*28,512),nn.ReLU())#――――――2――――――
  self.layer2 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) 
  self.layer3 = nn.Sequential(nn.Linear(512,512),nn.ReLU())
  self.layer4 = nn.Sequential(nn.Linear(512,10),nn.Softmax()) 

  self.to(device) #――――――3――――――
  self.opt = optim.SGD(self.parameters(),lr=0.01)#――――――4――――――
 def forward(self,inputs): #――――――5――――――
  x = self.layer1(inputs)
  x = self.layer2(x)
  x = self.layer3(x)
  x = self.layer4(x)
  return x 
 def get_loss(self,true_labels,predicts): 
  loss = -true_labels * torch.log(predicts) #――――――6――――――
  loss = torch.mean(loss)
  return loss
 def train(self,imgs,labels): 
  predicts = model(imgs) 
  loss = self.get_loss(labels,predicts)
  self.opt.zero_grad()#――――――7――――――
  loss.backward()#――――――8――――――
  self.opt.step()#――――――9――――――
def get_data(device,is_train = True, batch = 1024, num = 10000):
 train_data,test_data = mnist.load_data()
 if is_train:
  imgs,labels = train_data
 else:
  imgs,labels = test_data 
 imgs = (imgs/255*2-1)[:,np.newaxis,...]
 labels = to_categorical(labels,10) 
 imgs = torch.tensor(imgs,dtype=torch.float32).to(device)
 labels = torch.tensor(labels,dtype=torch.float32).to(device)
 i = 0
 while(True):
  i += batch
  if i > num:
   i = batch 
  yield imgs[i-batch:i],labels[i-batch:i] 
train_dg = get_data(device, True,batch=4096,num=60000) 
test_dg = get_data(device, False,batch=5000,num=10000) 

model = ModelTest(device) 
summary(model,(1,28,28),11,device='cuda') 
ACCs = []
import time
start = time.time()
for j in range(20000):
 #  
 imgs,labels = next(train_dg)
 model.train(imgs,labels)

 #  
 img,label = next(test_dg)
 predicts = model(img) 
 acc = 1 - torch.count_nonzero(torch.argmax(predicts,axis=1) - torch.argmax(label,axis=1))/label.shape[0]
 if j % 50 == 0:
  t = time.time() - start
  start = time.time()
  ACCs.append(acc.cpu().numpy())
  print(j,t,'ACC: ',acc)
#  
x = np.linspace(0,len(ACCs),len(ACCs))
plt.plot(x,ACCs)
정확도 변화 도 는 다음 과 같다.

3  기타 사용 방법
3.1  tensor 와 array
주의해 야 할 것 은 pytorch 의 tensor 는 numpy 의 array 를 기반 으로 메모리 공유 입 니 다.즉,tensor 를 목록 에 직접 삽입 하면 이 tensor 를 수정 할 때 목록 에 있 는 이 tensor 도 수정 된다.더 쉽게 무시 되 는 것 은 tensor.detach.numpy()를 사용 하 더 라 도 tensor 를 array 형식 으로 바 꾸 고 목록 을 삽입 하 는 것 입 니 다.원래 tensor 를 수정 할 때 목록 의 이 array 도 변 경 됩 니 다.따라서 전체 대상 이 아 닌 tensor 의 값 을 저장 하려 면 np.array(tensor)를 사용 하여 tensor 의 값 을 복사 해 야 합 니 다.
3.2  사용자 정의 계층
TF 에서 사용자 정의 모델 은 보통 keras 의 모델 을 계승 하고 사용자 정의 층 은 layers.Layer 를 계승 하 며 서로 다른 부 류 를 계승 하 는 것 은 초보 자 들 에 게 어려움 을 줄 수 있다.pytorch 에 서 는 사용자 정의 층 이 사용자 정의 모델 과 마찬가지 로 N.Module 을 계승 합 니 다.Pytorch 는 층 과 모형 을 모두 모듈 로 보고 이해 하기 쉽다.확실히 층 과 모델 사이 에 도 명확 한 경계 가 없 었 다.또한 정의 방식 은 위 에서 모델 을 정의 하 는 방식 과 마찬가지 로 두 함 수 를 실현 하면 된다.코드 예 시 는 다음 과 같다.

import torch  
from torch import nn 

class ParaDeconv(nn.Module):#――――――1――――――
 def __init__(self,in_n,out_n):
  super().__init__() 
  self.w = nn.Parameter(torch.normal(0,0.01,size = [in_n,out_n]),requires_grad=True)
  self.b = nn.Parameter(torch.normal(0,0.01,size = [out_n]),requires_grad=True) 
 def forward(self,inputs):
  x = torch.matmul(inputs,self.w)
  x = x + self.b
  return x 
layer = ParaDeconv(2,3)
y = layer(torch.ones(100,2))#――――――2――――――
loss = torch.sum(y)#――――――3――――――
loss.backward()#――――――4――――――
for i in layer.parameters():#――――――5――――――
 print(i.grad)#――――――6――――――
\#1:전체 연결 층 을 사용자 정의 합 니 다.층 에서 훈련 할 수 있 는 매개 변 수 는 N.Parameter 를 사용 하 는 것 으로 정 의 됩 니 다.torch.tensor 를 직접 사용 하면\#5 에서 옮 겨 다 닐 수 없습니다.
\#2/3/4:loss 를 입력 하고 계산 한 다음 에 역방향 전파 계산 매개 변수 경사도.
\#5/6:출력 이 역방향 전파 후 층 매개 변수의 경사도 를 완성 합 니 다.
이상 정 의 된 층 은 pytorch 자체 의 층 과 같이 모델 에 직접 삽입 하여 사용 할 수 있 습 니 다.
3.3  저장/불 러 오기
3.3.1  모델 저장/불 러 오기
두 가지 방법 이 있 습 니 다.하 나 는 모델 을 저장 하 는 매개 변수 입 니 다.

torch.save(model.state_dict(), PATH)         #    
model.load_state_dict(torch.load(PATH),strict=True) #  
이런 로드 방식 은 먼저 모델 을 정의 한 다음 에 파 라 메 터 를 불 러 와 야 한다.정 의 된 모델 매개 변수 이름과 저 장 된 매개 변수 가 맞지 않 으 면 오류 가 발생 합 니 다.그러나 strict 를 False 로 수정 하고 엄격하게 일치 하지 않 으 면 해당 하 는 키 값 만 일치 하고 더 많 거나 부족 한 인자 로 인해 오 류 를 보고 하지 않 습 니 다.
다른 하 나 는 모델 을 직접 저장 하 는 것 입 니 다.

torch.save(model, PATH) #  
model = torch.load(PATH) #  
이런 방식 은 보기 에는 편리 해 보이 지만 실제로는 실수 하기 쉽다.python 은 전체 모델 의 클래스 를 저장 할 수 없 기 때문에 정의 클래스 의 코드 파일 위 치 를 저장 하여 불 러 올 때 클래스 의 구 조 를 가 져 올 수 있 습 니 다.정의 클래스 의 코드 위 치 를 바 꾸 면 클래스 를 찾 지 못 해 오류 가 발생 할 수 있 습 니 다.
3.3.2  보존 훈련 점
어떤 훈련 단계 의 상 태 를 저장 하려 면 최적화 기 파라미터,모델 파라미터,훈련 교체 횟수 등 을 포함 하고 다음 과 같은 조작 을 할 수 있다.

#     
torch.save({
      'epoch': epoch,
      'model_state_dict': model.state_dict(),
      'optimizer_state_dict': optimizer.state_dict(),
      'loss': loss
      }, PATH)
#     
model = TheModelClass(*args, **kwargs)
optimizer = TheOptimizerClass(*args, **kwargs)

checkpoint = torch.load(PATH)

model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']
저장 모델 과 마찬가지 로 torch.save()를 사용 합 니 다.사전 을 저장 할 수 있 기 때문에 읽 을 때 도 사전 색인 에 따라 읽 으 면 됩 니 다.물론 어떤 유형 이 든 저장 할 수 있 는 것 이 아니 라 여기 저 장 된 네 가지 유형 은 다음 과 같 습 니 다.
  1. int
  2. collections.OrderedDict
  3. collections.OrderedDict
  4. list 
3.4  모델 매개 변수 수정
Pytorch 는 모델 파 라 메 터 를 수정 할 수 있 는 추가 방식 을 제공 하지 않 았 습 니 다.위 에 모델 파 라 메 터 를 불 러 오 는 방식 으로 파 라 메 터 를 수정 할 수 있 습 니 다.어떤 매개 변수 에 대해 서 는 키 값 과 수정 할 값 을 사전 에 넣 으 면 loadstate_dict 하면 됩 니 다.모든 인자 가 들 어 오지 않 았 다 면 strict 를 False 로 설정 하 십시오.예 는 다음 과 같다.

model.load_state_dict({'weight':torch.tensor([0.])},strict=False) #      
매개 변수 이름,즉 키 값,대응 하 는 매개 변수 shape 는 model.state 를 통 해dict()보기.
이상 은 Pytorch 를 사용 하여 모델 을 구축 하 는 절차 의 상세 한 내용 입 니 다.Pytorch 모델 구축 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기