[2022 국민대학교 겨울 인공지능 특강] 4주차 2일 학습 내용

하지원·2022년 2월 6일
0

어제는 딥러닝 모듈인 PyTorch를 사용하지 않고 선형회귀(Linear regression)식을 직접 구현하여 예측값을 얻었지만, 이번엔 본격적으로 PyTorch를 이용해 구현했다.

X = [1, 2, 3, 4, 5, 6, 7]
Y = [25000, 55000, 75000, 110000, 128000, 155000, 180000]
데이터가 위와 같이 주어졌을 때 x값이 8일 때의 y값을 예측하는 것이다.

우선 값들을 텐서화 하기 위해 다음과 같이 코딩한다.
X = [[i] for i in X]
Y = [[i] for i in Y]

x_data = torch.Tensor(X)
y_data = torch.Tensor(Y)

X, Y 텐서를 입력하여 다음 값을 예측해야 하며, 둘 다 1차원이다.

선형회귀 모델을 만들기 위해 LinearRegressionModel이라는 클래스를 준비한다. 딥러닝 신경망을 사용하기 위해 torch.nn.Module도 필요하다.

	class LinearRegressionModel(torch.nn.Module): 
		def __init__(self, input_dim, output_dim):
    		super(LinearRegressionModel, self).__init__() 
    		self.linear = torch.nn.Linear(input_dim, output_dim)
		def forward(self, x): 
    		y_pred = self.linear(x)
    		return y_pred

	model = LinearRegressionModel(1, 1)

이렇게 입력값이 두개가 되도록 설정하고, y_pred 변수가 출력이 되도록 linear 함수를 저장시킨다. linear 변수에는 선형함수를 사용하도록 torch.nn.Linear를 입력한다.

손실함수는 mean square error를 사용하기 위해 다음과 같이 선언한다.

	criterion = torch.nn.MSELoss()

그리고 딥러닝에는 최적화(optimization)이라는 과정이 있다. 학습을 반복하면서 손실(loss)이 최소가 되게 하는 과정이다. 대표적으로 Stochastic Gradient Descent, 줄여서 SGD라는 것이 있다. 기울기를 구할 때 전체 데이터가 아닌 일부만을 이용하여 계산이 부정확할 수 있지만 계산을 빠르게 할 수 있고, 극소값이 아닌 최소값에 빠지기 쉽게 해준다.

	optimizer = torch.optim.SGD(model.parameters(), lr=0.001)

lr은 learning rate(학습률)의 준말인데, 딥러닝 모델이 한번에 학습하는데 걸리는 시간을 뜻한다. 너무 크게 설정하면 데이터가 무질서하게 이동할 수 있어 최소값에 도달하지 못할 수 있고, 그렇다고 너무 작게 설정하면 학습이 느려져 최소값에 도달하기 전에 학습이 끝나게 될 수 있다. 그러므로 적당한 값이 중요하다.

	for epoch in range(10001): 
		pred_y = model(x_data)
		loss = criterion(pred_y, y_data)
		optimizer.zero_grad() 
		loss.backward() 
		optimizer.step()
		if epoch % 1000 == 0:
    		print("[ epoch: %d, cost: %.2f ]" % (epoch, loss.data))
    		print("w = %.2f, b = %.2f" % (model.linear.weight, model.linear.bias))

	print("f(x) = %.2fx + %.2f" % (model.linear.weight, model.linear.bias))
	print("예측값: [%.2f]" % (model(torch.Tensor([[8]]))))

마지막으로 학습을 위한 코딩을 하는데, 여기서 최적화를 할 때 optimizer.zero_grad()라는 코드를 볼 수 있다. 기울기를 0으로 초기화 하겠다는 뜻인데, 매번 다른 기울기를 정확하게 얻기 위한 것이며, 혹시나 있을 수 있는 불필요한 변화를 없에려는 것이다.

그리고 딥러닝 과정중에 back propagation(역전파)이라는 과정이 있다. 인공신경망에서 앞으로 진행하다가 뒤로도 가보면서 손실값을 변경하는 것이다. 적당히 뒤로가고 나서는 다시 앞으로 진행하면서 최적화(optimizer.step())를 한다.

최종적으로 X값이 8이었을 때 206523.78이 나왔다.


import torch

X = [1, 2, 3, 4, 5, 6, 7]
Y = [25000, 55000, 75000, 110000, 128000, 155000, 180000]

X = [[i] for i in X]
Y = [[i] for i in Y]

x_data = torch.Tensor(X)
y_data = torch.Tensor(Y)


class LinearRegressionModel(torch.nn.Module):
	def __init__(self, input_dim, output_dim):
    	super(LinearRegressionModel, self).__init__()
    	self.linear = torch.nn.Linear(input_dim, output_dim)

	def forward(self, x):
    	y_pred = self.linear(x)
    	return y_pred


model = LinearRegressionModel(1, 1)  # X, Y 둘다 1차원 리스트

criterion = torch.nn.MSELoss()  # 손실 함수: Mean Squared Error
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)

for epoch in range(10001):
	pred_y = model(x_data)  # model 데이터 x를 넣어서 결과를 구함
	loss = criterion(pred_y, y_data)  # 구한 데이터와 실제 데이터를 비교하는 손실 함수로 MSELoss 사용
	optimizer.zero_grad()  # zero_grad: back propagation 전에 기울기를 0으로 초기화 해줘야 함
	loss.backward()  # back propagation으로 parameter에 대해 gradient 구함
	optimizer.step()  # 최적화 진행; model parameter들을 learning rate만큼 기울기를 곱함
	if epoch % 1000 == 0:
    	print("[ epoch: %d, cost: %.2f ]" % (epoch, loss.data))
    	print("w = %.2f, b = %.2f" % (model.linear.weight, model.linear.bias))

print("\nf(x) = %.2fx + %.2f" % (model.linear.weight, model.linear.bias))
print("예측값: [%.2f]" % (model(torch.Tensor([[8]]))))
profile
국민대 전자공학부, 서강대학교 석사과정, 크래프톤 정글 2기

0개의 댓글