딥러닝 기반 콘텐츠 추천 구조
그로스 마케팅의 핵심은 데이터 기반의 개인화(Personalization)다. 즉, 사용자 개개인의 행동 데이터를 분석하여 "누가, 언제, 어떤 콘텐츠를 좋아하는가"를 예측하고 이를 바탕으로 재방문율(Retention), 전환율(Conversion), 체류시간(Engagement)을 높이는 것이다.
기존의 마케팅 자동화 도구들은 규칙 기반으로 작동했지만, 딥러닝 기반 추천 시스템은 사용자와 콘텐츠 간의 복잡한 상호작용을 학습한다.
1. 시스템 개념 구조

2. 코드 예제
# -----------------------------
# 추천 모델 정의
# -----------------------------
class Recommender(nn.Module):
"""사용자/콘텐츠 임베딩을 이용한 딥러닝 추천 모델"""
def __init__(self, num_users, num_items, emb_dim=16):
super().__init__()
self.user_emb = nn.Embedding(num_users, emb_dim)
self.item_emb = nn.Embedding(num_items, emb_dim)
def forward(self, user_ids, item_ids):
user_vec = self.user_emb(user_ids)
item_vec = self.item_emb(item_ids)
return (user_vec * item_vec).sum(dim=1) # 내적 기반 예측 점수
# -----------------------------
# 데이터 준비
# -----------------------------
num_users = df['user_id'].nunique()
num_items = df['item_id'].nunique()
user_tensor = torch.tensor(df['user_id'].values, dtype=torch.long)
item_tensor = torch.tensor(df['item_id'].values, dtype=torch.long)
rating_tensor = torch.tensor(df['rating'].values, dtype=torch.float32)
# -----------------------------
# 모델 학습
# -----------------------------
model = Recommender(num_users, num_items)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
criterion = nn.MSELoss()
print("\n[학습 시작]")
for epoch in range(300):
pred = model(user_tensor, item_tensor)
loss = criterion(pred, rating_tensor)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 50 == 0:
print(f"Epoch {epoch+1:3d} | Loss: {loss.item():.4f}")
# -----------------------------
# 추천 함수 정의
# -----------------------------
def recommend_for_user(user_id, top_k=3):
"""특정 사용자에게 top-k 콘텐츠 추천"""
model.eval()
all_items = torch.arange(num_items)
user_input = torch.tensor([user_id] * num_items)
scores = model(user_input, all_items).detach()
top_items = torch.topk(scores, top_k).indices.tolist()
return top_items
- Adam : 최적화 함수 (경사 하강법의 발전형)
- MSELoss : 손실 함수 (예측값 - 실제값 차이 측정)
- Embedding Layer : 사용자 / 아이템의 벡터화
- Forward 연산 : 내적 기반 예측
- Epoch : 전체 데이터 1회 학습 주기
- torck.topk : 상위 콘텐츠 추천 (Top-K)
3. 결과

