본문 바로가기
AI/Competition

[Dacon] 상추의 생육 환경 생성 AI 경진대회 후기

by Myungbin 2023. 7. 9.

개인의 의견을 바탕으로 작성되었습니다. 팀의 생각과 다를 수 있고 최종 결과물과 차이가 있을 수 있습니다.

한 달간 노력한 나에게 박수

이번 대회는 너무 힘들었다. 주제 자체가 난해하기도 했고 이런저런 사정이 겹쳐 정신적으로 많이 힘들었던 것 같다.

결과는 좋지만 너무 부족했다 생각하기 때문에 마냥 기쁘지는 않다.

좀 더 완벽하게 보완해서 하고 싶었지만 내 모델링 실력과 분석 결과에 대한 해석 능력, 데이터에 대한 해석 능력이 아직 부족하다는 것을 깨닫게 되는 대회였다. (세 가지가 데이터 분석의 전부인데..)


대회

[설명]

이번 경진대회에서는 예측 모델과 생성 모델 2가지 모두 개발해야 합니다.

  1. 상추의 일별 잎 중량을 예측하는 AI 예측 모델 개발 (정량평가)
  2. 1번의 예측 모델을 활용하여 생육 환경 생성 AI 모델 개발 (정성평가)
  • 생성 AI 모델 결과로부터 상추의 일별 최대 잎 중량을 도출할 수 있는 최적의 생육 환경 조성 및 제안 (최종 결과물)

다음 설명과 같이 대회는 AI 예측 모델과, 생성 AI 모델 2개를 해야 했다.

처음 이걸 할 수 있을까에 대한 고민을 하게 되었는데, 생성 모델을 듣기는 했지만 한 번도 해본 적 없었고 주변에 도움을 청할 사람도 없었다.

그렇기 때문에 예측 모델을 잘 한다고 해도 생성 모델의 비중이 크기 때문에 수상을 못할 것 같았다.

예측 모델은 RMSE라는 명확한 기준이 있지만 생성 모델은 결과를 설득을 시켜야 해서 생성 모델을 하지도 못함 + 설득시킬 자신도 없음

두 가지 이유로 되게 망설여졌고, 중간에 포기할 것 같은 느낌도 있었다.

그래도 일단 하기로 했으니까 예측 모델부터 잘 만든 후에 생성 모델을 해보기나 하자는 생각으로 시작을 하게 되었다.

2주 예측 모델을 하고, 2주 생성 모델을 하면 되겠다는 계획을 세우고 시작했다.

예측 모델

처음 데이터를 보고 어떻게 접근을 해야 할까에 대한 고민을 했다.

처음엔 24시간의 데이터가 28일 치가 있었고(X) 해당 일에 해당하는 weight(y)가 있었다.

X의 개수와 y의 row 수가 같지 않기 때문에(X =24, y = 1), 전처리로 개수를 맞춘 후, 회귀로 접근해야 하나 Baseline처럼 24시간의 데이터와 y를 매칭 시켜서 해야 하나 고민을 했지만 비슷한 대회에서 전자와 비슷한 방식을 채택했기 때문에 해당 전처리로 개수를 맞춰야겠다고 생각했다.

- 전처리

2가지 아이디어가 나왔는데,

  1. 일별 기초통계량(Mean, Median등)을 적용하여 24시간의 데이터를 1개로 함축
  2. 시간의 개념을 살려 Feature(Time) 의형식

ex) X_1(0시), X_1(1시), ... X_n(22시), X_n(23시)

이였다.

첫 번째 방법의 경우 Feature의 개수를 유지할 수 있고, 파생 변수를 만들기 쉽다는 장점이 있지만, 24시간의 행위를 하나로 함축했기 때문에 정보의 손실이 크고, 예측 모델을 설명하기 힘들다고 생각(행위에 대한 정보가 사라지기 때문) 했다.

두 번째 방법의 경우 시간과 행위의 개념은 살릴 수 있다는 장점이 있지만 Feature의 개수가 많아져 하나의 Row가 가지는 정보가 너무 많아 과적합의 위험이 있다고 생각했다.

