첫 번째 딥러닝 라이브러리는 단순히 모델을 실행하는 것 이상의 역할을 합니다. 그것은 그래디언트(gradient), 레이어(layer), 데이터 흐름에 대해 생각하는 방식을 형성합니다. 잘못된 라이브러리를 선택하면 신경망이 실제로 어떻게 작동하는지 배우는 대신, 보일러플레이트(boilerplate) 코드와 싸우느라 몇 주를 허비하게 됩니다. 올바른 라이브러리를 선택하면 코드가 방해가 되지 않기 때문에 개념들이 자연스럽게 이해될 것입니다.

대부분의 입문자는 선택지를 Keras, PyTorch, TensorFlow 세 가지 라이브러리로 좁힙니다. JAX도 있지만, Jacobian이 무엇인지 알기 전까지는 무시해도 좋습니다.

"입문자 친화적"이라는 말이 실제로 의미하는 것

라이브러리가 단순히 문서가 방대하다고 해서 친화적인 것은 아닙니다. 코드가 튜토리얼에서 본 수학 공식처럼 읽히고, 에러 메시지가 C++ 백엔드의 스택 트레이스(stack trace)를 쏟아내는 대신 사용자의 실수를 정확히 지목할 때 친화적이라고 할 수 있습니다. 여러분은 프레임워크 내부 깊숙한 곳에 숨겨진 텐서 모양 불일치(tensor shape mismatch)를 찾는 대신, 학습률(learning rate)과 활성화 함수(activation function)에 대해 고민하고 싶을 것입니다.

Keras: 결과물을 바로 확인하고 싶다면 여기서 시작하세요

Keras는 단순한 아이디어에서 시작되었습니다. 커피 한 잔을 마시는 시간 안에 아이디어를 학습된 모델로 구현할 수 있어야 한다는 것입니다. Keras는 역전파(backpropagation)와 그래프 최적화의 복잡성을 깔끔한 API 뒤로 숨겨주므로, 완전하게 작동하는 이미지 분류기를 단 10여 줄의 Python 코드로 작성할 수 있는 경우가 많습니다.

Sequential 객체 안에 레이어를 쌓아 모델을 정의하고, model.compile()을 호출하여 옵티마이저(optimizer)와 손실 함수(loss function)를 연결한 다음, model.fit()을 호출하여 학습시킵니다. 문법이 마치 체크리스트처럼 느껴집니다. 입력 형태(Input shape)? 완료. Dense 레이어? 완료. 학습 루프? 처리 완료. 이를 통해 초기 단계에서 실제로 중요한 것들에 집중하며 실험할 수 있습니다. 레이어를 하나 더 추가하면 도움이 될까요? ReLU 대신 sigmoid를 사용해야 할까요? 배치 크기(batch size)를 바꾸면 어떻게 될까요?

설정 파일(configuration files)의 늪에 빠지지 않고 레이어와 옵티마이저가 무엇을 하는지 배우는 것이 목표라면, Keras는 그 마찰을 제거해 줍니다. 패키지를 설치하고 한 시간 안에 실제 이미지로 작동하는 합성곱 신경망(convolutional network)을 실행할 수 있습니다. Keras는 기본적으로 TensorFlow 위에서 동작하므로, 상위 수준(high-level) API를 벗어나지 않고도 프로덕션급 데이터 파이프라인을 사용할 수 있습니다.

하지만 정해진 길을 벗어나면 트레이드오프(trade-off)가 나타납니다. 중간 활성화 값(intermediate activations)에 의존하는 사용자 정의 손실 함수를 작성해야 하거나, 학습 중에 역전파(backward pass) 과정을 수정하고 싶다면 Keras는 제약이 많게 느껴질 수 있습니다. 탈출구(escape hatches)가 있긴 하지만, 이를 사용하려면 결국 로우 레벨(raw) 프레임워크 코드로 내려가야 하는 경우가 많습니다. 커스텀 연구 로직을 구현할 때는 이 장벽이 실질적으로 다가옵니다.

PyTorch: 내부 구조를 직접 보며 배우기

PyTorch는 신경망을 일반적인 Python 프로그램처럼 다룹니다. torch.nn.Module을 상속받아 모델을 정의합니다. 순전파(forward pass)는 입력이 출력이 되는 과정을 설명하는 단순한 Python 메서드일 뿐입니다. loss.backward()를 호출하면 PyTorch가 즉석에서 그래디언트를 계산합니다.

이는 PyTorch가 계산 그래프(computation graph)를 동적으로 구축하기 때문입니다. 일부 프레임워크는 데이터가 입력되기 전에 전체 모델 구조를 미리 정의할 것을 요구합니다. 반면 PyTorch는 실제로 네트워크에 배치를 통과시킬 때까지 기다립니다. 배치마다 입력 크기가 바뀌거나, 텐서 모양 불일치를 디버깅하기 위해 순전파 중간에 텐서를 출력하고 싶어도 프레임워크는 불평하지 않습니다. 표준 디버거를 사용하면 됩니다. 모델 클래스 안에 print() 문을 넣으면 됩니다. 모든 텐서 차원이 퍼즐처럼 느껴질 때, 이러한 단순함은 디버깅을 일반적인 프로그래밍처럼 느껴지게 하므로 매우 중요합니다.

순전파가 어떻게 예측을 생성하는지, 역전파가 어떻게 오차를 분산시키는지, 옵티마이저가 어떻게 가중치(weights)를 업데이트하는지 등 학습이 실제로 어떻게 작동하는지 이해하고 싶다면, PyTorch는 여러분이 내부를 들여다보도록 강제합니다. 이러한 투명성 덕분에 PyTorch는 현재 연구 분야의 선두를 달리고 있으며, 대부분의 새로운 AI 채용 공고에 등장합니다. arXiv에서 논문을 읽을 때, 공식 구현체가 PyTorch로 작성되었을 확률이 매우 높습니다.

TensorFlow: 모델이 어디에서 실행될지를 생각하세요

TensorFlow는 코드가 장황하고 배우기 어렵다는 평판이 있었습니다. 하지만 Keras가 공식 고수준(high-level) API가 되면서 많은 것이 변했습니다. 최신 버전에서는 Keras를 임포트하면 인지하지 못하더라도 대개 TensorFlow 위에서 실행됩니다. 하지만 모델 학습 이후에 일어나는 일들 때문에 TensorFlow는 여전히 별개의 선택지로서 중요한 의미를 갖습니다.

이 생태계는 배포를 위해 구축되었습니다. TensorFlow Lite는 모델을 압축하여 메모리 제한이 엄격한 휴대폰, 마이크로컨트롤러 및 산업용 센서에서 실행할 수 있도록 합니다. TensorFlow.js는 데이터를 서버로 전송하지 않고 브라우저 내부에서 직접 추론을 수행합니다. TensorFlow Serving은 대규모 운영 환경에서 모델 버전 관리 및 배치 예측을 처리합니다.

프로젝트에 엄격한 물리적 제약이 있을 때 TensorFlow를 선택하십시오