4. 마케팅 인사이트
| 분석 항목 | 의미 |
| 개인화 정확도 | 사용자의 관심 장르(패션/IT/여행 등)에 따른 맞춤 추천 가능 |
| 세션 유지율 향상 | 사용자에게 “흥미로운 콘텐츠”만 보여줌으로써 체류시간 증가 |
| 전환율(CVR) 개선 | 추천 콘텐츠가 구독/결제/클릭 행동으로 이어질 확률 상승 |
| A/B 테스트 연계 | 추천 노출 vs 무작위 노출 그룹 간 CTR·Retention 비교로 최적화 |
| 데이터 피드백 루프 | 사용자의 반응 데이터를 다시 학습시켜 추천 품질을 지속 개선 |
👩🏻💻 딥러닝 초보(나)를 위한 코드 뜯어보기
# ============================================
# 딥러닝 기반 콘텐츠 추천 시스템 (그로스마케팅 예시)
# ============================================
import torch # PyTorch: 딥러닝 모델 구축 및 학습용 라이브러리
import torch.nn as nn # 신경망 모듈 (nn.Module 등 포함)
import pandas as pd # 데이터프레임 형태로 데이터 관리
import random # 난수 생성 (사용자/콘텐츠 랜덤 선택)
import numpy as np # 수치 연산 및 랜덤 시드 설정용
# -----------------------------
# 1. 데이터 생성 (마케팅 로그 기반 가정)
# -----------------------------
random.seed(42) # random 모듈의 결과를 고정 (재현성 확보)
np.random.seed(42) # numpy의 난수 시드도 고정
users = list(range(10)) # 사용자 ID: 0~9 → 총 10명
items = list(range(15)) # 콘텐츠 ID: 0~14 → 총 15개
genres = ['패션', 'IT', '여행', '헬스', '금융'] # 관심 장르 5개 정의
data = [] # 데이터 저장용 리스트 생성
for u in users: # 각 사용자마다 반복
preferred_genre = random.choice(genres) # 개인의 선호 장르 1개 랜덤 선택
for _ in range(10): # 각 사용자가 10개 콘텐츠와 상호작용했다고 가정
item_id = random.choice(items) # 임의의 콘텐츠 ID 선택
genre_match = 1 if random.random() < 0.7 else 0 # 70% 확률로 선호 장르 일치
rating = random.randint(4, 5) if genre_match else random.randint(1, 3)
# 선호 장르일 경우 평점 높게(4~5), 아니면 낮게(1~3)
data.append([u, item_id, rating, preferred_genre]) # 한 행 단위로 저장
# pandas DataFrame으로 변환
df = pd.DataFrame(data, columns=['user_id', 'item_id', 'rating', 'fav_genre'])
print("데이터 예시:")
print(df.head()) # 상위 5개 행 출력 (데이터 확인용)
# -----------------------------
# 2. 추천 모델 정의
# -----------------------------
class Recommender(nn.Module): # nn.Module을 상속받는 사용자 정의 모델 클래스
"""사용자/콘텐츠 임베딩을 이용한 딥러닝 추천 모델"""
def __init__(self, num_users, num_items, emb_dim=16):
super().__init__() # 부모 클래스 초기화
# 사용자 임베딩: user_id를 emb_dim(16차원) 벡터로 매핑
self.user_emb = nn.Embedding(num_users, emb_dim)
# 아이템 임베딩: item_id를 emb_dim(16차원) 벡터로 매핑
self.item_emb = nn.Embedding(num_items, emb_dim)
def forward(self, user_ids, item_ids):
# 사용자/아이템 ID → 임베딩 벡터로 변환
user_vec = self.user_emb(user_ids)
item_vec = self.item_emb(item_ids)
# 두 벡터의 내적(dot product)을 통해 예측 평점 계산
# 내적값이 클수록 선호도가 높다고 판단
return (user_vec * item_vec).sum(dim=1) # forward 연산: 예측 점수 출력
# -----------------------------
# 3. 데이터 준비
# -----------------------------
num_users = df['user_id'].nunique() # 전체 사용자 수 (10)
num_items = df['item_id'].nunique() # 전체 아이템 수 (15)
# 학습용 데이터 텐서로 변환 (PyTorch는 텐서 단위 연산 필수)
user_tensor = torch.tensor(df['user_id'].values, dtype=torch.long) # 사용자 ID
item_tensor = torch.tensor(df['item_id'].values, dtype=torch.long) # 콘텐츠 ID
rating_tensor = torch.tensor(df['rating'].values, dtype=torch.float32) # 평점 (실수형)
# -----------------------------
# 4. 모델 학습
# -----------------------------
model = Recommender(num_users, num_items) # Recommender 모델 인스턴스 생성
# Adam Optimizer : 경사 하강법 기반의 파라미터 갱신 방법
# momentum + adaptive learning rate로 빠르고 안정적으로 수렴함
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
# MSELoss : 손실 함수 (Mean Squared Error)
# 예측값(pred)과 실제값(rating)의 차이를 제곱해 평균낸 값
criterion = nn.MSELoss()
print("\n[학습 시작]")
for epoch in range(300): # 전체 데이터셋을 300번 반복 학습 (epoch = 1회 전체 학습 주기)
pred = model(user_tensor, item_tensor) # 모델 예측 수행 (forward)
loss = criterion(pred, rating_tensor) # 예측값과 실제값 간 손실(loss) 계산
optimizer.zero_grad() # 이전 단계에서 계산된 기울기 초기화 (중첩 방지)
loss.backward() # 역전파(Backpropagation): 각 파라미터별 기울기 계산
optimizer.step() # Adam을 이용해 파라미터 갱신 (경사 하강)
# 50 epoch마다 학습 상태 출력
if (epoch + 1) % 50 == 0:
print(f"Epoch {epoch+1:3d} | Loss: {loss.item():.4f}")
# -----------------------------
# 5. 추천 함수 정의
# -----------------------------
def recommend_for_user(user_id, top_k=3):
"""특정 사용자에게 top-k 콘텐츠 추천"""
model.eval() # 평가 모드 (dropout 등 비활성화)
all_items = torch.arange(num_items) # 전체 콘텐츠 ID 리스트 생성
user_input = torch.tensor([user_id] * num_items) # 사용자 ID를 모든 콘텐츠에 복제
scores = model(user_input, all_items).detach() # 모든 콘텐츠 예측 점수 계산
top_items = torch.topk(scores, top_k).indices.tolist() # 점수 상위 K개 아이템 ID 추출
return top_items
# -----------------------------
# 6. 추천 결과 출력
# -----------------------------
print("\n[사용자별 추천 콘텐츠]")
for u in range(num_users): # 모든 사용자에 대해 반복
rec_items = recommend_for_user(u, top_k=3) # 사용자별 상위 3개 추천 콘텐츠 추출
print(f"사용자 {u} 추천 콘텐츠 ID: {rec_items}") # 결과 출력
연습문제 풀이
Q1. Recommender 클래스에서 forward() 함수가 수행하는 연산의 의미를 설명하시오.
A1. 모델의 순전파 과정에서 사용자와 아이템 간의 유사도를 계산하는 핵심 단계다. 두 벡터의 내적을 계산하여 사용자가 해당 아이템을 얼마나 선호할지 예측한다.
Q2. nn.Embedding()을 사용하는 이유와, 일반적인 선형층(nn.Linear)과의 차이를 설명하시오.
A2. 임베딩은 범주형 데이터를 벡터 형태로 표현하기 위해 사용된다. 반면, Linear은 이미 수치형 피처가 주어졌을 때 사용하는 층이다. 임베딩은 ID 자체를 벡터로 바꾸는 역할을 수행하고, Linear는 이미 벡터화된 값을 변환하는 역할을 한다는 점에서 차이가 있다.
Q3. 다음 코드에서 학습률(lr)을 0.01보다 너무 크게 설정하면 학습 과정에서 어떤 현상이 발생할 수 있는가?
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
A3. 가중치가 업데이트 반복 때마다 너무 큰 수치로 변화하여 최적점을 지나치게 이동하게 된다. 이로 인해 손실이 제대로 줄어들지 않아 학습이 불안정해지거나 연산 오류가 발생할 수 있다.
Q4. recommend_for_user() 함수는 특정 사용자의 추천 콘텐츠를 예측한다. 이 함수를 수정하여, 추천 결과를 콘텐츠 ID와 예측 점수(score) 를 함께 출력하도록 코드를 작성하시오.
A4. 기존 recommend_for_user() 함수에 콘텐츠 ID 및 예측 점수 리스트를 반환하도록 return 추가
def recommend_for_user(user_name, top_k=5):
model.eval()
user_id = user2idx[user_name]
all_items = torch.arange(num_items)
user_input = torch.tensor([user_id] * num_items)
scores = model(user_input, all_items).detach()
top_scores, top_indices = torch.topk(scores, top_k)
recommended_contents = []
for i in range(top_k):
content_id = list(content2idx.keys())[top_indices[i]]
score = float(top_scores[i].item())
recommended_contents.append((content_id, score))
return recommended_contents
print("\n[사용자별 추천 콘텐츠 Top 5]")
for user in df['user_id'].unique():
recs = recommend_for_user(user, top_k=5)
print(f"\n▶ {user} 추천 결과:")
for content, score in recs:
print(f" {content} | 예측 점수: {score:.4f}")
Q5. 현재 모델은 단순히 사용자와 아이템의 임베딩만 고려한다. fav_genre(선호 장르) 정보를 모델에 반영하려면 어떤 방법으로 모델 구조를 확장할 수 있는지 설명하시오.
A5. 선호 장르를 별도의 임베딩 벡터로 학습시켜 사용자 정보와 함께 입력한다.
캠페인 최적화를 위한 역전파 및 최적화 기법
그로스 마케팅은 데이터 기반의 실험과 학습을 통해 광고 캠페인의 성과를 지속적으로 개선하는 과정이다. 캠페인 성과를 높이기 위해서는 광고 노출, 클릭률(CTR), 전환율(CVR), 구매 금액 등 다양한 데이터를 분석하고 그 결과를 모델의 파라미터(가중치)에 반영해야 한다.
이때 딥러닝의 핵심 메커니즘인 "역전파(Backpropagation)"가 사용된다.
💡 그로스 마케팅에서 역전파가 중요한 이유
| 항목 | 설명 |
| 성과 피드백 루프 구축 | 광고 집행 후 결과 데이터를 모델 학습에 재사용 |
| 자동화된 캠페인 개선 | 사람이 일일이 수정하지 않아도 가중치가 자동 조정 |
| 효율 극대화 | 불필요한 예산 낭비 최소화, 타깃 정밀도 향상 |
| 예측형 마케팅 | 클릭·전환 가능성을 사전에 예측해 개인화 캠페인 제공 |
- 딥러닝의 역전파 = “성과 기반 자동 의사결정”의 엔진
- 캠페인 데이터를 통해 모델이 스스로 학습하며 광고 효율(ROAS, CPA, CVR) 최적화
1. 개념 구조
[데이터 수집] : 광고 노출수, 클릭수, 전환수, 예산, 타깃 속성
[전방향 계산] : 예측된 전환확률(CVR_pred)
[오차 계산] : 실제값(CVR_actual) - 예측값(CVR_pred)
[역전파] : 오차를 각 가중치에 전달해 그래디언트 계산
[최적화] : 옵티마이저(Adam, SGD 등)가 가중치를 업데이트
[반복 학습] : 손실 감소 → 캠페인 효율 자동 향상
2. 코드 예제
# -----------------------------
# 2. 숫자형 데이터 전처리
# -----------------------------
df['ad_type'] = df['ad_type'].astype('category').cat.codes
df['platform'] = df['platform'].astype('category').cat.codes
X = df[['ad_type', 'platform', 'budget', 'impressions', 'clicks']].values
y = df['conversion_rate'].values
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)
# -----------------------------
# 3. 딥러닝 모델 정의
# -----------------------------
class CampaignModel(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(5, 16)
self.fc2 = nn.Linear(16, 8)
self.fc3 = nn.Linear(8, 1)
def forward(self, x):
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
return self.fc3(x)
model = CampaignModel()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
# -----------------------------
# 4. 학습 (역전파 및 최적화)
# -----------------------------
print("\n[학습 시작]")
for epoch in range(300):
pred = model(X_tensor)
loss = criterion(pred, y_tensor)
optimizer.zero_grad() # 그래디언트 초기화
loss.backward() # 역전파(Backpropagation)
optimizer.step() # 가중치 업데이트
if (epoch + 1) % 50 == 0:
print(f"Epoch {epoch+1:3d} | Loss: {loss.item():.6f}")
# -----------------------------
# 5. 예측 및 비교
# -----------------------------
model.eval()
with torch.no_grad():
sample = torch.tensor([[0, 1, 120, 5000, 200]], dtype=torch.float32)
pred_cvr = model(sample).item()
print(f"\n예측 전환율(CVR) 예시: {pred_cvr:.4f}")
3. 결과

4. 마케팅 인사이트
| 항목 | 설명 |
| 역전파를 통한 성과 피드백 | 모델은 실제 캠페인 데이터를 학습하면서, 어떤 광고 조합이 높은 전환율을 만드는지 스스로 학습함 |
| Adam 옵티마이저의 효율성 | 학습률을 자동 조정해 빠른 수렴 및 안정적인 성능 확보 |
| 예산 대비 효율 예측 가능 | 예산, 노출수, 클릭수를 입력하면 예상 전환율(CVR)을 예측 가능 |
| 자동화된 의사결정 기반 | 학습 결과를 활용해 “다음 캠페인에 예산을 어디에 배분할지” 자동 판단 가능 |
| 데이터 피드백 루프 완성 | 실험 → 결과 → 역전파 → 개선으로 이어지는 성장 사이클 구축 |
연습문제 풀이
Q1. optimizer.zero_grad()가 수행하는 역할을 설명하시오. (힌트: 역전파 과정에서 그래디언트 누적이 일어나면 어떤 문제가 생기는가?)
A1. 이전 학습 단계에서 계산된 기울기를 모두 0으로 리셋하는 역할을 수행하여, 이전 배치의 기울기 누적으로 인해 잘못된 방향으로 파라미터가 업데이트 되지 않도록 방지한다.
Q2. 아래 코드에서 loss.backward()가 수행하는 구체적인 연산 과정을 설명하시오.
loss.backward()
(힌트: 오차 역전파 과정에서 손실 함수의 기울기가 어떻게 계산되고, 각 가중치에 어떻게 전달되는가?)
A2. 역전파를 수행하는 메서드로, 손실 함수가 각 파라미터에 어떤 영향을 주는지를 자동으로 계산한다. 출력층 → 은닉층 → 입력층 방향으로 가중치의 미분값이 계산되어 모델의 모든 파라미터 객체에 기울기 값이 저장된다.
Q3. optimizer.step()이 하는 일은 무엇이며, 어떤 수학적 원리에 기반하여 모델의 파라미터를 업데이트하는가?
(힌트: Adam, SGD와 같은 최적화 기법은 공통적으로 어떤 값을 이용해 파라미터를 조정하는가?)
A3. 경사 하강법 원리에 기반하여 앞에서 계산된 기울기와 학습률을 이용해 모델의 가중치 파라미터를 업데이트한다.
🧐 추가 풀이
Q4. 다음과 같은 모델 구조에서 활성화 함수로 ReLU를 사용하는 이유를 설명하시오.
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
(힌트: ReLU 함수가 학습 안정성과 비선형 표현력에 어떤 영향을 주는가?)
A4. ReLU는 비선형성을 부여하여 모델이 복잡한 패턴을 학습할 수 있게 하고, 음수 구간의 출력을 0으로 만들어 기울기 소실문제를 줄여준다. 또한 연산이 단순해 학습 속도가 빠르고 학습의 안정성과 효율성을 높여준다.
Q5. 현재 모델은 3개의 완전연결층(fc1, fc2, fc3)으로 구성되어 있다. 모델이 과적합(overfitting)되는 경우 이를 완화하기 위한 정규화(regularization) 방법 2가지를 제시하고 설명하시오. (힌트: Dropout, L2 정규화, 조기 종료(Early Stopping) 등)
A5.
1️⃣ Dropout : 학습 중 일부 뉴런을 임의로 비활성화하여 특정 뉴런에 과도하게 의존하지 않도록 한다.
→ 다양한 신경망 조합을 학습하게 되어 일반화 성능이 향상된다.
2️⃣ L2 정규화(Weight Decay) : 가중치의 크기가 커지지 않도록 제어하여 복잡한 모델이 되는 것을 방지한다.
→ 손실 함수에 가중치 제곱항을 추가해 모델의 복잡도를 줄이고 과적합을 완화한다.
과적합 방지를 위한 드롭아웃 정규화 적용법
그로스 마케팅에서는 광고 캠페인, 콘텐츠 추천, 고객 이탈 예측 등 데이터 기반 모델을 통해 사용자의 행동을 예측하고 마케팅 효율을 극대화한다.
하지만 데이터가 제한적이거나 편향되어 있을 때, 모델이 훈련 데이터에만 지나치게 맞춰져 실제 캠페인 환경에서는 성능이 급격히 저하되는 문제가 발생한다. 이를 과적합(Overfitting) 이라고 하며 딥러닝 기반 마케팅 모델에서는 반드시 해결해야 할 과제이다. 그로스 마케팅 모델이 과적합되면 아래와 같은 문제가 발생한다.
| 문제점 | 영향 |
| 훈련 데이터에만 최적화 | 실제 광고 집행 시 성과 예측 정확도 급감 |
| 신규 타깃군 일반화 실패 | 새로운 고객에게 잘못된 광고 추천 |
| 예산 낭비 | 클릭 가능성이 낮은 세그먼트에 광고 노출 |
| 캠페인 효율 저하 | ROAS, CTR, CVR 등 주요 지표 하락 |
→ 이를 방지하기 위한 대표적인 딥러닝 기법이 바로 드롭아웃 (Dropout) 정규화
드롭아웃(Dropout)
- 학습 과정에서 일부 뉴런을 무작위로 비활성화(drop)하여 모델이 특정 노드나 패턴에 과도하게 의존하지 않도록 만듦
- 즉, 모델의 일반화 성능을 향상시키는 정규화 기법
1. 개념 구조
[입력 데이터] → [Dense Layer 1] → [ReLU] → [Dropout(p=0.3)]
↓
[Dense Layer 2] → [ReLU] → [Dropout(p=0.3)]
↓
[출력 Layer] → [예측 결과]
- Dense : 모든 입력이 모든 출력 뉴런과 연결되어 있는 층
- p=0.3 : 학습 중 30%의 뉴런을 랜덤하게 끄겠다는 의미
- 훈련 시에만 적용되며, 추론(inference) 시에는 자동 비활성화되어 전체 노드를 사용함
2. 코드 예제
# -----------------------------
# 2. 전처리
# -----------------------------
df['ad_type'] = df['ad_type'].astype('category').cat.codes
df['platform'] = df['platform'].astype('category').cat.codes
X = df[['ad_type', 'platform', 'budget', 'impressions', 'clicks']].values
y = df['conversion_rate'].values
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)
# -----------------------------
# 3. 모델 정의 (Dropout 적용)
# -----------------------------
class CampaignModel(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(5, 32)
self.dropout1 = nn.Dropout(0.3) # 30% 드롭아웃
self.fc2 = nn.Linear(32, 16)
self.dropout2 = nn.Dropout(0.3)
self.fc3 = nn.Linear(16, 1)
def forward(self, x):
x = F.relu(self.fc1(x))
x = self.dropout1(x) # 첫 번째 드롭아웃
x = F.relu(self.fc2(x))
x = self.dropout2(x) # 두 번째 드롭아웃
return self.fc3(x)
model = CampaignModel()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
# -----------------------------
# 4. 학습
# -----------------------------
print("\n[학습 시작]")
for epoch in range(300):
model.train()
pred = model(X_tensor)
loss = criterion(pred, y_tensor)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 50 == 0:
print(f"Epoch {epoch+1:3d} | Loss: {loss.item():.6f}")
# -----------------------------
# 5. 예측
# -----------------------------
model.eval()
with torch.no_grad():
sample = torch.tensor([[0, 1, 120, 6000, 300]], dtype=torch.float32)
pred_cvr = model(sample).item()
print(f"\n예측 전환율(CVR) 예시: {pred_cvr:.4f}")
3. 결과

4. 마케팅 인사이트
| 항목 | 설명 |
| 드롭아웃 효과 | 학습 시 일부 뉴런을 무작위로 비활성화함으로써, 특정 패턴에 과도하게 의존하지 않음 |
| 모델의 일반화 향상 | 실제 신규 캠페인·타깃군 데이터에 대한 예측 정확도 향상 |
| 과적합 완화 | 훈련 데이터 손실은 다소 느리게 줄지만, 테스트 환경에서의 성능이 안정화 |
| 캠페인 예측 안정성 확보 | 실제 광고 집행 환경의 불확실성에도 견고한 예측 제공 |
| 성장 마케팅에 기여 | “학습 데이터 편향 최소화 → 더 많은 사용자 세그먼트에 일관된 효율 제공”으로 이어짐 |
연습문제 풀이
Q1. nn.Dropout()의 동작 원리를 설명하시오. (힌트: 학습 과정에서 일부 뉴런을 무작위로 비활성화하는 이유는 무엇인가?)
A1. 일부 뉴런을 무작위로 비활성화하여 모델이 특정 노드나 패턴에 과도하게 의존하지 않도록 만들고 과적합을 방지한다.
Q2. 다음 코드에서 model.train()과 model.eval()의 차이를 설명하시오.
model.train()
...
model.eval()
(힌트: 드롭아웃과 배치 정규화의 동작 방식이 두 모드에서 어떻게 달라지는가?)
A2.
1️⃣ train : 학습 모드로 드롭아웃이 활성화되어 일부 뉴런을 무작위로 꺼서 학습한다.
2️⃣ eval : 추론 모드로 드롭아웃이 비활성화되어 모든 뉴런을 사용한다. 배치 정규화의 경우 학습 중 저장해둔 값을 사용한다.
Q3. 드롭아웃 비율을 0.3에서 0.8로 높이면 모델의 학습 성능과 일반화 성능에 어떤 영향을 미칠 수 있는가?
(힌트: 너무 높은 드롭아웃 비율은 어떤 부작용을 초래할 수 있는가?)
A3. 더 많은 뉴런이 무작위로 비활성화되어 학습 시 과적합은 줄어들 수 있지만 정보의 손실이 커져 학습이 불안정하고 모델의 성능이 저하될 수 있다.
Q4. 현재 모델은 드롭아웃을 fc1, fc2 사이에 적용하고 있다. 드롭아웃을 fc3 이후 출력단에 적용하지 않는 이유를 설명하시오.
(힌트: 예측 결과가 확률이나 실수 값으로 해석될 때 드롭아웃이 적용되면 어떤 문제가 발생할까?)
A4. fc3 이후 출력층은 모델이 최종 예측 값을 계산하는 단계이므로 이때 뉴런을 비활성화할 경우 예측이 불안정하거나 왜곡될 수 있다.
🧐 추가 풀이
Q5. 드롭아웃 외에도 과적합(overfitting)을 방지하기 위한 대표적인 방법 2가지를 제시하고 간단히 설명하시오.
(힌트: 조기 종료(Early Stopping), L2 정규화, 데이터 증강, 교차 검증 등)
A5.
1️⃣ 조기 종료(Early Stopping) : 검증 데이터의 손실이 일정 시점 이후 더 이상 감소하지 않으면 학습을 중단하는 방법이다. 불필요하게 오래 학습해 훈련 데이터에만 과도하게 맞춰지는 것을 막아 과적합을 방지한다.
2️⃣ L2 정규화(Weight Decay) : 손실 함수에 가중치 제곱항을 추가해 가중치가 과도하게 커지는 것을 억제한다. 복잡한 모델이 되는 것을 방지하여 일반화 성능을 향상시킨다.
에이전트 코딩으로 앱 개발하기
| 구분 | 실행 환경 | 개발 언어/툴 | 성능 | 배포 | 장점 |
| Web App | 브라우저 | HTML, CSS, JS | 낮음 | URL 접속 | 개발 빠름, 플랫폼 제약 없음 |
| Hybrid App | 앱스토어 | JS + Framework (Flutter, RN 등) | 중간 | 앱스토어 | 멀티 플랫폼, 빠른 배포 |
| Native App | OS별 (Android/iOS) | Java/Kotlin, Swift | 높음 | 앱스토어 | 최고 성능, 완전 연동 |
- 프로토타입 단계에서는 WebApp(React or Streamlit 기반)으로 만드는 게 가장 현실적이고 빠름
- 실서비스 단계에서 Hybrid or Native로 확장하면 됨
Native App (네이티브 앱)
특정 OS(Android, iOS)에 최적화된 언어와 개발 환경으로 만든 앱으로, 각각의 플랫폼에서 직접 실행되며 디바이스 기능과 완전히 연동됨
- 개발 환경
- Android: Android Studio (Java / Kotlin)
- iOS: Xcode (Swift / Objective-C)
- 장점
- 최고 성능 & 빠른 반응 속도
- 모든 기기 기능(카메라, GPS, 센서 등) 완전 활용 가능
- 단점
- 플랫폼마다 별도 개발 필요 (Android, iOS 각각 코딩)
- 개발 비용 & 유지보수 부담 증가


이메일 배너 광고에 적합한 활성화 함수 이해
그로스 마케팅은 데이터 기반으로 사용자 반응(클릭, 구매, 구독)을 예측하고, 그 결과를 바탕으로 광고 소재와 타깃 전략을 최적화한다. 특히 이메일 배너 광고(Email Banner Ads)는 사용자의 클릭 의도나 전환 가능성이 상대적으로 미세하게 구분되므로, 딥러닝 모델이 비선형적인 반응 패턴(Non-linear Behavior)을 잘 표현할 수 있어야 한다.
이때 핵심 역할을 하는 것이 바로 활성화 함수(Activation Function)이다. 활성화 함수는 입력 신호를 적절히 변환하여 “이 사용자가 배너를 클릭할지 말지”와 같은 확률적 결과를 모델이 학습할 수 있게 한다.
활성화 함수가 이메일 광고에서 중요한 이유
| 마케팅 맥락 | 설명 |
| 비선형 반응 예측 | 사용자 클릭 행동은 단순 비례 관계가 아닌 ‘임계점 반응’ 형태로 나타남 |
| CTR 예측 모델 정밀도 향상 | 적절한 활성화 함수를 선택하면 클릭 예측 확률 분포가 안정적 |
| 학습 효율 개선 | 기울기 소실/폭주 문제를 줄여 모델이 빠르고 안정적으로 학습 |
| 캠페인 자동화 성능 향상 | 광고 문구·배너 디자인 등 변수 간 상호작용을 효과적으로 반영 |
1. 개념 구조
[입력: 광고데이터] : 광고유형, 클릭수, 노출수, 배너크기, 이메일열람시간 등
[은닉층1] → ReLU 활성화
[은닉층2] → ReLU 활성화
[출력층] → Sigmoid 활성화 → (클릭 확률 예측)
본 모델에서 주로 사용하는 활성화 함수 요약
| 함수 | 수식 | 적용 위치 | 특징 |
| ReLU | f(x)=max(0,x) | 은닉층 | 학습 빠름, 비선형 패턴 반영 |
| Leaky ReLU | f(x)=x (x>0), 0.01x (x<0) | 은닉층 | 음수 구간에서도 미세한 변화 반영 |
| Sigmoid | f(x)=1/(1+e^-x) | 출력층 | 클릭확률(0~1) 예측에 적합 |
| Softmax | e^xi / Σe^xj | 다중 클래스 출력층 | 여러 광고소재 간 클릭 확률 비교용 |
2. 코드 예제
# -----------------------------
# 2. 전처리
# -----------------------------
df['ad_type'] = df['ad_type'].astype('category').cat.codes
df['color'] = df['color'].astype('category').cat.codes
df['cta'] = df['cta'].astype('category').cat.codes
X = df[['ad_type', 'color', 'cta', 'open_time', 'impressions', 'clicks']].values
y = df['ctr'].values
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)
# -----------------------------
# 3. 모델 정의 (활성화 함수 적용)
# -----------------------------
class EmailCTRModel(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(6, 16)
self.fc2 = nn.Linear(16, 8)
self.fc3 = nn.Linear(8, 1)
def forward(self, x):
x = F.relu(self.fc1(x)) # 은닉층1 - ReLU
x = F.leaky_relu(self.fc2(x)) # 은닉층2 - Leaky ReLU
x = torch.sigmoid(self.fc3(x)) # 출력층 - Sigmoid
return x
model = EmailCTRModel()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
# -----------------------------
# 4. 학습
# -----------------------------
print("\n[학습 시작]")
for epoch in range(300):
pred = model(X_tensor)
loss = criterion(pred, y_tensor)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 50 == 0:
print(f"Epoch {epoch+1:3d} | Loss: {loss.item():.6f}")
# -----------------------------
# 5. 예측
# -----------------------------
model.eval()
with torch.no_grad():
sample = torch.tensor([[1, 0, 2, 3.5, 3000, 150]], dtype=torch.float32)
pred_ctr = model(sample).item()
print(f"\n예측 클릭률(CTR): {pred_ctr:.4f}")
3. 결과

4. 마케팅 인사이트
| 항목 | 설명 |
| ReLU의 역할 | 이메일 열람시간, 클릭수 등 비선형 관계를 효과적으로 학습 |
| Leaky ReLU의 장점 | 클릭이 거의 없는 경우(음수 입력)에도 미세한 변화 반영 |
| Sigmoid의 의미 | 출력값을 0~1 사이 확률로 변환 → CTR 예측에 적합 |
| 전환 가능성 해석 | 예측된 CTR이 높을수록 캠페인 소재의 효과가 높음을 의미 |
| 광고소재 테스트 활용 | 각 배너 유형별 CTR 예측값 비교로 A/B 테스트 자동화 가능 |
연습문제 풀이
Q1. F.relu()와 F.leaky_relu()의 차이를 설명하시오.
(힌트: ReLU의 단점인 ‘죽은 뉴런(Dead Neuron)’ 문제를 보완하기 위해 Leaky ReLU는 어떤 방식을 사용하는가?)
A1. relu는 음수 구간의 기울기를 0으로 출력하므로 음수 입력을 받는 뉴런은 죽은 뉴런이 되기 쉽다. 반면, Leaky relu의 경우 음수 구간에서도 작은 기울기를 나타낼 수 있으므로 함수의 기울기가 0이 되는 것을 막아 학습을 지속시킬 수 있다.
Q2. 출력층에서 torch.sigmoid()를 사용하는 이유를 설명하시오.
(힌트: 이메일 광고의 클릭률(CTR) 예측 문제에서 예측값의 범위는 어떻게 제한되어야 하는가?)
A2. CTR은 확률값이므로 0부터 1까지의 범위 내에서 표현되어야 한다. sigmoid 함수는 0과 1 사이의 반환값을 나타내어 이진 분류 및 확률 회귀식에 적합하게 사용할 수 있다.
Q3. 다음 코드에서 활성화 함수를 모두 ReLU로 변경하면 어떤 문제가 발생할 수 있는가?
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = F.relu(self.fc3(x))
(힌트: 출력값이 0~1 범위를 벗어나면 어떤 해석상의 문제가 생기는가?)
A3. 예측값이 0 이상으로만 나오기 때문에 확률로 해석할 수가 없다. 확률을 예측해야 하는 문제에서는 sigmoid 함수 사용으로 0부터 1까지의 범위를 보장할 수 있어야 한다.
Q4. Sigmoid 함수의 출력값이 0 또는 1에 가까워질수록 학습이 느려지는 이유를 설명하시오.
(힌트: 기울기 소실(Vanishing Gradient) 현상과 관련이 있다.)
A4. Sigmoid의 출력이 0 또는 1 근처면 미분값에 가까워지고, 그 결과 역전파 시 기울기가 사라져 학습 속도가 느려진다.
Sigmoid 함수의 출력값이 0 또는 1에 가까워질수록 함수의 기울기(미분 값)가 매우 작아지기 때문이다.
역전파 과정에서 가중치 업데이트는 기울기(gradient)를 통해 이루어지는데, 기울기가 매우 작으면 이전 층으로 전달될수록 점점 더 작아져 결국 기울기 소실(Vanishing Gradient) 현상이 발생한다.
즉, 출력이 0 또는 1에 가까울수록 오차가 뒤로 전달되지 않아 학습이 느려지거나 멈추게 된다.
Q5. 이메일 배너 광고의 클릭률(CTR) 예측 문제에서 활성화 함수를 선택할 때 고려해야 할 기준 2가지를 설명하시오.
(힌트: 데이터의 비선형성 표현과 출력값의 의미를 동시에 고려해야 한다.)
A5.
1️⃣ 은닉층 : relu 혹은 leack relu 와 같은 비선형 함수를 사용하여 기울기 소실을 줄이고 표현력을 확보한다.
2️⃣ 출력층 : CTR은 확률이므로 예측값 범위를 0~1로 반환하는 sigmoid 함수를 사용하여 확률 해석이 가능하도록 한다.
이미지 광고 분석을 위한 CNN 기초
그로스 마케팅의 핵심은 "데이터 기반 실험을 통해 사용자 행동을 증대시키는 것"이다. 전통적인 마케팅은 감각적인 디자인 판단이나 경험적 직관에 의존했지만, 오늘날 광고의 클릭률(CTR)과 전환율(CVR)은 수백, 수천 장의 이미지가 동시에 실험되는 크리에이티브 퍼포먼스 경쟁 환경 속에서 결정된다. 광고 효율의 70% 이상이 "이미지와 시각 요소의 품질"에 의해 좌우된다는 연구 결과도 있다.
이에 따라 마케터들은 다음과 같은 질문에 직면하게 된다.
- 어떤 이미지가 사용자의 클릭을 더 유도하는가?
- 시각적 구성이 클릭률에 어떤 영향을 주는가?
- AI가 인간보다 더 정확히 ‘성과가 좋은 이미지’를 판단할 수 있을까?
이 질문에 대한 핵심 기술이 바로 CNN(합성곱 신경망)이다. CNN은 이미지 데이터를 입력받아, 픽셀 수준의 정보를 학습하고 광고 성과와 직접적으로 연관된 시각적 패턴을 자동으로 추출한다.
CNN (Convolutional Neural Network)
- 딥러닝의 한 종류로 이미지, 영상, 시각적 패턴을 분석하는 데 특화된 (분류에 특화된) 신경망 구조
- MLP는 모든 픽셀을 하나의 벡터로 처리하지만, CNN은 공간적 구조(Spatial Structure)를 유지한 채 학습
- 이미지의 국소적 특징을 필터로 탐색하면서 “이 이미지 안에 어떤 모양, 패턴, 질감, 색상 대비가 존재하는가”를 자동으로 학습
1. 주요 구성 요소
| 구성 요소 | 역할 | 마케팅적 해석 |
| 합성곱 층 (Convolution Layer) | 이미지의 작은 영역을 스캔하며 특징 추출 | 광고 이미지의 구도, 로고 위치, 색상 대비, 텍스트 구성 등을 인식 |
| 활성화 함수 (ReLU) | 비선형성을 부여하여 복잡한 패턴 학습 가능 | 클릭을 유도하는 비선형 시각 요소 표현 |
| 풀링 층 (Pooling Layer) | 이미지 크기를 줄이면서 주요 특징 유지 | 다양한 크기·비율의 광고 이미지에서도 일관된 성과 분석 가능 |
| 완전연결층 (Fully Connected Layer) | 추출된 특징을 바탕으로 최종 분류 수행 | “이 광고는 클릭될 확률이 높은가?” 예측 수행 |
| Softmax / Sigmoid 출력층 | 확률 기반으로 분류 결과 출력 | 클릭/비클릭, 긍정/부정 이미지 등 확률 예측 가능 |
(예) CNN이 여러 광고 이미지를 학습하면 ‘따뜻한 색감 + 인물 중심 + 시선이 정면인 광고’가 클릭률이 높음을 스스로 학습하게 된다
2. 그로스 마케팅에서의 CNN 응용
그로스 마케팅의 실험(Experiment) – 분석(Analysis) – 최적화(Optimization) 과정에서 '이미지 데이터'라는 비정형 데이터를 구조화하고 해석하는 도구로 활용된다.
(1) 광고 클릭 예측 모델링
- 학습 데이터 : 클릭된 광고 (Exitosos), 클릭되지 않은 광고 (NoExitosos)
- CNN은 각 광고 이미지를 입력받아 두 클래스 중 하나로 분류 → 클릭 성과가 좋은 이미지의 시각적 패턴 파악 가능
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 32 * 16 * 16)
x = F.relu(self.fc1(x))
x = self.fc2(x)
(2) 광고 크리에이티브 자동 분류
- 신규 광고 이미지를 넣었을 때 “이 이미지가 클릭형 광고인지, 비클릭형 광고인지”를 자동 분류 가능
- 나아가 이미지 내부의 특정 패턴을 시각화하여 디자인 방향성을 피드백하는 ‘AI 크리에이티브 코치’ 로 활용 가능
(3) 썸네일 자동 추천
- CNN이 학습한 시각적 피처를 기반으로 유튜브, 쇼핑몰, SNS 썸네일 중 CTR이 높을 확률이 높은 이미지를 자동 추천
- A/B 테스트 이전 단계에서 효율이 낮을 것으로 예상되는 크리에이티브를 필터링함으로써 광고 테스트 비용 절감 가능
(4) 브랜드 톤앤매너 유지 분석
- CNN이 추출한 이미지 임베딩을 기반으로 브랜드 캠페인의 시각적 일관성 분석 가능
- “최근 광고 이미지가 브랜드 톤과 일치하는가?”를 AI가 자동 진단
(5) 고객 반응 기반 이미지 생성
- CNN을 생성 모델(GAN, Stable Diffusion)과 결합하여 과거 클릭된 광고의 시각 패턴을 모방한 새로운 이미지 생성 가능
- "클릭률이 높은 이미지 스타일"을 생성 AI에 직접 학습시키는 단계로 발전 중
3. 실제 응용 사례
| 기업/도구 | 활용 방식 | 효과 |
| Meta Ads (페이스북 광고) | 광고 이미지 자동 품질 분석 시스템에 CNN 내장 | 낮은 품질 이미지는 자동 제한 |
| Google Ads Creative Studio | CNN 기반 시각 피드백 제공 | 이미지 노출 최적화, CTR 향상 |
| 스타트업 (예) 크리에이티브 최적화 솔루션 | 클릭·비클릭 데이터를 학습한 CNN 모델로 이미지 자동 평가 | 광고 효율 +25% 향상 |
4. 전략적 가치와 인사이트
| 구분 | 설명 |
| 1. 데이터 기반 의사결정 | 감에 의존하던 디자인 평가를 수치화 가능 |
| 2. 실험 효율 향상 | CNN 모델이 고효율 크리에이티브를 선별하여 테스트 자원 절약 |
| 3. 브랜드 일관성 확보 | 시각적 특징 분석을 통해 캠페인 톤 유지 가능 |
| 4. 소비자 반응 예측 | 광고 이미지와 클릭 행동의 상관성을 자동 학습 |
| 5. 자동화 기반 확장성 | 인공지능 모델이 반복 실험을 대체하여 대규모 광고 세트 관리 가능 |
5. 코드 예제
# ============================================
# AdModel.zip 압축 해제 (루트에 그대로)
# ============================================
import zipfile
from google.colab import files
import os, shutil
# -----------------------------
# (1) 파일 업로드
# -----------------------------
print("AdModel.zip 파일을 업로드하세요...")
uploaded = files.upload()
zip_path = list(uploaded.keys())[0]
# -----------------------------
# (2) 기존 AdModel 폴더 삭제 (선택 사항)
# -----------------------------
target_dir = "/content/AdModel"
if os.path.exists(target_dir):
shutil.rmtree(target_dir)
# -----------------------------
# (3) 루트에 압축 해제
# -----------------------------
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall("/content")
print("\n압축 해제 완료!")
print("압축 해제 위치:", "/content")

