Post

SK네트웍스 Family AI 캠프 1기 14주차 회고

SK Networks AI Camp

Main image

Weekly 회고 - 14주차

:warning: 포스트를 읽기 전에..
이 포스트는 SK네트웍스 Family AI 캠프를 다니면서 느낀 개인적인 생각을 정리한 포스트입니다.
배운 내용이나 스킬셋에 대한 설명은 별도로 작성하지 않았기 때문에, 그에 대한 정보는 다른 포스트를 참고해주세요!

:thumbsup:Liked

휴가 이후 첫번째 회고록입니다.:raised_hands:
doomsday
휴가 때 많이 쉬어서 그런지 아침에 일어나는데 어려움이 없다는 게 첫번째 좋은 점입니다!
하지만 휴가 이후에 예전보다 공부에 집중하기 어렵다는 단점도 있긴합니다.
그리고 두번째 좋은 점은 이번 주에 LLM을 본격적으로 사용하기 시작했다는 것입니다.
다소 기초적이긴 하지만 문장 분석이나 영화 리뷰를 이용한 감정 분석 등 LLM이라고 할 수 있는 것들을 배우고 실습해보고 했습니다.
아직 배울 부분이 더 많지만 일단 시작은 했다! 라는 점에서 좋은 점이라고 하도록 하겠습니다.


:books:Learned

이번 주에는 기초적인 LLM에 대한 부분도 배웠지만 개인적으로 중요하다고 생각한 것은 LSTM을 이용한 감정 분석입니다.

감정 분석(Sentiment Analysis)

감정 분석이란 자연어 처리의 한 분야로, 텍스트에서 감정을 추출하고 분석하는 기술입니다.
특정 문장이나 문서가 긍정적인지, 부정적인지, 혹은 중립적인지 판단하는데 사용됩니다.
감정 분석은 설문 조사나 SNS 등에서 사람들의 의견을 분석하는 데 사용될 수 있습니다.

LSTM(Long Short-Term Memory)

LSTM이란 RNN(순환 신경망, Recurrent Neural Network)의 한 종류로, 시간에 따른 장기 의존성을 기억하는 능력을 가지고 있습니다.
일반적인 RNN은 시간이 지남에 따라 과거의 정보를 잃어버리는 문제가 있지만, LSTM은 게이트 구조(입력 게이트, 출력 게이트, 망각 게이트)를 이용해 과거 정보를 유지하거나 버리는 방식으로 작동합니다.

Tensorflow와 Keras를 이용한 감정 분석

먼저, 아래와 같이 영화 리뷰 데이터를 불러오고 전처리해줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def preprocess_text(text):
    text = re.sub(r'<.*?>', '', text)  # HTML 태그 제거
    text = re.sub(r'[^A-Za-z\s]', '', text)  # 알파벳 외 문자 제거
    words = text.split(' ')
    filtered = [w for w in words if w not in english_stops]
    return ' '.join(filtered).lower()

def get_max_length(reviews):
    review_length = [len(review) for review in reviews]
    return int(np.ceil(np.mean(review_length)))

def load_and_preprocess_data():
    try:
        global x_train, x_test, y_train, y_test, max_length, total_words
        x_data, y_data = load_dataset()
        x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.2, random_state=42)

        # 토큰화 및 패딩
        token.fit_on_texts(x_train)
        x_train = token.texts_to_sequences(x_train)
        x_test = token.texts_to_sequences(x_test)

        max_length = get_max_length(x_train)
        x_train = pad_sequences(x_train, maxlen=max_length, padding='post', truncating='post')
        x_test = pad_sequences(x_test, maxlen=max_length, padding='post', truncating='post')

        total_words = len(token.word_index) + 1
        print("Data loading and preprocessing completed.")
    except Exception as e:
        print(f"Error during data loading and preprocessing: {e}")

LSTM 모델을 정의하고 토큰화된 데이터를 학습합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
async def train_model():
    global x_train, y_train, model_file_path
    if 'x_train' not in globals():
        return JSONResponse(content={"message": "Data not loaded. Load data first."}, status_code=404)

    try:
        EMBED_DIM = 32
        LSTM_OUT = 64
        model = Sequential()
        model.add(Embedding(total_words, EMBED_DIM, input_length=max_length))
        model.add(LSTM(LSTM_OUT))
        model.add(Dense(1, activation='sigmoid'))
        model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

        checkpoint = ModelCheckpoint(model_file_path, monitor='accuracy', save_best_only=True, verbose=1)

        model.fit(x_train, y_train, epochs=5, batch_size=128, callbacks=[checkpoint])

        return JSONResponse(content={"message": "Model trained and saved."})
    except Exception as e:
        print(f"Error during model training: {e}")
        raise HTTPException(status_code=500, detail=str(e))

위의 과정이 완료되면 데이터를 이용하여 모델이 학습되고, 학습된 모델은 저장됩니다.
그리고 Postman을 이용하여 분석하고자 하는 문장을 입력하면 아래 함수를 이용하여 감정 분석이 진행됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async def predict(text: str):
    try:
        if not os.path.exists(model_file_path):
            raise HTTPException(status_code=404, detail="Model not found. Train the model first.")

        model = load_model(model_file_path)
        preprocessed_text = preprocess_text(text)
        tokenize_words = token.texts_to_sequences([preprocessed_text])
        tokenize_words = pad_sequences(tokenize_words, maxlen=max_length, padding='post', truncating='post')

        result = model.predict(tokenize_words)
        sentiment = "positive" if result >= 0.7 else "negative"

        return JSONResponse(content={"sentiment": sentiment})
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

이렇게 하면 입력된 문장이 Positive:relaxed:인지 Negative:rage:인지 알 수 있습니다.


:face_with_spiral_eyes:Lacked

휴가 이후 체력은 많이 회복된 것 같은데 자꾸 피곤합니다.:pensive: tired
그리고 공부에 대한 의지가 조금 꺾인 것 같아서 다시 분발해야될 것 같습니다!
그리고 소켓 통신을 이용하여 FastAPI와 DLLS(Deep Learning Local Server)를 연결하는 과정을 진행중인데, 생각처럼 쉽지 않아서 많이 헤매고 있습니다.
소켓 통신에 대한 이해도가 부족해서 생기는 문제인 것 같아서 이 부분에 대한 공부가 더 필요할 것 같습니다.


:thought_balloon:Longed for

첫번째는 스터디에 꾸준히 참여할 수 있으면 좋겠다는 것입니다.:pencil:
study-hard
알고리즘 스터디, LLM 스터디, CS 스터디 이렇게 총 3개의 스터디를 진행하고 있는데, 스터디마다 자료를 만들어야 해서 다소 부담감이 있습니다.
하지만 자료를 만들면서 스스로 몰랐던 내용을 알게된다는 장점도 있어서 꾸준히 해보고자 합니다.
두번째는 원래 생활 패턴을 찾는 것입니다.
아직 휴가 때 편하게 있었던 것에서 벗어나지 못한 것 같습니다.
주말동안 서서히 템포를 올려서 예전처럼 열심히 해보도록 하겠습니다!:fire:

This post is licensed under CC BY 4.0 by the author.