티스토리 뷰
Tabulear Data
1. 전처리 (Preprocessing)
1.1 결측치 처리 (Handling Missing Values)
- 삭제 (Deletion): 결측치가 적을 때 사용하는 방법입니다.
# 행 삭제 df.dropna(axis=0, inplace=True) # 열 삭제 df.dropna(axis=1, inplace=True)
- 대체 (Imputation): 결측치를 평균, 중앙값, 최빈값 등으로 대체합니다.
# 평균으로 대체 df.fillna(df.mean(), inplace=True) # 중앙값으로 대체 df.fillna(df.median(), inplace=True) # 최빈값으로 대체 df.fillna(df.mode().iloc[0], inplace=True)
- 예측 모델을 사용한 대체 (Model-Based Imputation): 예측 모델을 사용하여 결측치를 대체합니다
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='mean')
df_imputed = imputer.fit_transform(df)
- 중복치 확인 및 제거
# 중복치 확인 및 제거
print("중복된 행의 수:", df.duplicated().sum())
df.drop_duplicates(inplace=True)
1.2 이상치 처리 (Handling Outliers)
- IQR 방법: 1사분위수(Q1)와 3사분위수(Q3) 사이의 범위를 사용하여 이상치를 탐지합니다.
Q1 = df.quantile(0.25) Q3 = df.quantile(0.75) IQR = Q3 - Q1 df = df[~((df < (Q1 - 1.5 * IQR)) | (df > (Q3 + 1.5 * IQR))).any(axis=1)]
- Z-Score 방법: Z-Score를 사용하여 이상치를 탐지합니다.
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='mean')
df_imputed = imputer.fit_transform(df)
2. 인코딩 및 라벨링 (Encoding and Labeling)
2.1 레이블 인코딩 (Label Encoding)
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['category'] = le.fit_transform(df['category'])
2.2 원-핫 인코딩 (One-Hot Encoding)
df = pd.get_dummies(df, columns=['category'])
3. 데이터 분할 (Data Splitting)
학습 데이터와 테스트 데이터를 분할합니다. 또한 교차 검증을 위해 학습 데이터를 훈련 데이터와 검증 데이터로 나눌 수 있습니다.
from sklearn.model_selection import train_test_split
X = df.drop('target', axis=1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
4. 정규화 (Normalization)
데이터의 범위를 일정하게 맞춰주는 과정입니다. 주로 StandardScaler와 MinMaxScaler를 사용합니다.
4.1 표준화 (Standardization)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
4.2 Min-Max 스케일링
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
5. 모델 학습 (Model Training)
모델을 선택하고 학습시킵니다. 회귀와 분류에 따라 모델을 선택합니다.
5.1 회귀 모델 (Regression Model)
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
5.2 분류 모델 (Classification Model)
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_train, y_train)
6. 최적화 (Optimization)
하이퍼파라미터 튜닝을 통해 모델의 성능을 최적화합니다.
7. GridSearchCV
하이퍼파라미터 튜닝을 위해 GridSearchCV를 사용합니다.
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [100, 200],
'max_depth': [None, 10, 20],
}
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
print("Best parameters found: ", grid_search.best_params_)
print("Best accuracy: ", grid_search.best_score_)
8. 성능 평가 (Performance Evaluation)
회귀 모델과 분류 모델의 평가지표를 사용하여 모델의 성능을 평가합니다.
8.1 회귀 모델 평가지표 (Regression Metrics)
from sklearn.metrics import mean_squared_error, mean_absolute_error
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
print(f'MSE: {mse}, RMSE: {rmse}, MAE: {mae}')
8.2 분류 모델 평가지표 (Classification Metrics)
from sklearn.metrics import accuracy_score, f1_score, classification_report
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred, average='weighted')
print(f'Accuracy: {accuracy}, F1-Score: {f1}')
print(classification_report(y_test, y_pred))
전체 파이프라인 요약
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder, OneHotEncoder
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import mean_squared_error, mean_absolute_error, accuracy_score, f1_score, classification_report
from sklearn.model_selection import GridSearchCV
# 데이터 로드 및 전처리
df = pd.read_csv('data.csv')
df.dropna(axis=0, inplace=True)
# 중복치 제거
df.drop_duplicates(inplace=True)
Q1 = df.quantile(0.25)
Q3 = df.quantile(0.75)
IQR = Q3 - Q1
df = df[~((df < (Q1 - 1.5 * IQR)) | (df > (Q3 + 1.5 * IQR))).any(axis=1)]
# 인코딩 및 라벨링
le = LabelEncoder()
df['category'] = le.fit_transform(df['category'])
df = pd.get_dummies(df, columns=['category'])
# 데이터 분할
X = df.drop('target', axis=1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 정규화
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# 모델 학습
model = RandomForestClassifier()
model.fit(X_train, y_train)
# 최적화 및 GridSearchCV
param_grid = {
'n_estimators': [100, 200],
'max_depth': [None, 10, 20],
}
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
print("Best parameters found: ", grid_search.best_params_)
print("Best accuracy: ", grid_search.best_score_)
# 성능 평가
y_pred = grid_search.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred, average='weighted')
print(f'Accuracy: {accuracy}, F1-Score: {f1}')
print(classification_report(y_test, y_pred))
Text Data
텍스트 데이터를 전처리하고 모델링하는 과정은 여러 단계로 나눌 수 있습니다. 여기서는 전처리, 토큰화, 정제, 정규화, 데이터 분할, 문서 단어 행렬 변환, 모델 학습, 최적화, 성능 평가를 포함한 전체 프로세스를 설명하겠습니다.
1. 전처리 (Preprocessing)
1.1 텍스트 정제 (Text Cleaning)
import re
def clean_text(text):
text = re.sub(r'\d+', '', text) # 숫자 제거
text = re.sub(r'<.*?>', '', text) # HTML 태그 제거
text = re.sub(r'[^\w\s]', '', text) # 특수 문자 제거
text = text.lower() # 소문자 변환
return text
df['text'] = df['text'].apply(clean_text)
2. 토큰화 (Tokenization)
- 단어 단위 토큰화: 텍스트를 단어 단위로 분할합니다.
from nltk.tokenize import word_tokenize
df['tokens'] = df['text'].apply(word_tokenize)
3. 정제 (Cleaning)
- 불용어 제거: 의미 없는 단어(불용어)를 제거합니다.
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
df['tokens'] = df['tokens'].apply(lambda x: [word for word in x if word not in stop_words])
4. 정규화 (Normalization)
- 어간 추출 및 표제어 추출: 단어의 형태를 표준화합니다.
from nltk.stem import PorterStemmer, WordNetLemmatizer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
df['tokens'] = df['tokens'].apply(lambda x: [stemmer.stem(word) for word in x])
# 또는
df['tokens'] = df['tokens'].apply(lambda x: [lemmatizer.lemmatize(word) for word in x])
5. 데이터 분할 (Data Splitting)
- 훈련 데이터와 테스트 데이터로 분할:
from sklearn.model_selection import train_test_split
X = df['tokens'].apply(lambda x: ' '.join(x))
y = df['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
6. 문서-단어 행렬 변환 (CountVectorizer)
- 텍스트 데이터를 수치 데이터로 변환:
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
X_train_vect = vectorizer.fit_transform(X_train)
X_test_vect = vectorizer.transform(X_test)
7. 모델 학습 (Model Training)
7.1 로지스틱 회귀 (Logistic Regression)
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train_vect, y_train)
7.2 나이브 베이즈 (Naive Bayes)
from sklearn.naive_bayes import MultinomialNB
model = MultinomialNB()
model.fit(X_train_vect, y_train)
7.3 서포트 벡터 머신 (Support Vector Machine)
from sklearn.svm import SVC
model = SVC()
model.fit(X_train_vect, y_train)
8. 최적화 (Optimization)
8.1 GridSearchCV
- 하이퍼파라미터 튜닝:
from sklearn.model_selection import GridSearchCV
param_grid = {
'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf']
}
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train_vect, y_train)
print("Best parameters found: ", grid_search.best_params_)
print("Best accuracy: ", grid_search.best_score_)
9. 성능 평가 (Performance Evaluation)
9.1 성능 평가 지표
- 분류 모델 평가 지표:
from sklearn.metrics import accuracy_score, f1_score, classification_report
y_pred = grid_search.predict(X_test_vect)
accuracy = accuracy_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred, average='weighted')
print(f'Accuracy: {accuracy}, F1-Score: {f1}')
print(classification_report(y_test, y_pred))
전체 파이프라인 요약
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder, OneHotEncoder
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, f1_score, classification_report
from sklearn.model_selection import GridSearchCV
import re
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer, WordNetLemmatizer
# 데이터 로드
df = pd.read_csv('data.csv')
# 텍스트 정제
def clean_text(text):
text = re.sub(r'\d+', '', text) # 숫자 제거
text = re.sub(r'<.*?>', '', text) # HTML 태그 제거
text = re.sub(r'[^\w\s]', '', text) # 특수 문자 제거
text = text.lower() # 소문자 변환
return text
df['text'] = df['text'].apply(clean_text)
# 토큰화
df['tokens'] = df['text'].apply(word_tokenize)
# 불용어 제거
stop_words = set(stopwords.words('english'))
df['tokens'] = df['tokens'].apply(lambda x: [word for word in x if word not in stop_words])
# 정규화 (어간 추출 또는 표제어 추출)
stemmer = PorterStemmer()
df['tokens'] = df['tokens'].apply(lambda x: [stemmer.stem(word) for word in x])
# 또는
lemmatizer = WordNetLemmatizer()
df['tokens'] = df['tokens'].apply(lambda x: [lemmatizer.lemmatize(word) for word in x])
# 데이터 분할
X = df['tokens'].apply(lambda x: ' '.join(x))
y = df['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 문서-단어 행렬 변환
vectorizer = CountVectorizer()
X_train_vect = vectorizer.fit_transform(X_train)
X_test_vect = vectorizer.transform(X_test)
# 모델 학습 (여기서는 로지스틱 회귀를 예시로 사용)
model = LogisticRegression()
model.fit(X_train_vect, y_train)
# 최적화 및 GridSearchCV (서포트 벡터 머신을 예시로 사용)
param_grid = {
'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf']
}
grid_search = GridSearchCV(estimator=SVC(), param_grid=param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train_vect, y_train)
print("Best parameters found: ", grid_search.best_params_)
print("Best accuracy: ", grid_search.best_score_)
# 모델 저장하고 로드하는 법
# 모델 저장
# joblib.dump(grid_search, 'text_classification_model.pkl')
# joblib.dump(vectorizer, 'count_vectorizer.pkl')
# 모델 로드
# loaded_model = joblib.load('text_classification_model.pkl')
# loaded_vectorizer = joblib.load('count_vectorizer.pkl')
# 성능 평가
y_pred = grid_search.predict(X_test_vect)
accuracy = accuracy_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred, average='weighted')
print(f'Accuracy: {accuracy}, F1-Score: {f1}')
print(classification_report(y_test, y_pred))
Image Data
이미지 데이터 전처리 및 모델링
이미지 데이터를 전처리하고 모델링하는 과정은 여러 단계로 나눌 수 있습니다. 여기서는 전처리, 데이터 분할, 모델 생성, 모델 학습, 최적화, 성능 평가를 포함한 전체 프로세스를 설명하겠습니다.
1. 전처리 (Preprocessing)
이미지 데이터 전처리는 크기 조정, 자르기, 패딩 등을 포함합니다.
1.1 크기 조정 (Resize)
- 이미지를 동일한 크기로 조정:
import tensorflow as tf
def resize_image(image, size=(224, 224)):
return tf.image.resize(image, size)
1.2 자르기 (Cropping)
- 중앙 부분을 자르기:
def crop_image(image, size=(200, 200)):
return tf.image.central_crop(image, central_fraction=0.8)
1.3 패딩 (Padding)
- 이미지에 패딩 추가:
def pad_image(image, size=(224, 224)):
return tf.image.resize_with_pad(image, target_height=size[0], target_width=size[1])
1.4 이미지 전처리 파이프라인
- 전처리 파이프라인:
def preprocess_image(image, label, size=(224, 224)):
image = resize_image(image, size)
image = pad_image(image, size)
return image, label
2. 데이터 분할 (Data Splitting)
데이터를 훈련 데이터와 테스트 데이터로 분할합니다.
from sklearn.model_selection import train_test_split
def load_and_split_data(data_path):
dataset = tf.keras.preprocessing.image_dataset_from_directory(
data_path,
image_size=(224, 224),
batch_size=32,
validation_split=0.2,
subset="both",
seed=42
)
train_ds, val_ds = dataset.take(0.8), dataset.skip(0.8)
return train_ds, val_ds
data_path = "path/to/dataset"
train_ds, val_ds = load_and_split_data(data_path)
3. 모델 생성 (Model Creation)
3.1 CNN 모델
- 간단한 CNN 모델:
from tensorflow.keras import layers, models
def create_cnn_model(input_shape=(224, 224, 3), num_classes=10):
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(num_classes, activation='softmax'))
return model
3.2 YOLO 모델
YOLO 모델은 일반적인 라이브러리를 사용하여 구성할 수 있습니다. 다만, YOLO 모델을 직접 구현하는 것보다는 사전 훈련된 모델을 사용하는 것이 더 효율적입니다.
# YOLO 모델을 불러오기 위한 예제 코드 (간단한 구현)
from yolov3_tf2.models import (
YoloV3, YoloV3Tiny
)
from yolov3_tf2.dataset import transform_images, load_tfrecord_dataset
def create_yolo_model(size=416, channels=3, classes=80, tiny=False):
if tiny:
yolo = YoloV3Tiny(classes=classes)
else:
yolo = YoloV3(classes=classes)
return yolo
4. 모델 학습 (Model Training)
모델을 컴파일하고 학습시킵니다.
def compile_and_train_model(model, train_ds, val_ds, epochs=10, batch_size=32):
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs,
batch_size=batch_size
)
return history
# CNN 모델 학습 예제
cnn_model = create_cnn_model(input_shape=(224, 224, 3), num_classes=10)
history = compile_and_train_model(cnn_model, train_ds, val_ds)
5. 최적화 (Optimization)
모델을 최적화하기 위해 다양한 방법을 사용할 수 있습니다.
5.1 드롭아웃 (Dropout)
- 드롭아웃을 사용하여 과적합 방지:
def create_cnn_model_with_dropout(input_shape=(224, 224, 3), num_classes=10):
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(num_classes, activation='softmax'))
return model
5.2 배치 크기 조정 (Adjusting Batch Size)
- 배치 크기를 조정하여 성능 최적화:
def compile_and_train_model_with_batch_size(model, train_ds, val_ds, epochs=10, batch_size=64):
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs,
batch_size=batch_size
)
return history
- 배치 크기를 64로 설정하여 모델 학습
history = compile_and_train_model_with_batch_size(cnn_model, train_ds, val_ds, batch_size=64)
### 6. 성능 평가 (Performance Evaluation)
모델의 성능을 평가합니다.
```python
def evaluate_model(model, test_ds):
test_loss, test_accuracy = model.evaluate(test_ds)
print(f'Test Accuracy: {test_accuracy:.4f}')
return test_loss, test_accuracy
# 성능 평가 예제
test_loss, test_accuracy = evaluate_model(cnn_model, val_ds)
전체 파이프라인 요약
import tensorflow as tf
from tensorflow.keras import layers, models
from sklearn.model_selection import train_test_split
# 데이터 로드 및 전처리
data_path = "path/to/dataset"
def load_and_preprocess_data(data_path):
dataset = tf.keras.preprocessing.image_dataset_from_directory(
data_path,
image_size=(224, 224),
batch_size=32,
validation_split=0.2,
subset="both",
seed=42
)
train_ds, val_ds = dataset.take(0.8), dataset.skip(0.8)
return train_ds, val_ds
train_ds, val_ds = load_and_preprocess_data(data_path)
# 모델 생성
def create_cnn_model(input_shape=(224, 224, 3), num_classes=10):
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(num_classes, activation='softmax'))
return model
cnn_model = create_cnn_model(input_shape=(224, 224, 3), num_classes=10)
# 모델 학습
def compile_and_train_model(model, train_ds, val_ds, epochs=10, batch_size=32):
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs,
batch_size=batch_size
)
return history
history = compile_and_train_model(cnn_model, train_ds, val_ds)
# 모델 저장하고 로드하는 법
# 모델 저장
# cnn_model.save('cnn_model.h5')
# 모델 로드
# loaded_model = tf.keras.models.load_model('cnn_model.h5')
# 성능 평가
def evaluate_model(model, test_ds):
test_loss, test_accuracy = model.evaluate(test_ds)
print(f'Test Accuracy: {test_accuracy:.4f}')
return test_loss, test_accuracy
test_loss
전체 파이프라인 요약: YOLO로 객체 탐지 후 CNN으로 객체 분류
1. YOLO 모델로 객체 탐지
먼저, YOLO 모델을 사용하여 이미지에서 객체를 탐지합니다. 여기서는 YOLOv3 모델을 사용합니다.
1.1 YOLO 모델 설치 및 로드
!pip install tensorflow
!pip install yolov3-tf2
import tensorflow as tf
from yolov3_tf2.models import YoloV3
from yolov3_tf2.dataset import transform_images
from yolov3_tf2.utils import draw_outputs
# YOLO 모델 로드
yolo = YoloV3(classes=80) # COCO 데이터셋을 사용한 모델
yolo.load_weights('./checkpoints/yolov3.tf') # 사전 학습된 가중치 로드
1.2 객체 탐지
import cv2
import numpy as np
import matplotlib.pyplot as plt
def load_image(img_path):
img_raw = tf.image.decode_image(open(img_path, 'rb').read(), channels=3)
img = tf.expand_dims(img_raw, 0)
img = transform_images(img, 416)
return img, img_raw
def detect_objects(yolo, img_path):
img, img_raw = load_image(img_path)
boxes, scores, classes, nums = yolo.predict(img)
img_with_boxes = draw_outputs(img_raw.numpy(), (boxes, scores, classes, nums), class_names)
return img_with_boxes, boxes, classes
# COCO 클래스 이름 로드
class_names = [c.strip() for c in open('./data/coco.names').readlines()]
img_path = 'path/to/your/image.jpg'
img_with_boxes, boxes, classes = detect_objects(yolo, img_path)
plt.imshow(img_with_boxes)
plt.show()
2. 탐지된 객체를 CNN으로 분류
탐지된 객체 영역을 잘라서 CNN 모델로 분류합니다.
2.1 CNN 모델 정의 및 학습
from tensorflow.keras import layers, models
def create_cnn_model(input_shape=(224, 224, 3), num_classes=10):
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(num_classes, activation='softmax'))
return model
cnn_model = create_cnn_model(input_shape=(224, 224, 3), num_classes=10)
# CNN 모델 컴파일
cnn_model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 예제 데이터를 사용하여 모델 학습 (실제 데이터로 대체 필요)
# train_images, train_labels = ...
# cnn_model.fit(train_images, train_labels, epochs=10, validation_split=0.2)
2.2 탐지된 객체 영역 자르기 및 분류
def crop_and_classify_objects(img_path, boxes, cnn_model, class_labels):
img_raw = cv2.imread(img_path)
cropped_objects = []
for box in boxes[0]:
ymin, xmin, ymax, xmax = box
cropped_img = img_raw[int(ymin):int(ymax), int(xmin):int(xmax)]
cropped_img = cv2.resize(cropped_img, (224, 224))
cropped_img = np.expand_dims(cropped_img, axis=0) / 255.0
cropped_objects.append(cropped_img)
classifications = []
for obj in cropped_objects:
pred = cnn_model.predict(obj)
class_idx = np.argmax(pred, axis=1)
class_name = class_labels[class_idx[0]]
classifications.append(class_name)
return classifications
# 탐지된 객체를 분류
class_labels = ['class1', 'class2', 'class3', 'class4', 'class5',
'class6', 'class7', 'class8', 'class9', 'class10']
classifications = crop_and_classify_objects(img_path, boxes, cnn_model, class_labels)
print(classifications)
가장 신뢰도 높은 한 객체 선택
1. YOLO 모델로 객체 탐지
1.1 YOLO 모델 설치 및 로드
!pip install tensorflow
!pip install yolov3-tf2
import tensorflow as tf
from yolov3_tf2.models import YoloV3
from yolov3_tf2.dataset import transform_images
from yolov3_tf2.utils import draw_outputs
# YOLO 모델 로드
yolo = YoloV3(classes=80) # COCO 데이터셋을 사용한 모델
yolo.load_weights('./checkpoints/yolov3.tf') # 사전 학습된 가중치 로드
1.2 객체 탐지
import cv2
import numpy as np
import matplotlib.pyplot as plt
def load_image(img_path):
img_raw = tf.image.decode_image(open(img_path, 'rb').read(), channels=3)
img = tf.expand_dims(img_raw, 0)
img = transform_images(img, 416)
return img, img_raw
def detect_objects(yolo, img_path):
img, img_raw = load_image(img_path)
boxes, scores, classes, nums = yolo.predict(img)
# 가장 높은 신뢰도를 가진 객체 하나만 선택
best_idx = np.argmax(scores[0])
best_box = boxes[0][best_idx]
best_score = scores[0][best_idx]
best_class = classes[0][best_idx]
img_with_boxes = draw_outputs(img_raw.numpy(), ([best_box], [best_score], [best_class], [1]), class_names)
return img_with_boxes, best_box, best_class
# COCO 클래스 이름 로드
class_names = [c.strip() for c in open('./data/coco.names').readlines()]
img_path = 'path/to/your/image.jpg'
img_with_boxes, best_box, best_class = detect_objects(yolo, img_path)
plt.imshow(img_with_boxes)
plt.show()
2. 탐지된 객체를 CNN으로 분류
탐지된 객체 영역을 잘라서 CNN 모델로 분류합니다.
2.1 CNN 모델 정의 및 학습
from tensorflow.keras import layers, models
def create_cnn_model(input_shape=(224, 224, 3), num_classes=10):
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(num_classes, activation='softmax'))
return model
cnn_model = create_cnn_model(input_shape=(224, 224, 3), num_classes=10)
# CNN 모델 컴파일
cnn_model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 예제 데이터를 사용하여 모델 학습 (실제 데이터로 대체 필요)
# train_images, train_labels = ...
# cnn_model.fit(train_images, train_labels, epochs=10, validation_split=0.2)
2.2 탐지된 객체 영역 자르기 및 분류
def crop_and_classify_object(img_path, best_box, cnn_model, class_labels):
img_raw = cv2.imread(img_path)
ymin, xmin, ymax, xmax = best_box
ymin, xmin, ymax, xmax = int(ymin * img_raw.shape[0]), int(xmin * img_raw.shape[1]), int(ymax * img_raw.shape[0]), int(xmax * img_raw.shape[1])
cropped_img = img_raw[ymin:ymax, xmin:xmax]
cropped_img = cv2.resize(cropped_img, (224, 224))
cropped_img = np.expand_dims(cropped_img, axis=0) / 255.0
pred = cnn_model.predict(cropped_img)
class_idx = np.argmax(pred, axis=1)
class_name = class_labels[class_idx[0]]
return class_name
# 탐지된 객체를 분류
class_labels = ['class1', 'class2', 'class3', 'class4', 'class5',
'class6', 'class7', 'class8', 'class9', 'class10']
classification = crop_and_classify_object(img_path, best_box, cnn_model, class_labels)
print(classification)
3. 성능 평가
3.1 테스트 데이터셋의 정확도 계산
from sklearn.metrics import accuracy_score
def evaluate_on_test_set(test_images, test_labels, yolo, cnn_model, class_labels):
y_true = []
y_pred = []
for img_path, true_label in zip(test_images, test_labels):
_, best_box, _ = detect_objects(yolo, img_path)
predicted_class = crop_and_classify_object(img_path, best_box, cnn_model, class_labels)
y_true.append(true_label)
y_pred.append(predicted_class)
accuracy = accuracy_score(y_true, y_pred)
print(f'Test Accuracy: {accuracy:.4f}')
return accuracy
# 예제 테스트 데이터 (실제 데이터로 대체 필요)
test_images = ['path/to/test_image1.jpg', 'path/to/test_image2.jpg', ...]
test_labels = ['class1', 'class2', ...]
# 테스트 데이터셋의 정확도 평가
evaluate_on_test_set(test_images, test_labels, yolo, cnn_model, class_labels)
모델을 제출해야 하는 경우, 보통 다음과 같은 절차를 따르게 됩니다. 여기서는 모델 저장, 로드, 추론 수행, 모델 파일 및 코드 패키징, 그리고 제출 파일 작성 과정을 설명합니다.
1. 모델 저장
모델을 저장하여 나중에 로드하고 사용할 수 있도록 합니다. TensorFlow/Keras에서는 model.save를 사용하여 모델을 저장할 수 있습니다.
# CNN 모델 저장
cnn_model.save('cnn_model.h5')
# YOLO 모델 저장
yolo.save_weights('yolo_weights.tf')
2. 모델 로드
저장된 모델을 로드하는 방법입니다.
# CNN 모델 로드
from tensorflow.keras.models import load_model
cnn_model = load_model('cnn_model.h5')
# YOLO 모델 로드
yolo = YoloV3(classes=80)
yolo.load_weights('yolo_weights.tf')
3. 추론 수행
로드된 모델을 사용하여 새로운 데이터에 대해 추론을 수행합니다.
# YOLO로 객체 탐지 후 CNN으로 분류
img_path = 'path/to/your/test_image.jpg'
img_with_boxes, best_box, best_class = detect_objects(yolo, img_path)
classification = crop_and_classify_object(img_path, best_box, cnn_model, class_labels)
print(classification)
4. 모델 파일 및 코드 패키징
모델 파일과 함께 필요한 코드를 패키징합니다. 예를 들어, model.py라는 파일에 필요한 코드를 작성할 수 있습니다.
4.1 model.py
import tensorflow as tf
from tensorflow.keras.models import load_model
import cv2
import numpy as np
from yolov3_tf2.models import YoloV3
from yolov3_tf2.dataset import transform_images
from yolov3_tf2.utils import draw_outputs
class_names = [c.strip() for c in open('./data/coco.names').readlines()]
def load_image(img_path):
img_raw = tf.image.decode_image(open(img_path, 'rb').read(), channels=3)
img = tf.expand_dims(img_raw, 0)
img = transform_images(img, 416)
return img, img_raw
def detect_objects(yolo, img_path):
img, img_raw = load_image(img_path)
boxes, scores, classes, nums = yolo.predict(img)
best_idx = np.argmax(scores[0])
best_box = boxes[0][best_idx]
best_score = scores[0][best_idx]
best_class = classes[0][best_idx]
img_with_boxes = draw_outputs(img_raw.numpy(), ([best_box], [best_score], [best_class], [1]), class_names)
return img_with_boxes, best_box, best_class
def crop_and_classify_object(img_path, best_box, cnn_model, class_labels):
img_raw = cv2.imread(img_path)
ymin, xmin, ymax, xmax = best_box
ymin, xmin, ymax, xmax = int(ymin * img_raw.shape[0]), int(xmin * img_raw.shape[1]), int(ymax * img_raw.shape[0]), int(xmax * img_raw.shape[1])
cropped_img = img_raw[ymin:ymax, xmin:xmax]
cropped_img = cv2.resize(cropped_img, (224, 224))
cropped_img = np.expand_dims(cropped_img, axis=0) / 255.0
pred = cnn_model.predict(cropped_img)
class_idx = np.argmax(pred, axis=1)
class_name = class_labels[class_idx[0]]
return class_name
def main(img_path):
# 모델 로드
cnn_model = load_model('cnn_model.h5')
yolo = YoloV3(classes=80)
yolo.load_weights('yolo_weights.tf')
# COCO 클래스 이름 로드
class_labels = ['class1', 'class2', 'class3', 'class4', 'class5',
'class6', 'class7', 'class8', 'class9', 'class10']
# 객체 탐지 및 분류
img_with_boxes, best_box, best_class = detect_objects(yolo, img_path)
classification = crop_and_classify_object(img_path, best_box, cnn_model, class_labels)
print(f'Detected object class: {classification}')
return classification
5. 제출 파일 작성
모델 파일, 코드, 필요한 데이터 파일 등을 압축하여 제출합니다. 일반적으로 다음과 같은 파일들을 포함합니다.
- cnn_model.h5 (저장된 CNN 모델)
- yolo_weights.tf (YOLO 모델 가중치)
- model.py (모델 로드 및 추론 코드)
- requirements.txt (필요한 라이브러리 목록)
5.1 requirements.txt
tensorflow==2.4.1
yolov3-tf2==0.1.1
opencv-python-headless==4.5.1.48
numpy==1.19.5
matplotlib==3.3.4
6. 제출
위의 파일들을 모두 포함하여 압축 파일로 만들어 제출합니다.
zip -r submission.zip cnn_model.h5 yolo_weights.tf model.py requirements.txt
이 압축 파일을 제출 시스템에 업로드하면 됩니다.
최종 제출 파일 구조
submission/
│
├── cnn_model.h5
├── yolo_weights.tf
├── model.py
├── requirements.txt
이렇게 제출하면, 제출 시스템에서 model.py를 실행하여 모델을 로드하고 추론을 수행할 수 있습니다.