# ============================================
# 2. CNN 이미지 광고 분석 (AdModel 데이터 기반)
# ============================================
!pip install koreanize-matplotlib -q
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import koreanize_matplotlib
import os
# -----------------------------
# 1. 데이터 경로 지정
# -----------------------------
# Exitosos → 클릭된 광고 (clicked)
# NoExitosos → 클릭되지 않은 광고 (not_clicked)
data_dir = "/content/AdModel"
# -----------------------------
# 2. 데이터 전처리 정의
# -----------------------------
transform = transforms.Compose([
transforms.Resize((64, 64)), # 이미지 크기 통일
transforms.ToTensor(), # Tensor 변환
transforms.Normalize((0.5, 0.5, 0.5), # RGB 채널 정규화
(0.5, 0.5, 0.5))
])
# -----------------------------
# 3. ImageFolder로 데이터 로드
# -----------------------------
dataset = datasets.ImageFolder(root=data_dir, transform=transform)
train_loader = DataLoader(dataset, batch_size=8, shuffle=True)
classes = dataset.classes
print(f"클래스 목록: {classes}")
print(f"총 이미지 수: {len(dataset)}")
# -----------------------------
# 4. CNN 모델 정의
# -----------------------------
class AdCNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(16, 32, 3, padding=1)
self.fc1 = nn.Linear(32 * 16 * 16, 64)
self.fc2 = nn.Linear(64, 2) # Exitosos / NoExitosos
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 32 * 16 * 16)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
# -----------------------------
# 5. 학습 준비
# -----------------------------
model = AdCNN()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# -----------------------------
# 6. 학습 루프
# -----------------------------
print("\n[학습 시작]")
for epoch in range(10):
running_loss = 0.0
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1:2d} | Loss: {running_loss/len(train_loader):.4f}")
print("\n[학습 완료]")
# -----------------------------
# 7. 학습 결과 확인 (예시 이미지 예측)
# -----------------------------
data_iter = iter(train_loader)
images, labels = next(data_iter)
# 모델 예측
outputs = model(images)
_, preds = torch.max(outputs, 1)
# 시각화
fig, axes = plt.subplots(1, 4, figsize=(10, 4))
for i in range(4):
img = images[i] / 2 + 0.5 # 정규화 복원
npimg = img.permute(1, 2, 0).numpy()
axes[i].imshow(npimg)
axes[i].set_title(f"예측: {classes[preds[i]]}")
axes[i].axis('off')
plt.show()

