본문 바로가기
네이버클라우드/AI

AI 5일차 (2023-05-12) 인공지능 기초 - Imdb 와 Rueters

by prometedor 2023. 5. 12.

Imdb

ㄴ IMDB(Internet Movie Database)

ㄴ 긍정 부정 영화 리뷰(이진분류)

ㄴ 각 리뷰에 대한 긍정 또는 부정의 감성을 예측하는 감성 분석 문제를 풀기 위한 데이터셋

ㄴ 훈련용(train) 리뷰 25,000개와 테스트용(test) 리뷰 25,000개로 구성

ㄴ 각각 50%는 긍정 리뷰와 50%는 부정 리뷰입

 

VSCode 이용

 

tf21_embedding_imdb.py

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding, Dropout
from keras.datasets import imdb
from keras.preprocessing.text import Tokenizer
from keras_preprocessing.sequence import pad_sequences
import time

(x_train, y_train), (x_test, y_test) = imdb.load_data(	# imdb 데이터셋을 로드하여 x_train, y_train, x_test, y_test를 분리
    num_words=10000 # embedding layer 의 input_dim(가장 빈번하게 등장하는 단어 10000개로 제한)
)
print(x_train)
print(x_train.shape, y_train.shape)	# (25000,) (25000,)
print(np.unique(y_train, return_counts=True))   # unique한 label의 개수를 출력
						# return_counts=True는 고유한 값들이 몇 번 나타났는지에 대한 정보를 함께 반환하도록 하는 파라미터
						# y_train의 고유한 값들과 각 값들이 등장한 횟수를 반환하는 함수
						# y_train에서 어떤 클래스(positive/negative)가 얼마나 등장하는지 알 수 있음
						# 반환값은 튜플(tuple) 형태로 (고유값들의 배열, 각 고유값들의 등장 횟수 배열)로 나타남
print(len(np.unique(y_train)))  # 2

# 최대 길이와 평균 길이
print('리뷰의 최대 길이 : ', max(len(i) for i in x_train))
print('리뷰의 평균 길이 : ', sum(map(len, x_train)) / len(x_train))


# pad_sequences
x_train = pad_sequences(x_train, padding='pre',
                       maxlen=100)
x_test = pad_sequences(x_test, padding='pre',
                      maxlen=100)

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

