[개발일지 2022.4.15] Scikit-Learn의 활용(3)

1.학습한 내용

1) 인공신경망

keras 를 통해서 인공 신경망을 만든다.

이를 위해서 필요한 라이브러리를 불러온다.

from keras import models

from keras import layers


network = models.Sequential()

network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10,activation='softmax'))

위에서 불러온 라이브러리를 통해서 만들어진 network를 통하여 신경망을 만든다.

network.compile(optimizer='rmsprop',
               loss='categorical_crossentropy',
               metrics=['accuracy'])

이때 compile 코드가 신경망을 만드는 코드이다.

이때 이 신경망을 확인하기 위해서 데이터의 차원을 조절한다.

train_images = train_images.reshape(60000,28*28)
train_images = train_images.astype('float32') /255

test_images = test_images.reshape(10000,28*28)
test_images = test_images.astype('float32')/255

이때 (x0000,28,28) 이던 데이터를 (x0000,28*28) 의 2차원 데이터로 바꾸고, unit8 타입이던 데이터의 타입을 float32 타입으로 변경을 한다.

이미지의 데이터는 변경하였지만, labels 의 경우 1차원데이터를 카테고리컬로 바꾸기 위해서 필요한 라이브러리를 불러온다.

from tensorflow.keras.utils import to_categorical

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

그 후 데이터를 위에서 만들어낸 신경망에 적용한다.

network.fit(train_images, train_labels, epochs=5, batch_size=128)


이렇게 5번 반복해서 나온 값을 통해서 정확도를 측정한다.

test_loss,test_acc= network.evaluate(test_images,test_labels)

print('test_acc:',test_acc)


이를 통해서 테스트 데이터의 정확도가 97.9퍼가 되는 신경망을 만든것을 확인할수 있다.

2)영화 리뷰 분류

이진 분류 예제

• IMDB 데이터셋

• 인터넷 영화 데이터베이스로
가져온 양극단의 리뷰 50000개

• Training data 25000개와 Test
data 25000개로 나눠져 있음.

• MNIST처럼 Keras에 기본으로
포함되어 있음

• 데이터는 전처리 되어 있어서
포함되어 있는 단어들이 모두
숫자로 변환되어 있음.

• 데이터의 준비

• 신경망에 숫자 리스트를 바로 주입할 수 없음(텐서로 변환해야 함.)
• 원 핫 인코딩을 사용해서 10,000 차원의 벡터로 변환해서 사용

영화 리뷰 데이터를 분류하기 위해서
라이브러리들을 불러온다.

import keras

from keras.datasets import imdb

(train_data, train_label),(test_data,test_label) = imdb.load_data(num_words=10000)


이때 num_words 의 갯수를 설정하지 않으면 무수히 많은 데이터들을 모두 가져오게 된다.

이렇게 불러온 데이터중 결과값인 label 의 값을 확인해본다.

train_label[0]

train_label[1]


이때 0(1번째)번의 데이터의 라벨값은 1, 1(2번째)번의 데이터의 라벨값은 0인것을 확인할수 있다.
이때 0와 1이 의미하는것은 긍정적인 내용인가, 부정적인 내용인가의 차이가 있는데, 아직은 어느쪽이 긍정적이고 부정적인지를 알수가 없다.
이를 확인 하기 위해서 데이터의 내용을 읽어온다.

# word_index는 단어와 정수 인덱스를 매핑한 딕셔너리입니다
word_index = imdb.get_word_index()
# 정수 인덱스와 단어를 매핑하도록 뒤집습니다
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
# 리뷰를 디코딩합니다. 
# 0, 1, 2는 '패딩', '문서 시작', '사전에 없음'을 위한 인덱스이므로 3을 뺍니다
decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])

decoded_review


이때 0번째 데이터의 내용을 출력하는데. 이 내용이 긍정적인 내용인것으로 라벨값중 1은 긍정적인 내용, 그리고 반대인 0은 부정적인 내용을 가진다는것을 확인할수있다.

이제 이 데이터를 이용해서 신경망을 이용해서 분류하기 위해서 신경망을 만들기 위한 기본적인 라이브러리를 불러온다.

import numpy as np

그리고 이 신경망에 적용하기 위해서 함수를 만든다.