# ============================================
# 3. 단일 이미지 예측 (AdModel CNN용)
# ============================================
from google.colab import files
from PIL import Image
import torch
import matplotlib.pyplot as plt
# -----------------------------
# (1) 테스트 이미지 업로드
# -----------------------------
print("테스트할 광고 이미지를 업로드하세요...")
uploaded = files.upload()
test_image_path = list(uploaded.keys())[0]
print(f"\n업로드된 테스트 이미지: {test_image_path}")
# -----------------------------
# (2) 이미지 표시
# -----------------------------
img = Image.open(test_image_path).convert("RGB")
plt.imshow(img)
plt.title("테스트 이미지")
plt.axis('off')
plt.show()
# -----------------------------
# (3) 이미지 전처리 및 예측
# -----------------------------
model.eval() # 평가 모드
with torch.no_grad():
# 학습 시 사용한 transform 그대로 적용
img_tensor = transform(img).unsqueeze(0) # (1, 3, 64, 64)
outputs = model(img_tensor)
_, predicted = torch.max(outputs, 1)
label = classes[predicted.item()]
print(f"\n예측 결과: {label}")
# -----------------------------
# (4) 결과 해석 출력
# -----------------------------
if label.lower().startswith("exito"):
print("→ 이 이미지는 클릭된(성공적인) 광고로 예측되었습니다")
else:
print("→ 이 이미지는 클릭되지 않은(비성공적인) 광고로 예측되었습니다")