# 2. 모델 구성
model = Sequential()
model.add(Embedding(input_dim = 10000, output_dim = 100))
model.add(LSTM(128, activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(64, activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(64, activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(1, activation = 'sigmoid'))

model.summary()


# [실습] 코드 완성하기

# 3. 컴파일, 훈련
model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics='accuracy')

## EarlyStopping
from keras.callbacks import EarlyStopping, ModelCheckpoint

# Model Check Point
mcp = ModelCheckpoint(
    monitor='val_loss',
    mode='auto',
    verbose=1,
    # save_weights_only=False,
    save_best_only=True,
    filepath='./_mcp/embedding_imdb.hdf5'
)

earlyStopping = EarlyStopping(monitor='val_loss', patience=10, mode='min',  # mode='auto'가 기본, patience=100 --> 100부터 줄여나가기
                              verbose=1, restore_best_weights=True) # restore_best_weights --> default 는 False 이므로 True 로 꼭!!! 변경!!!  

start_time = time.time()    # 시작 시간

model.fit(x_train, y_train, epochs=100, 
          batch_size=32, validation_split=0.2,
          callbacks=[earlyStopping, mcp])  # early Stopping 을 할 것

end_time = time.time() - start_time


# 4. 평가, 예측
loss, acc = model.evaluate(x_test, y_test)
print('loss : ', loss)
print('acc : ', acc)

# Epoch 13: early stopping
# loss :  0.4743201434612274
# acc :  0.777999997138977

** 참고

np.unique(y_train, return_counts=True)

--> np.unique : y_train의 고유한 값들과 각 값들이 등장한 횟수를 반환하는 함수
--> return_counts : 고유한 값들이 몇 번 나타났는지에 대한 정보를 함께 반환하도록 하는 파라미터
--> y_train에서 어떤 클래스(positive/negative)가 얼마나 등장하는지 알 수 있음
--> 반환값은 튜플(tuple) 형태로 (고유값들의 배열, 각 고유값들의 등장 횟수 배열)로 나타남

 

print(np.unique(y_train, return_counts=True)) 의 출력 값 : (array([0, 1]), array([12500, 12500]))

--> y_train(훈련 데이터)는 0  또는 1 의 값을 가지고 있고, 0 과 1 각각 12500 개의 데이터를 가지고 있음을 의미 (0 과 1 일 확률 각각 50%)

 


**Jupyter 이용 시 주의

pip install numpy==1.19.5         # numpy 버전 이슈로 LSTM 실행이 안됨

 

 

Jupyter 이용

Rueters

ㄴ 46개의 뉴스 토픽 기사(다중분류)

 

tf02_Embedding_reuter.ipynb

# pip install numpy==1.19.5 # numpy 버전 이슈로 LSTM 실행이 안됨

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding, Dropout
from keras.datasets import reuters
from keras.preprocessing.sequence import pad_sequences
import time

# 1. 데이터
(x_train, y_train), (x_test, y_test) = reuters.load_data(
    num_words = 10000
)

print(x_train.shape, x_test.shape)	# (8982,) (2246,)

# print(np.unique(y_train, return_counts=True))   # 데이터 확인
print(x_train.shape, x_test.shape)	# (8982,) (2246,)
print(len(np.unique(y_train)))  # 46

print('뉴스 기사의 최대 길이 : ', max(len(i) for i in x_train))
print('뉴스 기사의 평균 길이 : ', sum(map(len, x_train)) / len(x_train))
# 뉴스 기사의 최대 길이 :  2376
# 뉴스 기사의 평균 길이 :  145.5398574927633

#pad_sequences
x_train = pad_sequences(x_train, padding = 'pre', maxlen = 100)
x_test = pad_sequences(x_test, padding='pre', maxlen = 100)

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
# (8982, 100) (8982,)
# (2246, 100) (2246,)



# 2. 모델 구성
model = Sequential()
model.add(Embedding(input_dim = 10000,
                   output_dim = 100))  # maxlen = 100
model.add(LSTM(128, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(46, activation='softmax'))   # 다중분류 이므로 softmax

model.summary()

# 3. 컴파일, 훈련
model.compile(loss='sparse_categorical_crossentropy',
             optimizer='adam',
             metrics='accuracy')

## EarlyStopping
from keras.callbacks import EarlyStopping, ModelCheckpoint

# Model Check Point
mcp = ModelCheckpoint(
    monitor='val_loss',
    mode='auto',
    verbose=1,
    # save_weights_only=False,
    save_best_only=True,
    filepath='./_mcp/embedding_reuter.hdf5'
)

earlyStopping = EarlyStopping(monitor='val_loss', patience=10, mode='min',  # mode='auto'가 기본, patience=10 : 검증 손실이 10 epoch 동안 향상되지 않으면 학습을 중지
                              verbose=1, restore_best_weights=True) # restore_best_weights --> default 는 False 이므로 True 로 꼭!!! 변경!!!  
# 검증 손실(val_loss)을 모니터링 중이고, 이 손실이 감소해야 하는 경우 mode='min'으로 설정
# 만약 모니터링 중인 지표가 정확도(accuracy)라면, 이 지표가 최대화되어야 하므로 mode='max'로 설정

start_time = time.time()    # 시작 시간

model.fit(x_train, y_train, epochs=50, batch_size=256,
         validation_split=0.2, callbacks=[earlyStopping, mcp])

end_time = time.time() - start_time
# Epoch 00025: early stopping


# 4. 평가, 예측
loss, acc = model.evaluate(x_test, y_test)
print('loss : ', loss)
print('acc : ', acc)
# loss :  2.404205799102783
# acc :  0.36197686195373535