[Pytorch] Python으로 딥 러닝 모델 개발하기 2
2. PyTorch 딥 러닝 모델 수명주기
이 섹션에서는 모델을 정의하는 데 사용할 수 있는 딥 러닝 모델 및 PyTorch API의 수명주기를 알아볼 수 있다.
모델에는 수명주기가 있으며, 이 매우 간단한 지식은 데이터 세트 모델링과 PyTorch API 이해 모두를 위한 백본을 제공한다.
수명주기의 5 단계는 다음과 같다.
1. 데이터준비
2. 모델 정의
3. 모델 훈련
4. 모델 평가
5. 예측
1 단계 : 데이터 준비
첫 번째 단계는 데이터를 로드하고 준비하는 것이다.
신경망 모델에는 숫자 입력 데이터와 숫자 출력 데이터가 필요한다.
표준 Python 라이브러리를 사용하여 CSV 파일과 같은 테이블 형식 데이터를 로드하고 준비할 수 있다. 예를 들어 Pandas를 사용하여 CSV 파일을 로드할 수 있고 scikit-learn의 도구를 사용하여 클래스 레이블과 같은 범주 형 데이터를 인코딩할 수 있다.
예를 들어 데이터 세트 개체의 생성자는 데이터 파일 (예 : CSV 파일)을 로드할 수 있다.
그런 다음 데이터 세트의 길이 (행 또는 샘플 수)를 가져오는 데 사용할 수 있는__len __ () 함수와 인덱스 별로 특정 샘플을 가져오는 데 사용되는 __getitem __ () 함수를 재정의 할 수 있다.ㅠ데이터 세트를 로드할 때 확장 또는 인코딩과 같은 필요한 변환을 수행할 수도 있다.
커스텀 Dataset 클래스의 스켈레톤은 아래와 같다.
# dataset definition
class CSVDataset(Dataset):
# load the dataset
def __init__(self, path):
# store the inputs and outputs
self.X = ...
self.y = ...
# number of rows in the dataset
def __len__(self):
return len(self.X)
# get a row at an index
def __getitem__(self, idx):
return [self.X[idx], self.y[idx]]
로드되면 PyTorch는 모델 학습 및 평가 중에 Dataset 인스턴스를 탐색할 수 있는 DataLoader 클래스를 제공한다
훈련 데이터 세트, 테스트 데이터 세트 및 유효성 검사 데이터 세트에 대한 DataLoader 인스턴스를 만들 수 있다.
random_split () 함수는 열차 테스트 세트로 데이터 세트를 분할하는 데 사용될 수 있다. 일단 분할되면 데이터 세트에서 선택한 행을 일괄 처리 크기 및 매 세대마다 셔플 해야 하는지 여부와 함께 DataLoader에 제공할 수 있다.
예를 들어 데이터 세트에서 선택한 행 샘플을 전달하여 DataLoader를 정의할 수 있다.
'''
# create the dataset
dataset = CSVDataset(...)
# select rows from the dataset
train, test = random_split(dataset, [[...], [...]])
# create a data loader for train and test sets
train_dl = DataLoader(train, batch_size=32, shuffle=True)
test_dl = DataLoader(test, batch_size=1024, shuffle=False)
...
# train the model
for i, (inputs, targets) in enumerate(train_dl):
...
정의되면 DataLoader를 열거하여 반복할 때마다 하나의 일괄 처리에 해당하는 샘플을 생성할 수 있다.
2 단계 : 모델 정의
다음 단계는 모델을 정의하는 것이다.
클래스의 생성자는 모델의 레이어를 정의하고 forward () 함수는 모델의 정의된 레이어를 통해 입력을 전달하는 방법을 정의하는 재정의 이다. 활성화 함수는 ReLU , Softmax 및 Sigmoid와 같은 레이어로 정의할 수도 있다.
다음은 하나의 레이어가 있는 간단한 MLP 모델의 예다.
# model definition
class MLP(Module):
# define model elements
def __init__(self, n_inputs):
super(MLP, self).__init__()
self.layer = Linear(n_inputs, 1)
self.activation = Sigmoid()
# forward propagate input
def forward(self, X):
X = self.layer(X)
X = self.activation(X)
return X
'''
xavier_uniform_(self.layer.weight)
지정된 레이어의 가중치는 생성자에서 레이어가 정의된 후에도 초기화될 수 있다.
3 단계 : 모델 훈련
훈련 과정에서는 손실 함수와 최적화 알고리즘을 정의해야 한다.
일반적인 손실 함수는 다음과 같다.
- BCELoss: 이진 분류를 위한 이진 교차 엔트로피 손실
- CrossEntropyLoss: 다중 클래스 분류에 대한 범주 형 교차 엔트로피 손실이다.
- MSELoss : 회귀에 대한 평균 제곱 손실.
확률 적 경사 하강 법은 최적화에 사용되며 표준 알고리즘은 SGD 클래스에서 제공되지만 Adam과 같은 다른 버전의 알고리즘도 사용할 수 있다.
# define the optimization
criterion = MSELoss()
optimizer = SGD(model.parameters(), lr=0.01, momentum=0.9)
모델 훈련에는 훈련 데이터 세트에 대한 DataLoader 열거가 포함된다.
첫째, 훈련 시대의 수에 대한 루프가 필요한다. 그런 다음 확률 적 경사 하강 법을 위한 미니 배치에 내부 루프가 필요하다.
...
# enumerate epochs
for epoch in range(100):
# enumerate mini batches
for i, (inputs, targets) in enumerate(train_dl):
...
모델에 대한 각 업데이트에는 다음으로 구성된 동일한 일반 패턴이 포함된다.
- 마지막 오류 그라디언트를 지운다.
- 모델을 통해 입력을 전달한다.
- 모델 출력에 대한 손실을 계산한다.
- 모델을 통해 오류를 역 전파한다.
- 손실을 줄이기 위해 모델을 업데이트하자.
예를 들면 :
...
# clear the gradients
optimizer.zero_grad()
# compute the model output
yhat = model(inputs)
# calculate loss
loss = criterion(yhat, targets)
# credit assignment
loss.backward()
# update model weights
optimizer.step()
4 단계 : 모델 평가
모델이 적합하면 테스트 데이터 세트에서 평가할 수 있다. 이는 테스트 데이터 세트에 DataLoader를 사용하고 테스트 세트에 대한 예측을 수집 한 다음 예측을 테스트 세트의 예상 값과 비교하고 성능 메트릭을 계산하여 수행할 수 있다.
...
for i, (inputs, targets) in enumerate(test_dl):
# evaluate the model on the test set
yhat = model(inputs)
...
5 단계 : 예측하기
적합 모델을 사용하여 새 데이터를 예측할 수 있다.
예를 들어 단일 이미지 또는 단일 데이터 행이 있고 예측을 원할 수 있다. 이를 위해서는 데이터를 PyTorch Tensor 데이터 구조로 래핑 해야 한다. Tensor는 데이터를 보관하기 위한 NumPy 배열의 PyTorch 버전이다. 또한 모델을 학습할 때 backward ()을 호출하는 것과 같이 모델 그래프에서 자동 미분 작업을 수행할 수 있다. 자동 미분 그래프에서 Tensor를 분리하고 NumPy 함수를 호출하여 NumPy 배열을 검색할 수 있지만 예측도 Tensor 가된다.
...
# convert row to data
row = Variable(Tensor([row]).float())
# make prediction
yhat = model(row)
# retrieve numpy array
yhat = yhat.detach().numpy()