(응용) 에폭 횟수 조정 후 재시도
# -----------------------------
# 5. 학습 준비
# -----------------------------
model = AdCNN()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# -----------------------------
# 6. 학습 루프
# -----------------------------
print("\n[학습 시작]")
for epoch in range(50):
running_loss = 0.0
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1:2d} | Loss: {running_loss/len(train_loader):.4f}")


6. 마케팅 인사이트
| 항목 | 설명 |
| 자동 시각 분석 | CNN이 광고 이미지의 색상, 텍스트 배치, 인물 존재 여부 등을 학습 |
| 효과적 광고 식별 | 클릭된 광고의 시각적 패턴(밝기, 대비, 감정 톤)을 정량적으로 비교 가능 |
| 디자인 가이드라인 도출 | 고성과 이미지의 공통된 시각 요소를 분석하여 새로운 디자인 방향 제시 |
| 성과 예측 자동화 | 신규 광고 이미지의 성과 가능성을 사전에 예측 가능 |
연습문제 풀이
Q1. Conv2d 계층은 이미지 데이터에서 어떤 역할을 하나요?
A1. 이미지의 공간적 특징을 자동으로 추출하는 역할을 한다.
Q2. MaxPool2d 계층을 사용하는 이유를 간단히 설명하세요.
A2. 다운 샘플링으로 주요 특징만 남겨 과적합을 줄이는 역할을 한다. 또한, 가장 중요한 값은 보존해 모델의 일반화 성능을 높인다.
Q3. 다음 코드에서 predicted == labels의 의미를 설명하세요.
(predicted == labels)
A3. 예측 결과와 실제 정답이 일치하는지를 비교하는 연산으로 정확도를 계산하는 바탕이 된다.
Q4. 학습률(lr)이 너무 클 때 학습이 제대로 되지 않는 이유를 쓰세요.
A4. 학습률이 너무 크면 가중치가 최적점을 지나치며 손실이 오히려 커지고 모델이 불안정해질 수 있다.
Q5. 이 CNN 모델이 그로스 마케팅에서 어떻게 활용될 수 있는지 간단히 설명하세요.
A5. 광고나 캠페인 이미지 데이터를 분석해 클릭률이 높은 디자인 패턴이나 구성 요소를 자동으로 분류할 수 있다. 이를 통해 광고 소재의 성패 요인을 파악하고 이후 효율적인 크리에이티브 전략 수립에 활용할 수 있다.
실습. 나이키 운동화 분류



