import torch
# 학습 데이터 (입력과 출력) 선언
x_train = torch.FloatTensor([[1, 1], [2, 2], [3, 3], [4, 4], [5, 3], [6, 2], [8, 1]]) # 입력 데이터
y_train = torch.FloatTensor([[0], [0], [0], [1], [1], [1], [0]]) # 출력 데이터 (0 또는 1)
# 각 레이어에 사용할 노드 개수 설정
nH1 = 10 # 첫 번째 은닉층 노드 수
nH2 = 5 # 두 번째 은닉층 노드 수
nH3 = 8 # 세 번째 은닉층 노드 수
# 가중치와 편향 초기화
# w_h1, b_h1: 입력층에서 첫 번째 은닉층으로 가는 가중치와 편향
w_h1 = torch.randn([2, nH1], requires_grad=True)
b_h1 = torch.randn([nH1], requires_grad=True)
# w_h2, b_h2: 첫 번째 은닉층에서 두 번째 은닉층으로 가는 가중치와 편향
w_h2 = torch.randn([nH1, nH2], requires_grad=True)
b_h2 = torch.randn([nH2], requires_grad=True)
# w_h3, b_h3: 두 번째 은닉층에서 세 번째 은닉층으로 가는 가중치와 편향
w_h3 = torch.randn([nH2, nH3], requires_grad=True)
b_h3 = torch.randn([nH3], requires_grad=True)
# w_o, b_o: 세 번째 은닉층에서 출력층으로 가는 가중치와 편향
w_o = torch.randn([nH3, 1], requires_grad=True)
b_o = torch.randn([1], requires_grad=True)
# 최적화 방법 설정 (확률적 경사 하강법)
optimizer = torch.optim.SGD([w_h1, b_h1,
w_h2, b_h2,
w_h3, b_h3,
w_o, b_o], lr=0.01)
# 모델을 정의하는 함수
def H(x):
# 각 층에서 계산 수행 (가중치와 편향을 적용한 뒤 활성화 함수 사용)
h1 = torch.sigmoid(torch.matmul(x, w_h1) + b_h1) # 첫 번째 은닉층 계산
h2 = torch.sigmoid(torch.matmul(h1, w_h2) + b_h2) # 두 번째 은닉층 계산
h3 = torch.relu(torch.matmul(h2, w_h3) + b_h3) # 세 번째 은닉층 계산
model = torch.sigmoid(torch.matmul(h3, w_o) + b_o) # 출력층 계산 (이진분류: sigmoid 사용)
return model
# 학습 과정
for iter in range(100000): # 100,000번 반복
# 비용 함수 (모델이 얼마나 틀렸는지 계산)
cost = torch.mean((-1) * y_train * torch.log(H(x_train)) +
(-1) * (1 - y_train) * torch.log(1 - H(x_train)))
optimizer.zero_grad() # 이전 계산된 기울기 초기화
cost.backward() # 비용 함수의 기울기 계산
optimizer.step() # 가중치와 편향 업데이트
if iter % 10000 == 0: # 10,000번마다 비용 출력
print(iter, cost.detach().item())
# 새로운 데이터를 넣어 모델이 예측하도록 함
x_test = torch.FloatTensor([[7, 1]]) # 테스트 데이터
model_result = H(x_train) # 모델 결과
print(model_result)
# 임계값(0.5) 기준으로 0 또는 1로 변환
threshold = 0.5
binary_tensor = (model_result > threshold).float()
print(binary_tensor)
0 3.0521583557128906
10000 0.028955373913049698
20000 0.004755963105708361
30000 0.0021211702842265368
40000 0.0012795006623491645
50000 0.0008888268494047225
60000 0.0006701701204292476
70000 0.0005320971249602735
80000 0.00043783787987194955
90000 0.0003697801730595529
tensor([[2.0964e-06],
[7.6455e-06],
[7.9331e-04],
[9.9902e-01],
[9.9999e-01],
[9.9986e-01],
[3.0520e-04]], grad_fn=<SigmoidBackward0>)
tensor([[0.],
[0.],
[0.],
[1.],
[1.],
[1.],
[0.]])