뭔가 GPT로 요즘 kaggle도 씹어 먹을 수 있다 그래서 한번 쯤 진행해 보고 싶었던 내용입니다.
GPT한테 대회 규정 다 던져주고, 이 가이드 라인에 따라 제작해달라고 하니까 작성해줍니다.
o1-preview는 사용 횟수에 제한이 있으니 적절히 사용해야 되니까 4o를 많이 사용해서 최대한 요약했습니다.
가이드라인: 제1회 MAI 경진대회 준비
1. 대회 목표 및 데이터 분석
- 목표: H&E 염색된 조직 이미지를 통해 유전자 발현 정보를 예측하는 모델 개발.
- 데이터:
- 학습 데이터: 6992개의 이미지와 3467개의 유전자 발현 정보.
- 테스트 데이터: 2277개의 이미지 (유전자 발현 정보는 제공되지 않음).
- 특징*: 각 이미지에 대해 다차원적인 유전자 발현 정보를 추론해야 하므로, 이미지 처리와 고차원 예측 능력을 모두 갖춘 모델이 필요.
2. 모델 선택 전략
이미지 데이터를 처리해야 하므로, 이미지 처리에 강한 모델이 필요합니다. 이를 위해 Convolutional Neural Networks (CNNs) 기반의 모델을 추천하며, 유전자 발현 정보를 다차원으로 예측하기 위해서 다층 출력 레이어를 적용해야 합니다.
다음과 같은 모델을 고려할 수 있습니다:
- Pretrained CNN: 이미지넷(ImageNet)으로 사전 학습된 CNN 모델을 이용하고, 해당 모델을 Fine-tuning하여 의료 이미지에 적합하도록 조정.
- 추천 모델: ResNet, EfficientNet 등. 이미 널리 사용되고 성능이 검증된 모델들이며, 경량화와 정확도의 균형이 좋습니다.
- 전이 학습: 사전 학습된 가중치를 가져와 새로운 의료 데이터를 학습할 때 훨씬 적은 데이터로도 높은 성능을 기대할 수 있음.
- Multi-output Neural Network: 각 이미지에 대해 다차원(3467개 유전자) 출력을 내는 모델 필요. CNN의 마지막 레이어를 변형해 다층 Fully Connected Layer를 활용하여 유전자 발현을 추정할 수 있는 구조로 설계.
- Ensemble Models: CNN 기반의 여러 모델을 앙상블하여 다양한 패턴을 포착할 수 있도록 하여 성능을 높일 수 있음.
3. 데이터 전처리 전략
- 이미지 크기 조정: 모델 학습에 적합한 크기로 이미지 리사이징. 일반적으로 224x224 또는 299x299 크기가 많이 사용됨.
- 데이터 증강: 이미지 데이터를 다각적으로 증강해 학습 데이터 수를 늘림.
- 방법: 회전, 자르기, 밝기 조정 등
- 정규화: 유전자 발현 값이 다차원적이고 서로 범위가 다를 수 있으므로, min-max scaling 또는 표준화를 통해 값의 범위를 통일.
4. 학습 및 검증 전략
- 손실 함수: 유전자 발현 예측이 회귀 문제에 해당하므로, Mean Squared Error (MSE) 또는 Mean Absolute Error (MAE)를 사용.
- 평가 지표: 대회에서 Pearson Correlation Coefficient (PCC)를 평가 기준으로 사용하므로, 학습 과정에서 이를 모니터링하며 성능을 확인.
- K-Fold Cross Validation: 데이터를 여러 폴드로 나누어 다양한 학습/검증 셋을 구성하여 과적합 방지.
5. 모델 최적화 및 제출
- Hyperparameter Tuning: 학습률, 배치 크기, 드롭아웃 비율 등을 조정하며 최적의 모델을 찾아야 함.
- 모델 경량화: 최종 제출 시 용량 제한(250MB)이 있으므로, 모델 프루닝 또는 양자화를 통해 모델 크기를 줄이는 작업도 필요.
- 앙상블 및 모델 병합: 여러 모델의 예측 결과를 앙상블하여 최종 결과 제출 시 성능을 극대화.
6. 주의 사항
- 제출 횟수 제한: 하루 최대 3회 제출 가능하므로, 제출 전 철저히 검증하고 제출.
- 데이터 유출 방지: 평가 데이터셋에 대한 정보가 학습에 사용되지 않도록 주의해야 함.
- 코드 및 환경 관리: 코드의 경로, 라이브러리 버전 등을 명확히 작성해 재현 가능하게 관리.
이러한 전략을 바탕으로 계획을 수립하고, 실험 및 검증을 통해 최적의 모델을 개발해나가면 됩니다. 추가적으로 대회 중 진행상황에 따라 다양한 전략을 병행하면서 유연하게 대응할 필요가 있습니다.
대회의 가이드라인을 바탕으로 Python 코드를 작성해보겠습니다. 이 코드는 기본적으로 CNN 모델을 사용하여 H&E 염색된 조직 이미지를 입력받고 유전자 발현 정보를 예측하는 구조입니다. 또한 데이터 전처리와 학습 과정이 포함됩니다.
1. 라이브러리 임포트
import os
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
from tensorflow.keras.models import Model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.metrics import mean_squared_error, mean_absolute_error
2. 데이터 로드 및 전처리
# 파일 경로 설정
train_csv = 'train.csv'
test_csv = 'test.csv'
train_images_dir = 'train'
test_images_dir = 'test'
# 데이터 로드
train_df = pd.read_csv(train_csv)
test_df = pd.read_csv(test_csv)
# 유전자 발현 정보와 이미지 경로 분리
X = train_df['path'].values
y = train_df.drop(['ID', 'path'], axis=1).values # 유전자 발현 정보
# 이미지 파일 경로에 접근
train_df['path'] = train_df['path'].apply(lambda x: os.path.join(train_images_dir, x))
test_df['path'] = test_df['path'].apply(lambda x: os.path.join(test_images_dir, x))
# 데이터 전처리: 이미지 데이터 증강
img_size = 224 # ResNet50 기본 이미지 사이즈
batch_size = 32
datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=15,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
def load_image(image_path):
img = tf.keras.preprocessing.image.load_img(image_path, target_size=(img_size, img_size))
img = tf.keras.preprocessing.image.img_to_array(img)
return img
# 이미지 데이터 로드
X_images = np.array([load_image(path) for path in train_df['path']])
3. 데이터 분할 및 정규화
# 데이터 스케일링
scaler = StandardScaler()
y_scaled = scaler.fit_transform(y)
# 학습/검증 데이터 분할
X_train, X_val, y_train, y_val = train_test_split(X_images, y_scaled, test_size=0.2, random_state=42)
4. 모델 정의 (ResNet50 기반 Fine-tuning)
# ResNet50 모델 로드 (ImageNet으로 사전 학습된 가중치 사용)
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(img_size, img_size, 3))
# Fine-tuning: ResNet50 위에 새로운 출력층 추가
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dropout(0.5)(x)
outputs = Dense(3467, activation='linear')(x) # 유전자 발현값 예측 (3467개의 유전자)
# 최종 모델 정의
model = Model(inputs=base_model.input, outputs=outputs)
# 학습 시 이전 레이어들은 고정하고 마지막 층만 학습
for layer in base_model.layers:
layer.trainable = False
# 모델 컴파일
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), loss='mean_squared_error')
# 모델 요약 출력
model.summary()
5. 모델 학습 설정
# 모델 체크포인트와 조기 종료 설정
checkpoint = ModelCheckpoint('best_model.h5', monitor='val_loss', save_best_only=True, mode='min', verbose=1)
early_stop = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
# 학습
history = model.fit(
datagen.flow(X_train, y_train, batch_size=batch_size),
validation_data=(X_val, y_val),
epochs=100,
callbacks=[checkpoint, early_stop],
steps_per_epoch=len(X_train) // batch_size,
validation_steps=len(X_val) // batch_size,
verbose=1
)
6. 모델 평가 및 테스트 예측
# 검증 데이터에 대한 예측 및 평가
y_pred = model.predict(X_val)
mse = mean_squared_error(y_val, y_pred)
mae = mean_absolute_error(y_val, y_pred)
print(f"Validation MSE: {mse}, MAE: {mae}")
# 테스트 데이터 로드 및 예측
X_test_images = np.array([load_image(path) for path in test_df['path']])
test_predictions = model.predict(X_test_images)
# 예측 결과를 스케일링 해제
test_predictions_rescaled = scaler.inverse_transform(test_predictions)
# 제출 파일 생성
submission = pd.DataFrame(test_predictions_rescaled, columns=train_df.columns[2:])
submission.insert(0, 'ID', test_df['ID'])
submission.to_csv('sample_submission.csv', index=False)
7. 제출 준비
이 코드를 통해 모델이 학습되고, 테스트 데이터에 대한 예측이 이루어집니다. 예측 결과는 sample_submission.csv
파일로 저장되며, 이를 대회에 제출할 수 있습니다.
개선 방안:
- 하이퍼파라미터 튜닝: 학습률, 배치 크기 등을 조정하여 성능을 개선.
- 앙상블: 여러 모델을 앙상블하여 성능을 높임.
- 모델 최적화: 모델 경량화와 프루닝(pruning)으로 크기를 줄임.
사전 학습 모델에 한계를 느끼고 모델을 처음부터 다시 만들어 보자!
만약 사전 학습된 모델을 사용하지 않고, 처음부터 모델을 학습하고 싶다면 기본적인 CNN 모델을 설계하여 학습을 진행할 수 있습니다. 이 경우 ResNet50과 같은 복잡한 아키텍처 대신, 커스텀 CNN 모델을 설계하여 H&E 염색된 조직 이미지 데이터를 처리하고 유전자 발현 정보를 예측하도록 만들 수 있습니다.
CNN 모델 설계 및 학습 코드
1. 필요한 라이브러리 임포트
import os
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, GlobalAveragePooling2D
from tensorflow.keras.models import Sequential
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.metrics import mean_squared_error, mean_absolute_error
2. 데이터 로드 및 전처리
# 파일 경로 설정
train_csv = 'train.csv'
test_csv = 'test.csv'
train_images_dir = 'train'
test_images_dir = 'test'
# 데이터 로드
train_df = pd.read_csv(train_csv)
test_df = pd.read_csv(test_csv)
# 유전자 발현 정보와 이미지 경로 분리
X = train_df['path'].values
y = train_df.drop(['ID', 'path'], axis=1).values # 유전자 발현 정보
# 이미지 파일 경로에 접근
train_df['path'] = train_df['path'].apply(lambda x: os.path.join(train_images_dir, os.path.basename(x)))
test_df['path'] = test_df['path'].apply(lambda x: os.path.join(test_images_dir, os.path.basename(x)))
# 이미지 전처리 및 증강
img_size = 224 # 이미지 크기 (224x224)
batch_size = 32
datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=15,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
def load_image(image_path):
img = tf.keras.preprocessing.image.load_img(image_path, target_size=(img_size, img_size))
img = tf.keras.preprocessing.image.img_to_array(img)
return img
# 이미지 데이터 로드
X_images = np.array([load_image(path) for path in train_df['path']])
# 유전자 발현 값 스케일링
scaler = StandardScaler()
y_scaled = scaler.fit_transform(y)
# 학습/검증 데이터 분할
X_train, X_val, y_train, y_val = train_test_split(X_images, y_scaled, test_size=0.2, random_state=42)
3. 커스텀 CNN 모델 설계
# CNN 모델 정의
model = Sequential()
# 첫 번째 Conv2D 레이어
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(img_size, img_size, 3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
# 두 번째 Conv2D 레이어
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# 세 번째 Conv2D 레이어
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# 네 번째 Conv2D 레이어
model.add(Conv2D(256, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# Global Average Pooling
model.add(GlobalAveragePooling2D())
# 완전 연결층
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
# 출력 레이어 (3467개의 유전자 예측)
model.add(Dense(3467, activation='linear')) # 회귀 문제이므로 'linear' 사용
# 모델 컴파일
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), loss='mean_squared_error')
# 모델 요약 출력
model.summary()
4. 모델 학습 및 검증 설정
# 모델 체크포인트와 조기 종료 설정
checkpoint = ModelCheckpoint('best_custom_model.keras', monitor='val_loss', save_best_only=True, mode='min', verbose=1)
early_stop = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
# 학습
history = model.fit(
datagen.flow(X_train, y_train, batch_size=batch_size),
validation_data=(X_val, y_val),
epochs=100,
callbacks=[checkpoint, early_stop],
steps_per_epoch=len(X_train) // batch_size,
validation_steps=len(X_val) // batch_size,
verbose=1
)
5. 모델 평가 및 테스트 예측
# 검증 데이터에 대한 예측 및 평가
y_pred = model.predict(X_val)
mse = mean_squared_error(y_val, y_pred)
mae = mean_absolute_error(y_val, y_pred)
print(f"Validation MSE: {mse}, MAE: {mae}")
# 테스트 데이터 로드 및 예측
X_test_images = np.array([load_image(path) for path in test_df['path']])
test_predictions = model.predict(X_test_images)
# 예측 결과를 스케일링 해제
test_predictions_rescaled = scaler.inverse_transform(test_predictions)
# 제출 파일 생성
submission = pd.DataFrame(test_predictions_rescaled, columns=train_df.columns[2:])
submission.insert(0, 'ID', test_df['ID'])
submission.to_csv('sample_submission.csv', index=False)
주요 사항:
- CNN 모델: 기본적인 CNN 모델 구조로 이미지를 처리하고, 유전자 발현 정보를 예측할 수 있도록 설계되었습니다.
- 전처리: 이미지를
(224x224)
크기로 변환하고 데이터 증강을 적용하여 과적합을 방지하고 학습 데이터의 다양성을 증가시킵니다. - 모델 출력: 회귀 문제로 출력 레이어에서
linear
활성화 함수를 사용하여 3467개의 유전자 발현을 예측합니다. - 조기 종료 및 체크포인트: 조기 종료와 체크포인트를 적용하여 최적의 모델을 저장하고, 불필요한 학습을 방지합니다.
이 모델은 처음부터 학습하며, 사전 학습된 가중치를 사용하지 않고 데이터를 학습하게 됩니다.
레이어 복잡하게 만들어줘!
더 복잡한 모델 구조를 설계하려면 더 많은 레이어, 다양한 레이어 구성, 그리고 정규화 기법을 추가하여 학습 성능을 개선할 수 있습니다. 또한, Residual Connections나 Batch Normalization, Dropout 같은 기법을 사용하여 모델의 학습 안정성과 성능을 높일 수 있습니다.
아래는 기존의 CNN 구조보다 더 복잡하고 체계적인 CNN 아키텍처입니다. 이 모델은 Residual Connections와 Batch Normalization을 추가로 적용하여 학습 성능을 개선할 수 있도록 설계했습니다.
1. 필요한 라이브러리 임포트
이미 임포트된 라이브러리를 사용할 수 있지만, 여기에 Batch Normalization과 Residual Block을 추가하기 위한 부분을 포함한 코드를 제공하겠습니다.
import os
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, GlobalAveragePooling2D
from tensorflow.keras.layers import BatchNormalization, Add, Input
from tensorflow.keras.models import Model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.metrics import mean_squared_error, mean_absolute_error
2. Residual Block 정의
Residual Block은 CNN 네트워크에서 매우 효과적인 기법으로, 깊은 네트워크에서의 vanishing gradient 문제를 해결하는 데 도움이 됩니다.
def residual_block(x, filters, kernel_size=3, stride=1):
# 첫 번째 Conv 레이어
res = Conv2D(filters, kernel_size, strides=stride, padding='same', activation='relu')(x)
res = BatchNormalization()(res)
# 두 번째 Conv 레이어
res = Conv2D(filters, kernel_size, strides=1, padding='same', activation=None)(res)
res = BatchNormalization()(res)
# Skip connection
shortcut = Conv2D(filters, kernel_size=(1, 1), strides=stride, padding='same')(x)
# 두 출력을 더함
out = Add()([res, shortcut])
out = tf.keras.activations.relu(out)
return out
3. 커스텀 CNN 모델 설계 (Residual + Batch Normalization)
이제 더 복잡한 CNN 모델을 정의해 보겠습니다. Residual Block을 네트워크에 추가하고, Batch Normalization을 통해 학습 성능을 향상시킵니다.
def build_model(input_shape):
inputs = Input(shape=input_shape)
# 첫 번째 Residual Block
x = Conv2D(64, (3, 3), padding='same', activation='relu')(inputs)
x = BatchNormalization()(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
# 두 번째 Residual Block
x = residual_block(x, filters=128)
x = MaxPooling2D(pool_size=(2, 2))(x)
# 세 번째 Residual Block
x = residual_block(x, filters=256)
x = MaxPooling2D(pool_size=(2, 2))(x)
# 네 번째 Residual Block
x = residual_block(x, filters=512)
x = MaxPooling2D(pool_size=(2, 2))(x)
# Global Average Pooling
x = GlobalAveragePooling2D()(x)
# 완전 연결층
x = Dense(1024, activation='relu')(x)
x = Dropout(0.5)(x)
# 출력층 (3467개의 유전자 발현 예측)
outputs = Dense(3467, activation='linear')(x)
# 모델 정의
model = Model(inputs=inputs, outputs=outputs)
# 모델 컴파일
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), loss='mean_squared_error')
return model
4. 데이터 로드 및 전처리
기존 코드와 동일하게 데이터를 로드하고 전처리합니다.
# 이미지 경로 및 유전자 발현 데이터 로드
train_df['path'] = train_df['path'].apply(lambda x: os.path.join(train_images_dir, os.path.basename(x)))
test_df['path'] = test_df['path'].apply(lambda x: os.path.join(test_images_dir, os.path.basename(x)))
X_images = np.array([load_image(path) for path in train_df['path']])
# 유전자 발현 정보 스케일링
scaler = StandardScaler()
y_scaled = scaler.fit_transform(y)
# 학습/검증 데이터 분할
X_train, X_val, y_train, y_val = train_test_split(X_images, y_scaled, test_size=0.2, random_state=42)
5. 모델 학습 및 검증
이제 새로 설계한 모델을 사용해 학습을 진행합니다.
# 모델 생성
model = build_model(input_shape=(img_size, img_size, 3))
# 모델 체크포인트와 조기 종료 설정
checkpoint = ModelCheckpoint('best_complex_model.keras', monitor='val_loss', save_best_only=True, mode='min', verbose=1)
early_stop = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
# 모델 학습
history = model.fit(
datagen.flow(X_train, y_train, batch_size=batch_size),
validation_data=(X_val, y_val),
epochs=100,
callbacks=[checkpoint, early_stop],
steps_per_epoch=len(X_train) // batch_size,
validation_steps=len(X_val) // batch_size,
verbose=1
)
6. 모델 평가 및 테스트 예측
기존 코드와 동일하게 모델을 평가하고 예측합니다.
# 검증 데이터에 대한 예측 및 평가
y_pred = model.predict(X_val)
mse = mean_squared_error(y_val, y_pred)
mae = mean_absolute_error(y_val, y_pred)
print(f"Validation MSE: {mse}, MAE: {mae}")
# 테스트 데이터 로드 및 예측
X_test_images = np.array([load_image(path) for path in test_df['path']])
test_predictions = model.predict(X_test_images)
# 예측 결과를 스케일링 해제
test_predictions_rescaled = scaler.inverse_transform(test_predictions)
# 제출 파일 생성
submission = pd.DataFrame(test_predictions_rescaled, columns=train_df.columns[2:])
submission.insert(0, 'ID', test_df['ID'])
submission.to_csv('sample_submission.csv', index=False)
주요 개선 사항:
- Residual Blocks: 네트워크가 깊어졌을 때 발생할 수 있는 vanishing gradient 문제를 해결하기 위해 Residual Blocks을 추가하여 학습이 원활하게 진행되도록 합니다.
- Batch Normalization: 각 레이어의 출력을 정규화하여 학습 속도를 높이고, 모델이 과적합하지 않도록 돕습니다.
- Dropout: 완전 연결층에 Dropout을 적용하여 과적합을 방지합니다.
- 더 깊고 복잡한 아키텍처: 더 많은 필터와 깊이를 추가하여 이미지 데이터를 더 세밀하게 처리할 수 있습니다.
이 모델은 더 복잡한 구조로 설계되었으며, 높은 점수를 얻을 가능성이 높아졌습니다. 이제 해당 모델을 기반으로 여러 실험을 진행하며 성능을 최적화해보세요.
이 전까지는 점수가 굉장히 낮습니다.
학습만 해도 오버피팅이 주르륵....
이제 어떻게 하는지 알았으니 o1-preview 를 시켜봅니다
다음은 주어진 데이터를 사용하여 이미지를 입력으로 3467개의 유전자 발현을 예측하는 딥러닝 모델을 구축하는 코드입니다. 데이터셋의 크기가 작기 때문에 과적합을 방지하고 일반화 능력을 향상시키기 위해 전이 학습과 데이터 증강을 사용합니다.
import os
import pandas as pd
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import EfficientNetB0
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
from sklearn.model_selection import train_test_split
# 파일 경로 설정
train_csv = 'train.csv'
test_csv = 'test.csv'
train_images_dir = 'train'
test_images_dir = 'test'
# 데이터 로드
train_df = pd.read_csv(train_csv)
test_df = pd.read_csv(test_csv)
# 이미지 파일 경로 수정
train_df['path'] = train_df['path'].apply(lambda x: os.path.join(train_images_dir, os.path.basename(x)))
test_df['path'] = test_df['path'].apply(lambda x: os.path.join(test_images_dir, os.path.basename(x)))
# 유전자 발현 컬럼 리스트 생성
gene_columns = train_df.columns.drop(['ID', 'path'])
# 데이터 분할 (훈련/검증)
train_df, valid_df = train_test_split(train_df, test_size=0.2, random_state=42)
# 이미지 증강을 위한 ImageDataGenerator 설정
train_datagen = ImageDataGenerator(
rescale=1./255,
horizontal_flip=True,
vertical_flip=True,
rotation_range=15,
zoom_range=0.1,
width_shift_range=0.1,
height_shift_range=0.1
)
valid_datagen = ImageDataGenerator(rescale=1./255)
# 데이터 제너레이터 생성
train_generator = train_datagen.flow_from_dataframe(
dataframe=train_df,
x_col='path',
y_col=gene_columns.tolist(),
target_size=(224, 224),
batch_size=32,
class_mode='raw',
shuffle=True
)
valid_generator = valid_datagen.flow_from_dataframe(
dataframe=valid_df,
x_col='path',
y_col=gene_columns.tolist(),
target_size=(224, 224),
batch_size=32,
class_mode='raw',
shuffle=False
)
# 모델 구축 (EfficientNetB0 사용)
base_model = EfficientNetB0(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
# 베이스 모델의 가중치 고정
for layer in base_model.layers:
layer.trainable = False
# 모델 아키텍처 구성
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
predictions = Dense(3467, activation='linear')(x)
model = Model(inputs=base_model.input, outputs=predictions)
# 모델 컴파일
model.compile(optimizer=Adam(learning_rate=1e-3), loss='mean_squared_error')
# 콜백 설정
callbacks = [
ModelCheckpoint('best_model.h5', monitor='val_loss', save_best_only=True, mode='min'),
EarlyStopping(monitor='val_loss', patience=10, mode='min'),
ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-7, mode='min')
]
# 스텝 계산
train_steps = train_generator.n // train_generator.batch_size
valid_steps = valid_generator.n // valid_generator.batch_size
# 모델 학습 (1단계: 상위 레이어 학습)
history = model.fit(
train_generator,
steps_per_epoch=train_steps,
validation_data=valid_generator,
validation_steps=valid_steps,
epochs=10,
callbacks=callbacks
)
# 베이스 모델의 일부 레이어를 학습 가능하게 설정 (미세 조정)
for layer in base_model.layers[-20:]:
layer.trainable = True
# 모델 재컴파일
model.compile(optimizer=Adam(learning_rate=1e-4), loss='mean_squared_error')
# 모델 학습 (2단계: 미세 조정)
history_fine = model.fit(
train_generator,
steps_per_epoch=train_steps,
validation_data=valid_generator,
validation_steps=valid_steps,
epochs=50,
callbacks=callbacks
)
# 테스트 데이터 제너레이터 생성
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_dataframe(
dataframe=test_df,
x_col='path',
y_col=None,
target_size=(224, 224),
batch_size=32,
class_mode=None,
shuffle=False
)
# 예측 수행
test_steps = test_generator.n // test_generator.batch_size + 1
predictions = model.predict(test_generator, steps=test_steps, verbose=1)
# 예측 결과를 데이터프레임으로 변환
pred_df = pd.DataFrame(predictions, columns=gene_columns)
pred_df['ID'] = test_df['ID'].values
# 결과 저장
pred_df.to_csv('submission.csv', index=False)
설명:
- 데이터 전처리 및 증강:
ImageDataGenerator
를 사용하여 이미지 데이터를 실시간으로 증강하고 전처리합니다. 이는 작은 데이터셋에서 모델의 일반화 능력을 향상시키는 데 도움이 됩니다. - 모델 구성:
EfficientNetB0
사전 학습된 모델을 사용하여 이미지 특징을 추출합니다. 출력 레이어는 3467개의 뉴런으로 구성되며, 각 유전자 발현을 예측합니다. - 전이 학습과 미세 조정: 초기에는 베이스 모델의 가중치를 고정하고 상위 레이어만 학습합니다. 그런 다음 일부 베이스 모델의 레이어를 학습 가능하게 변경하여 모델을 미세 조정합니다.
- 모델 컴파일 및 학습:
mean_squared_error
손실 함수를 사용하여 모델을 컴파일하고 학습합니다.EarlyStopping
과ReduceLROnPlateau
콜백을 사용하여 과적합을 방지하고 학습률을 조정합니다. - 예측 및 저장: 학습된 모델을 사용하여 테스트 데이터에 대한 예측을 수행하고 결과를 CSV 파일로 저장합니다.
추가 고려사항:
- 정규화: 유전자 발현 값의 범위가 다양할 수 있으므로, 입력 데이터와 출력 데이터를 정규화하거나 표준화하는 것이 도움이 될 수 있습니다.
- 평가 지표: 회귀 문제에 적합한 평가 지표(예: MSE, MAE)를 사용하여 모델의 성능을 평가합니다.
- 모델 튜닝: 하이퍼파라미터(예: 학습률, 배치 크기)를 조정하여 모델의 성능을 향상시킬 수 있습니다.
주의사항:
- 데이터셋의 크기가 작고 출력 차원이 매우 크기 때문에(3467개) 모델이 과적합될 수 있습니다. 따라서 데이터 증강, 정규화, 드롭아웃 등의 기법을 활용하여 과적합을 방지해야 합니다.
- 가능한 경우, 중요한 유전자 발현만 선택하거나 차원 축소 기법을 적용하여 출력 차원을 감소시키는 것도 고려해볼 수 있습니다.
위의 코드를 기반으로 모델을 구축하고 성능을 평가해보세요. 필요에 따라 추가적인 조정을 통해 정확도를 향상시킬 수 있습니다.
validation loss가 상당히 떨어진 것을 볼 수 있습니다.
이게 메트릭 차이인지 한번 더 확인이 필요하긴 하지만 그래도 좋은 현상 같습니다.
'인공지능 > gpt 활용' 카테고리의 다른 글
gpt 활용 노이즈 제거 및 업스케일링 최종 (1) | 2024.05.16 |
---|---|
gpt4o 활용 업스케일링, 노이즈 제거방식 비교하기 (0) | 2024.05.16 |
GPT 활용하여 사진 noise 제거 및 upscaling 분석 (0) | 2024.05.15 |
인공지능,gpts 활용하여 일본 여행 친구 만들기! - 번역, 메뉴 추천, 여행지 추천 ! (2) | 2024.01.09 |
아직은 미약한 친구에요... (1) | 2023.11.21 |