def vectorize_sequences(sequences,dimension=10000):
    results = np.zeros((len(sequences),dimension))
        
    for i,sequence in enumerate(sequences):
        results[i,sequence] = 1.
    return results

이때의 함수의 뜻은 입력한 값의 행과 디멘션(10000)의 열의 크기를 가진 행렬에 모두 0을 넣어서 만들고, (입력한순번,sequences)번째의 값에 1을 입력하는 함수이다.

이를 통해서 입력할 데이터를 만들어낸다.

x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

y_train = np.asarray(train_label).astype('float32')
y_test = np.asarray(test_label).astype('float32')

이제 이 값을 사용할 신경망을 만들기 위해서 필요한 라이브러리 들을 불러온다.

from keras import models
from keras import layers

model = models.Sequential()
model.add(layers.Dense(16,activation='relu',input_shape=(10000,))) 
model.add(layers.Dense(16,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))

이때 만드려는 신경망은 1번째 레이어에는 16개가 나오고, 2번째 레이어에도 16개, 3번째 레이어에는 1개가 나오는 3개의 레이어를 만들려고 한다.
따라서 model.add() 를 통해서 3개를 만든다.

이때 input_shape 는 첫번째 레이어 에만 쓰여져있는데 이는 들어올때만 지정하면 나머지는 알아서 하기때문이다.

이를 통하여서 compile 을 하여 신경망을 만든다.

model.compile(optimizer='rmsprop',
             loss='binary_crossentropy',
             metrics='accuracy')

이제 입력하기 위한 데이터를 분류를 한다.

x_val = x_train[:10000]
partial_x_train = x_train[10000:]

y_val = y_train[:10000]
partial_y_train = y_train[10000:]

이때 1만번째까지의 값을 테스트용 데이터, 그외의 나머지(1만~2만5천)까지의 데이터를 학습용 데이터로 만든다.

이러한 데이터를 신경망에 적용시킨다.

model.fit(partial_x_train, 
          partial_y_train,
          epochs=20,
          batch_size=512)

이때 횟수는 20회를 한다.

이 결과를 보면 정확도가 횟수를 진행할때마다 점점 올라가는것을 볼수있다, 이것은 loss 의 값에 따라 가중치에 옵티마이저를 통해서 피드백을 받아서 정확도가 올라가는것을 볼수있다.
또한 도중에 15->16번째를 확인해보면 정확도가 오히려 줄어든 것을 확인할수있는데, 무조건 횟수가 많아 진다고 정확도가 올라가는것은 아니라는것을 알수있다.

이후 검증 데이터를 추가하기 위해서 validation 을 추가한다.

history = model.fit(partial_x_train, 
          partial_y_train,
          epochs=20,
          batch_size=512,
          validation_data=(x_val,y_val))

이를 통해서 val_값이 추가가 된다.

이제 이 값들을 시각화 하기위해서 plt 라이브러리를 불러온다.

import matplotlib.pyplot as plt

그리고 표시할 데이터들을 입력한다.

acc = history.history['binary_accuracy']
val_acc = history.history['val_binary_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1,len(acc)+1)

이제 이 데이터들로 그래프를 그리게되면

plt.plot(epochs,loss,'bo',label='Traing loss')
plt.plot(epochs,val_loss,'r-',label='Validation loss')
plt.title('Training and Validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()


시행횟수에 따른 loss 값이 줄어들고, 반대로 validation loss의 값은 늘어나는것을 볼수있다.
이로 인해서 적절한 횟수를 확인하는것이 중요하다는것을 알수있다.

또한 이를 통해서 정확도 또한 확인이 가능하다.

plt.plot(epochs, acc, 'bo', label='Training acc')

plt.plot(epochs, val_acc, 'r-', label='Validation acc')

plt.title('Training and validation accuracy')

plt.xlabel('Epochs')

plt.ylabel('Accuracy')

plt.legend()

이제 이러한 결과값들을 가지고 예측을 진행함으로써 영화리뷰를 분류를 하는것이 가능해졌다.

model.predict(x_test)


이렇게 나온 값이 1에 가까울수록 긍정적인 내용이고 0에 가까울수록 부정적인 내용이다.

3)CNN

CNN(Convolutional Neural Networks)

이미지를 인식하기 위해 패턴을 찾는데 특히 유용하다.
데이터에서 직접 학습하고 패턴을 사용해 이미지를 분류한다.

특징을 수동으로 추출할 필요가 없다.

자율주행자동차, 얼굴인식, 객체인식 등 computer vision 이 필요한 분야에서 많이 사용되고있다.

이를 위해서 필요한 라이브러리를 불러온다.

import keras

from keras import layers
from keras import models

그리고 이렇게 불러온 라이브러리를 통해서 신경망의 내부구조를 만든다.

model = models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation='relu', input_shape=(28,28,1)))
model.add(layers.MaxPool2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation='relu'))
model.add(layers.MaxPool2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation='relu'))