첫 번째 방법으로 다양한 방법을 시도했지만 어느 순간 벽을 느꼈다.

EDA를 하면서 계속 데이터를 살펴보면서 시간의 개념이 없기 때문에 시간의 개념을 어느 정도 추가했고(이동 평균, 중앙값 등), 행위의 개념이 없어 행위의 개념을 추가해 주었다.

맞는다고 생각한 논리가 맞지 않았고, 아니라고 생각하는 게 맞는 경우가 많았다. 나름 괜찮은 아이디어였던 것 같지만 문제를 도저히 못 찾을 것 같았다. 그냥 '모르겠다'가 결론이었다. 시간이 지나도 RMSE가 떨어지지가 않자, 결국 예측 모델을 잠시 접어두고 나는 생성 모델로 뛰어들게 되었다.

지금 생각하면 내가 만든 데이터의 하이퍼 파라미터 튜닝을 너무 대충 한 것 같다는 생각을 하게 된다. 파라미터 튜닝을 좀 더 해봤어야 하는 아쉬움이 남긴 하지만 팀원분이 예측 모델을 너무 잘 해 주셔서 팀원분의 점수를 넘지는 못했을 것 같다.

생성 모델

대회가 끝나기 2주 전부터 부랴부랴 생성 모델에 대한 정보를 찾기 시작했다. 생성 모델이란 무엇이며, 어떤 원리로 동작되는지 등을 공부하기 시작했다.

생성 모델을 공부할수록 이게 생성 모델을 쓰는 대회가 맞나 하는 생각이 들었다. 생성 모델은 내가 공부한 바로는 데이터를 비슷하게 만드는 것인데

대회 주제는

o 최적의 생육 환경 파일 : 생성 AI 모델의 결과를 바탕으로 조성된 최적의 0일~27일차의 시간별 생육 환경과 일별 predicted_weight_g를 필수로 포함한 자유 형식의 파일 (csv, xlsx 등)

이였기 때문이다.

과연 비슷하게 만드는 게 최적의 생육환경을 만드는 것인가?에 대한 고민을 하기 시작했다. 그래서 생각한 게 강화 학습이었다.

머릿속으로 생각한 논리는 뭔가 맞는 것 같았다.

강화 학습으로 y가 줄어들 시 벌점을 주고 y가 늘어날 시 상점을 주고 하는 방식으로 일별 최댓값을 찾을 수 있다고 생각했다.

그렇게 되면 예측 모델을 활용한 생성 모델이 된다 생각했다. 하지만 이게 생성 AI 모델인가 하는 고민과 구현의 어려움으로 인해 일단은 접어두기로 했다.

그래서 GAN을 알아보기로 했다. GAN 자체를 구현하고 해봤을 때는 생성 모델이 되게 재밌다.라고 생각했다. MNIST로 일단 어떻게 돌아가는지에 대해 알아보는데 노이즈 데이터에서 점점 데이터와 비슷해지는 게 재밌었던 것 같다.

하지만 우리는 이미지가 아닌 Tabular 데이터기 때문에 잘 될지 의문이었고 한번 테스트를 해보았다.

GAN

처음 GAN을 테스트했을 때 그래프인데 파란색이 노이즈 데이터인데 epoch가 지날수록 점점 빨간색에 가까워지는 것을 확인할 수 있었다. 하지만 아무리 튜닝을 해도 데이터 값은 엉망이었고, 이거 가능한가?라는 생각이 들었다.

그래서 Tabular 데이터를 생성하는 경우는 없나에 대해 찾아보았다.

결국 생성 모델의 해답은 찾았다.

Modeling Tabular data using Conditional GAN을 읽고 이걸 쓰면 되겠다고 생각했다.

https://arxiv.org/abs/1907.00503

두 개를 참고하여 생성 모델의 방향성을 잡을 수 있었다.

하나의 케이스를 테스트해 보고 잘 된다는 것을 확인했다. 그리고 기초 Baseline을 만들어 두고 어떤 데이터를 넣을지 와 어떻게 활용할지에 대한 고민을 하게 되었다.

프로세스를

Raw data - 생성 모델 - 생성 데이터 - 전처리 - 예측 모델 - 최댓값 도출