✏️ 개인 회고
따로 공부 중인 내용에서도 계-속 나왔던 활성화 함수 🥺
코드와 실행 결과로 보니까 확실히 와닿는다 Sigmoid, ReLU, Softmax는 절대 헷갈리지 않겠고만
이번 머신러닝 기초 챕터에서 연습문제를 따로 제시해 주시는 부분이 정말 좋다
어려운 내용 투성이인 와중에 한번씩 다시 되짚고 정리할 수 있어서 (아주 조금은) 이해가 수월하다
그래도 여전히 코드 보는 건 어려워 ... 주석 보면서 한 줄 한 줄 잘 뜯어보고 복습하장 @.@
'🦁 GM3 > 블로그 챌린지' 카테고리의 다른 글
| [멋쟁이사자처럼 그로스마케팅 3기] 부트캠프를 마치며, (0) | 2025.12.03 |
|---|---|
| [멋쟁이사자처럼 그로스마케팅 3기] 학습 기록 44일차 : 크리에이티브 성과 개선을 위한 풀링과 CNN 설계 및 RNN 기초 (0) | 2025.10.29 |
| [멋쟁이사자처럼 그로스마케팅 3기] 학습 기록 42일차 : 머신러닝 적용 마케팅 평가 지표 이해 및 딥러닝 예측 모델 (1) | 2025.10.27 |
| [멋쟁이사자처럼 그로스마케팅 3기] 학습 기록 41일차 : 앙상블 기법과 랜덤 포레스트, 광고 성과 최적화를 위한 그라디언트 부스팅 (0) | 2025.10.24 |
| [멋쟁이사자처럼 그로스마케팅 3기] 학습 기록 40일차 : 의사결정 나무를 활용한 캠페인 분산 분석 및 모델 생성 연습 (0) | 2025.10.23 |