이때 layers.MaxPool2D, 맥스풀링은 노이즈나 흐릿한 부분같은 사소한 변화를 무시해주는 레이어이다. 해당 범위에서 가장 큰 범위를 고른다.


이를 통해서 내부구조를 확인하는 것이 가능하다.

이때 이것은 2차원의 데이터이기때문에 1차원인 데이터로 바꿔주기 위해서 Flattenn 을 사용한다.

model.add(layers.Flatten())
model.add(layers.Dense(64,activation='relu'))
model.add(layers.Dense(10,activation='softmax'))
model.summary()


이렇게 사이에 Flatten layer 가 추가된것을 볼수있다.

이제 이 신경망을 사용하기 위해서 데이터를 라이브러리에서 불러온다.

from keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

(train_images,train_labels),(test_images,test_labels) =mnist.load_data()

그리고 불러온 데이터를 학습용, 테스트용 데이터로 분류를 하고 labels 를 categorical 데이터로 변경한다.

train_images = train_images.reshape((60000,28,28,1))  
train_images = train_images.astype('float32') /255 

test_images = test_images.reshape((10000,28,28,1))
test_images = test_images.astype('float32') /255

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

그리고 이제 기존에 구성한 model 들로 신경망을 만든다.

from keras import metrics
model.compile(optimizer='rmsprop',
             loss ='categorical_crossentropy', 
             metrics = 'accuracy')

그리고 위에서 가져온 데이터를 신경망에 적용을 시켜본다.

model.fit(train_images,train_labels, epochs=5,batch_size=64)


5회를 실행하였는데, 실행할때마다 옵티마이저를 통해서 정확도가 올라간것을 확인할수있다.

이제 이를 통해서 신경망을 평가를 하게 되면

test_loss, test_acc = model.evaluate(test_images,test_labels)

test_acc

흑백 문자를 99.14% 정확도로 분석하는 신경망을 만들어냈다는것을 확인할수있다.

2.학습내용 중 어려웠던 점

신경망에 데이터를 적용하고, 그래프를 그리는 과정에서 강사님, 그리고 다른 학우분들과 결과가 다르게 나타나는것을 확인하여 당황하였다.

3.해결방법

이는 지금까지 다른 수업에서는 random_state 를 지정하여서 변수를 최소화하였지만, 이번 수업에서는 변수에 대한 조정을 특별히 하지 않아서 그런것이었으며, 도중에 복습을 위해서 남겨뒀던 신경망 적용 부분이 남아있어서 중복작동을 하였던것이었다는것을 확인하였다.
이때 중복되는 부분을 주석처리 하고 커널을 통해서 리셋후 재실행을 하는것으로 해결하였다.

4.학습소감

신경망에서 실행을 반복하는 과정에서 loss값이 다르게 나타나고 그에 따라서 실행하는 사람마다 가중치도 다르게 설정되어서 조금씩은 모두 다르게 나타난다는것을 확인하게 되면서, 이런것이 딥러닝에서 학습하는 데이터와 테스트 데이터의 정확도가 중요한 이유를 알게 해주었다.
또한 데이터를 많이 사용하여서 많이 실행하는것으로 정확도를 높이는것이 중요하다고만 생각했지만, 그래프등 시각적인 정보를 보는것으로 반복할수록 오히여 과적합되어서 적절한 시행횟수를 찾는것 또한 중요하다는것을 이해할수있었다.

좋은 웹페이지 즐겨찾기