로 잡고 만들기 시작했다.

생성 모델을 진행하면서 다음과 같은 어려움을 겪게 되었다.

1. Raw 데이터 생성

생성 모델로 데이터를 생성하면 기존 Raw 데이터의 형식이 당연히 아니다. 기존 데이터는 0 ~ 24가 순서대로 28번 반복되지만 생성 데이터는 그렇지 않고 순서가 뒤죽박죽이다. 그래서 이것을 어떻게 해야 할까에 대한 고민을 했다. 많은 샘플을 뽑고 한다 해도 전처리가 되게 까다로워 힘들다고 생각했다. 이때 팀원분이 아이디어를 낸 게

"예측 모델 Feature(Time) 전처리 방식을 통해 데이터를 생성한 후 데이터를 원래 형식으로 다시 변환"

이였다. 이렇게 하게 되면 기존에 문제였던 순서의 문제가 해결되었다.

2. 전처리

기존 누적값에 대한 Feature가 있는데 이는 과거의 데이터를 포함하고 있었다.

기존에는 28일 치를 한 번에 생성하여 전처리 하는 방식을 고민했다. 하지만 이렇게 하게 되면 주제에서 약간 벗어난다고 생각했는데 일별 최대 잎 중량 도출이라는 주제기 때문에 28일 치를 한 번에 생성하면 일별 최대 잎 중량을 도출할 수 없다고 판단했다.

그래서 일별 최댓값을 도출해서 층을 쌓는 형식으로 변경을 했다. 그렇게 되면 일별 최대 잎 중량과 전처리 부분에서 걸릴 것이 없었다.

0일차 생성 - 예측 - 1일차 생성 후 0일차와 concat - 예측 - 2일차 생성 후 0, 1일차와 concat - ... 이런 방식으로 층을 쌓았다.

이렇게 일별 Max 값을 찾아 최댓값을 도출할 수 있는 환경을 만들게 되었다

이때 예측 모델을 활용해야 해서 전처리 코드를 이해할 필요가 있었는데 이때 약간 힘들었던 게 내가 짠 코드가 아니라 해석하기가... 조금 힘들었다.

결국 전처리 코드를 만들긴 했는데 다 만들고 팀원분이 이거 Case를 그냥 하나로 통일하면 기존에 만든 거 쓸 수 있지 않냐고 하셨다

그때 순간 멍했다. 맞는 말이어서. 왜 이렇게 밖에 생각을 못 했을까에 대한 자책과 함께 집 가면서 한숨을 쉬었던 기억이 난다.

3. 논리적 타당성

생성 모델을 진행하면서 가장 어려웠던 점은 "생성 모델로 나온 결과가 최적의 생육환경이라는 것의 증명" 이였다.

Baseline을 만들어 놓고 이제 어떤 데이터를 넣을까?에 대한 고민만 남아있었다. 다양한 테스트를 하면서 일정 수치 이상은 넘지 못한다는 결론은 알고 있었다. 그 경험적 결과를 바탕으로 어떻게 해야 논리적으로 설득시킬 수 있을까에 대해 고민을 했다.

여기서 약간의 의견 대립이 있었는데 기존 데이터와 논문이었다. 두 가지를 가지고 진짜 오래 얘기했던 기억이 난다.

재밌었다. 같은 주제를 가지고 이렇게 의견이 다를 수 있구나를 체감했고 많이 배웠다. 혼자 했다면 전혀 생각하지 못했을 것이다.

Input data에 대한 적합성과 생성된 데이터에 대한 논리적 타당성을 설명해야 했는데, 난 그게 기존 데이터만을 가지고 해도 충분하다고 판단했었다. 왜냐하면,

1. 논문에서의 생육환경과 기존 데이터와의 조건의 불일치

A라는 공통된 조건이 있어도 다른게 있으면 결국 노이즈 낀 데이터가 된다고 생각했기 때문이다. 증명이 되지 않은 환경을 임의로 쓰면 안 된다고 생각했다.

2. 다른 점이 존재

