탐구이유: 지난 시간에는 일정 부피의 음료수캔의 재료비가 최소가 되는 최솟값을 직접 구해보고 실제 음료수캔과 비교해 보는 시간을 가졌었다. 그러나 이는 우리가 미분 가능한 함수를 다루었기에 미분을 통해 최솟값을 구할 수 있던 것이지 그렇지 않은 경우에는 문제를 해결할 방안이 없어 보인다. 이때 때마침 학교 밖 교육으로 수강한 우석대 파이썬 프로그래밍 수업의 마지막 수업으로 배운 경사하강법이란 방식이 있었는데, 이 방식을 사용하면 더 복잡한 케이스도 해결할 수 있을 것 같아 탐구해 보고자 한다.
Ⅰ.서론
1.경사하강법(gradient descent)이란?
경사하강법은 함수 값이 낮아지는 방향으로 독립 변수 값을 변형시켜가면서 최종적으로 최소 함수 값을 갖도록 하는 독립 변수 값을 찾는 방법이라 정의할 수 있는데, 간단히 말하자면 2차원 세계에서 눈을 가리고 산을 내려간다고 생각하면 된다. 만약 자신이 자신이 서있는 곳을 더듬었다고 하자. 이때 산이 위쪽으로 뻗어있는 추세이면 당신은 음의 방향으로 이동할 것이고 아래쪽으로 뻗어있다면 양의 방향으로 이동해야겠다고 판단할 것이다. 즉 무작위 위치에 있다 가정했을 때 그 점에서의 기울기가 양수이면 x좌표가 음의 방향인 곳으로, 음수이면 양의 방향인 곳으로 일정 거리만큼 이동시켜 결국 최솟값에 도달하는 방식인 것이다. 이것을 수식화하자면 간단하게
로 생각할 수 있는데, 여기서
는 step size 즉 이동 거리를 의미한다. 이
를 너무 작게 하면 최솟값에 수렴하지 못하고 너무 크면 함숫값이 계속 커질 수 있기 때문에 적절한 거리를 설정하는 것이 중요하다. 나는 우석대 정보보안학과 교수님이 추천한 0.1값을 사용하고 문제가 생길 시 추후 적절히 변경할 예정이다.
Ⅱ.본론
1.미분불가능한 함수에서의 적용
비용 함수 는 x=5에서 연속이지만 좌미분계수가 1, 우미분계수가 3이므로 미분불가능하므로 기존처럼 단순한 미분을 통해 구할 수 없다. 그러나 파이썬 코딩을 활용해 경사하강법을 사용하면 이러한 문제를 해결할 수 있다.
코드를 이런 식으로 작성하고 Anaconda Prompt에서 실행시키면
위와 같은 결과물을 얻을 수 있고
다음과 같이 x=4.5에서 최솟값을 갖는다는 것을 알 수 있다.
하지만 방금 본 함수는 매우 단순하여 그냥 그래프를 그려서 파악할 수도 있기에 오히려 비효율적인 방법이었을지도 모른다. 그럼 조금 더 현실적인 함수에 적용해
보겠다.
2.절삭 가공 시 공구의 진동과 마찰열에 의한 비용 상승 모델에서의 적용
이번엔 한국정밀공학회에 실제 실려있는 함수를 AI를 통해 단순화한 모델을 해결해 보고자 한다. 손실 함수는 이며
은 기본 설계 비용을,
는 기계 진동 노이즈를, 0.2
는 과부하 위험 가중치를 의미한다. 전에 본 함수가 스프링 설계 시 압축 거리에 따른 비용을 탄성 구간에서 소성 구간으로만 고려하였다면, 이번에는 비록 하나의 변수로 단순화되었지만 다양한 요소를 고려하여 좀 더 현실적인 경우라고 할 수 있다. 이번 함수의 경우 수2까지 학습한 나와 같은 학생의 경우 미분할 수 없을뿐더러 극값을 사람이 찾는 것도 거의 불가능하다. 그러므로 이번엔
를 사용하는 것이 아닌 미분계수의 정의처럼
를 사용해 보고자 한다. 그러나 파이썬에서 lim를 구현하기 어려우므로 h를 1e-6(0.000001)로 가정하고 진행하겠다. 이제 프로그램을 진행시키면
이런 결과가 나오는데 우선 하나의 극값에 수렴하지 않고 다양한 곳을 왔다갔다 했다는 것 자체가 앞서 말했던 step size 즉 이동 거리가 너무 크다는 것이다. 또한 우리가 원하는건 최솟값이지 극솟값이 아니다. 수정할 것이 많아 보이니 천천히 바꿔보자.
먼저 하나의 극값에 수렴하도록 step size를 0.1에서 0.02로 바꾸어보겠다.
아주 훌륭한 결과를 얻어냈으니 이제 최솟값을 구할 방법을 생각해보자.
첫 번째로 고려한 방식은 시작점을 다양하게 하여 그 중 가장 작은 값을 최솟값으로 설정하는 방법이다. 우선 시작점을 0에서 10까지 1000개를 설정하고 방금과 같은 방식을 반복하여 최솟값을 구하도록 하였다.
기존 대비 1000배의 시간이 걸리다 보니 아무래도 시간이 조금 걸렸지만, 이동 거리, 시작점 당 이동 횟수 등을 약 1000번으로 맞추니 x=4.2674라는 값이 반복적으로 나오기 시작했다. 따라서 내가 구한 값이 정말 이 함수의 최솟값인지 기대되는 마음으로 검사해봤는데 놀랍게도 오답이었다. 믿을 수 없는 일이다. 1000개의 씨앗을 뿌리고 혹시 몰라 한 시작점 당 1000번을 이동하게 하였는데 그 중 단 하나도 맞는게 없다는 것이 참 이해가 되지 않았다. 대충 계산해도 1000000번의 시행을 거친건데 말이 되는 것일까? 일단 코드 또한 비효율적인 부분이 있을 뿐 이상이 없다고 나오니 고칠 수 있는 부분은 단 하나, step size이다. 우선 위에서 이동 거리를 적절하게 조정하게 골짜기를 튀어 오르는 현상을 없앴으므로 너무 커서 생기는 문제는 아니다. 그럼 값이 너무 작아 탈출이 어렵다는건데 0.1보다 크고 0.02보다는 작은 값으로 설정해보겠다. 그리고 전에 걸어두었던 이전 x값과 현재 x값의 차이가 0.000001보다 작으면 작동을 멈추는 것 또한 풀어보겠다.
십여 차례 이동 거리, 시작점 개수, 반복 횟수를 변경했음에도 이 방식으로는 4.2
근방의 늪을 벗어날 수 없음을 깨달았다. 이는 아마 최솟값으로 들어가는 골짜기가 매우 좁기 때문이 아닐까 싶다. 대망의 10000개의 시작점과 0.01이라는 매우 좁은 이동 거리를 설정해도 여전히 4.2에 머무르게 되어 깔끔히 패배를 인정했다. 아쉬운 마음에 조금 더 탐구를 해본 결과 현재 가장 진보한 방식은 Adam (Adaptive Moment Estimation)이다. 이것은 우리가 산을 더듬거리며 움직였던 것과 달리 ‘관성(Momentum)을 사용하여 마치 자동차가 굴러가듯 극값에 빠지지 않고 그래프를 따라 움직여 적은 시행만으로 최솟값을 정확히 알아낼 수 있는 방식이다.
Ⅲ.결론
지금까지 단순한 음료수캔의 최적설계에서 나아가 미분 불가능하거나 더 복잡한 케이스에는 어떻게 최적의 값을 구할 수 있는지 알아보고 생기는 모순(극솟값)에 대한 대안도 고려해 보았다. 그러나 실제 공학에서는 이러한 정적인 값으로 정의되지 않고 변수가 다양할 뿐더러 가동 온도, 가동 속도, 압축 거리 등 고려해야 할 사항이 훨씬 많을 것이다. 이런 경우 경사하강법을 어떻게 적용할 것인지에 또 의문이 발생하게 된다. 이때 사용되는 것이 바로 우석대 수업에서 배웠던 하나의 미지수에 대하여 미분하는 편미분이라는 것이었다. 즉 인공지능이란 수천억 개의 모든 변수에 대하여 각 변수의 전체 오차에 대한 기여도를 계산하기 위해 편미분 값을 구해 동시에 업데이트 하여 최선의 값을 내고 있었던 것이다. 이것이 미적분이 어떻게 세상의 기초가 되는지에 대한 나의 탐구의 결론이 되었다. (다층 퍼셉트론)