28일 치의 값은 비슷하지만 이전의 값은 테스트했던 게 더 높았기 때문에 결국 일별 최대 잎 중량을 예측하는 문제에 맞는다고 생각했다.

3. 관점의 차이

input이 논문이 되어선 안된다고 생각했다. 분석한 결과를 바탕으로 input을 넣어야 한다고 생각했는데 논문의 데이터를 바탕으로 넣는다면 분석의 본질이 흐려진다 생각했다. 예측한 모델의 결과를 바탕으로 분석하면서 얻은 '경험적' 결과를 토대로 input을 넣어야 분석의 목적에 맞고 논문은 그저 뒷받침해주는 역할이라고 생각하여 분석 결과와 비슷한 것을 찾아 쓰면 된다고 생각했다.

여기서 반문이 논리적 설명의 부재였다. 맞는 말이었다.

기존 데이터를 사용하여 Input을 넣게 되면 심사위원이 이 환경이 최적의 생육환경이라는 것을 납득시키기가 난해했다. 논문을 바탕으로 넣게 되면 논문이라는 근거가 생기는데 기존 데이터를 넣는다면 근거는 우리의 경험적 결과밖에 없었고, 그것을 설명하기 힘들었다.

게다가 기존 데이터를 넣은 이유를 설명하기 힘들었고 좋은 방법이 떠오르지 않았다.

결국에는 다른 방법으로 하기는 했지만 많은 고민을 하면서 되게 많이 배웠던 시간이었다. 아쉬운 건 더 빨리 정했으면 좋았을 텐데 하는 아쉬움이 남는다.

후기

이번 대회는 정말 힘들었다. 나의 부족함을 너무 많이 깨닫는 대회였다.

결과는 좋지만 만족을 전혀 못하는 대회였다. 저번 대회에서는 내가 잘했다는 생각을 했지만 이번 대회는 못했다는 생각이 든다.

데이터를 보고 했던 생각들을 정리했어야 했는데 기록을 안 하니까 내가 무슨 생각으로 했는지에 대해 계속 잊게 된다.

예측 모델도 생각했던 게 조금 있었는데 테스트를 해봤어야 하는 생각도 들고, 생성 모델에서는 고쳐야 할 점이 너무 많았다.

앞으로는 데이터를 해석하는 능력을 좀 더 키워야겠다는 생각이 든다.

또, 협업에 있어서 내가 아직 많이 부족하다고 느꼈다.

1. 코드 관리는 했지만 기준점이 너무 '나'에게 맞춰진 게 아닌가 하는 생각이 들었다.

사람마다 스타일이 엄청 다른데 너무 나에게 맞춰달라 한 게 없지 않아 있던 것 같다.

2. 팀원들이 어떻게 하면 더 잘 이해할 수 있을까에 대한 고민이 부족했다.

늦게 팀에 합류하신 분들을 위해 어디까지 진행되었고 어떻게 할 예정 등에 대한 설명이 부족했다. 들어오셨을 때 이거 보고 있다고만 말했던 것 같은데 좀 더 정리해서 말씀드렸으면 좋았을 것 같다는 생각을 한다.

3. 일정관리가 부족했다.

시간이 진짜 부족했다. 일정을 잡고 언제부터 언제까지는 이거 하고 이런 게 명확했으면 더 좋았을 것 같다는 생각을 하게 되었다.

생각한 게 있으면 바로 공유드렸으면 일정관리 면에서 더 좋았을 것 같다.

협업 면에서 어떻게 해야 좀 더 좋을지에 대한 고민을 해봐야겠다.

별개로 멘탈 관리가 진짜 중요하다는 걸 느꼈다. 중간중간 머리가 너무 복잡해서 코드를 못 짜겠는 순간이 있었다. 멘탈 관리가 안 돼서 그만할까 하는 생각도 했다.

원래 스트레스를 뛰면서 푸는데 대회한다는 핑계와 춥다는 핑계를 대며 안 뛰니까 스트레스가 계속 쌓여만 갔던 것 같다.

앞으로는 조절 좀 해야 할 것 같다.

코드는 여기에

https://github.com/Myungbin/Lettuce-Growth-Environment-Prediction

 

-