[TensorFlow] 숫자 인식 AI 제작 (2)

2021. 1. 30. 14:55Artificial_Intelligence/Computer Vision

colab.research.google.com/drive/1vcBfl192NDGJ2_c2u01tAa65NGSJmrw8?usp=sharing

 

Google Colaboratory

 

colab.research.google.com

원문입니다. 코랩으로 보는거 추천.

 

(이전글)

2021/01/28 - [Hi/AI] - [TensorFlow] 숫자 인식 AI 제작 (1)


<인공지능 모델 설계>

# 모델설계

 

4개의 층으로 만들거임. 입력층, 은닉층, 은닉층, 출력층

 

입력층 뉴런의 수는 28 * 28이니 784임. 28 * 28개의 픽셀로 이루어진 숫자를 한줄로 바꾼거임.

 

첫번째 은닉층의 노드 수는 512개, 두번째 은닉층의 노드 수는 256개, 세번째 결과층의 노드수는 10개로 설정함.

(마지막은 0~9이니 10개)

 

활성화 함수는 렐루(ReLU)함수 사용하고, 마지막은 소프트맥스(softmax)함수를 사용할거임.

(ReLU - 0보다 작은값이 입력되면 0을 반환, 0보다 큰 값이 입력되면 그 값을 그대로 반환.

softmax - 0~1 사이의 값으로 모두 정규화 시킴. 모든 출력값의 합이 1이 되게 만드는 활성화 함수임.

분류문제에서 어떤 범주를 가장 높은 확률로 예측하는지에 대해 주로 사용됌.)

 

케라스는 시퀀셜 모델을 통해 쉽게 개발할 수록 도와줌.

model = Sequential()  #모델은 시퀀셜 방식
model.add(Dense(512, input_shape = (784, ))) #첫번째 인자는 해당 은닉층의 노드 수, 두번째 인자는 입력하는 데이터의 형태.
model.add(Activation('relu'))
model.add(Dense(256)) #두번째부터는 입력받는 노드 설정 안해도됌. 케라스를 사용하는 이유임.
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('softmax'))

model.summary() # 모델 확인

Layer 은 레이어를 표시해주는 거고,

Output Shape는 레이어의 모습을 나타내주는 거고,

Param은 각 노드와 편향을 연결하는 가중치의 수를 나타내는 것임.

 

첫번째 레이어는 512개의 노드로 이루어짐.

784개의 입력층 에서 512개의 은닉층으로 각각 연결되어 있기에 가중치는 784 * 512 이고, 은닉층의 각 노드 수만큼 편향이 있기에 편향은 512임.

 

따라서 784 * 512 + 512 이므로 401920개의 파라미터로 이루어져 있음.

다음 레이어도 마찬가지로 512 * 256 + 256 = 131328

마지막 레이어도 256 * 10 + 10 이므로 2570 이 나옴.


# 모델 학습

 

이제 모델을 설계했으니 모델을 실행해 보아야함.

심층 신경망에 데이터를 흘려보내 정답을 예측할수 있게 신경망을 학습하는 과정이 필요함. (딥러닝)

 

신경망이 예측한 결과와 실제 정답을 비교, 오차있으면 신경망을 다시 학습.

웬만하면 오차가 0이 나오는 일이 거의 없음. 그래서 보통 학습시키는 횟수를 정해줘서 그만큼만 학습시킴.

 

신경망을 잘 학습시키려면 신경망이 분류한 값과 실제 값의 오차부터 계산해야함.

오차줄이는 방법 - 경사 하강법.

model.compile(loss = 'categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_Train, Y_train, batch_size=128, epochs=10, verbose=1)

 

loss = 오차값

accuracy = 정확도

loss는 Epoch가 증가할 수록 줄어들고 accuracy는 증가하는 것을 확인할 수 있다.

 

compile 함수는 케라스에서 제공하는 함수로, 심층 신경망의 학습하는 방법을 정하는 명령어임.

 

1. 오차값을 계산하는 방법을 알려줘야함.

    10개중 하나로 분류하는 것이니 다중 분류 문제이다. 따라서 categorical_crossentropy 방법으로 설정해준다.

 

2. 오차를 줄이는 방법을 알려줘야함.

    오차를 줄이기 위해 optimizer의 adam 방법을 사용함. 

 

딥러닝을 통해 인공지능 모델 학습시킬때, 오차를 줄이기 위해 경사 하강법 알고리즘을 사용함. 이때 경사 하강법을 어떤 방식으로 사용할지 여러 알고리즘 있는데 이 알고리즘들을 케라스에서 모아 놓은 것이 옵티마이저 라이브러리임.

옵티마이저 종류에는 adam뿐만 아니라 확률적 경사 하강법(SGD) 등이 있음.

 

3. 학습 결과를 어떻게 확인할지 알려줘야함.

    정확도(Accuracy)는 실제 6만개 데이터의 예측 결과와 실제 값을 비교하고 정답 비율을 알려줌.

    

 

이제 심층 신경망의 학습하는 방법을 정했으니 fit이라는 케라스의 학습 명령어를 사용해 학습을 시킴.

 

1. 입력할 데이터를 정해야함.

    X_Train , Y_train 데이터를 사용해서 인공지능 모델을 학습하니 이 두개를 넣어줌.

 

2. 배치사이즈를 정해야함.

    Batch_Size 는 인공지능 모델이 한번에 학습하는 데이터 수 임.

    한번에 128개 데이터를 학습 시킨거임.

 

3. 에포크를 정해야함.

    Epochs는 모든 데이터를 한번 학습하는 것을 의미함.

    모든 데이터를 10번 반복 시킬려고 epochs =10, verbose =1 로 설정함

    verbose는 케라스 fit 함수의 결괏값을 출력하는 방법임.

    0, 1, 2 중 하나로 결정할 수 있음.

 

    - verbose = 0 : 아무런 표시 X

    - verbose = 1 : 에포크별 진행 사항 보여줌

    - verbose = 3 : 에포크별 학습 결과 보여줌.

 


# 모델 정확도 확인

모델을 설계하고, 학습을 했으면 다음은 성능을 확인해 보아야한다.

인공지능 모델이 얼마나 잘 학습하는지, 검증 데이터를 얼마나 잘 맞추는지 확인해봤다.

model.evaluate(X_Test, Y_test)

케라스의 evakuate 함수는 모델의 정확도를 평가하는 함수임.

첫번째 인자는 테스트할 데이터,

두번째 인자는 테스트할 데이터의 정답임.

loss(오차값)은 0 ~ 1 사이 값으로 0에 가까울 수록 오차가 적은것임.

accuracy(정확도) 또한 0~1 사이 값으로 1에 가까울 수록 정확한 거임.

 

 

#모델 학습 결과 확인

 

predicted_classes = np.argmax(model.predict(X_Test), axis=1)
correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]

predict 는 결과를 예측하는 함수임.

X_Test 의 데이터 개수가 만개였으니 예측값도 만개나옴.

 

numpy의 argmax 함수를 이용해서 여러 데이터 중 가장 큰 값의 위치를 반환함.

argmax를 쓸 때는, 열에서 가장 큰 값을 구할지, 행에서 가장 큰 값을 구할지 설정해야함.

이 때 기준을 정해주는 것이 axis 임. axis=0이면 열에서 가장 큰 수를 고르고, axis=1이면 행에서 가장 큰 수를 고름.

 

nonzero는 넘파이 배열에서 0이 아닌 값을 찾는 것임. 

 

plt.figure()
for i in range(9):
    plt.subplot(3,3,i+1)
    correct = correct_indices[i]
    plt.imshow(X_Test[correct].reshape(28,28), cmap='gray')
    plt.title("Predicted {}, Class {}".format(predicted_classes[correct], y_test[correct]))
plt.tight_layout()

matplotlib 라이브러리를 통해 그래프를 그림.

figure()은 그래프를 그리겠다는 명령임. 그래프를 그리려면 그릴 준비를 해야함. 그 준비하는 명령이 figure함수임.

 

subplot은 그림의 순서를 정해주는 함수임. 

첫번째 인자는 그림의 가로 개수,

두번째 인자는 그림의 새로 개수,

세번째 인자는 그림의 순서임.

 

imshow 함수는 어떤 이미지를 보여줄지에 대한 내용을 담고 있음.

현재 데이터는 1차원 배열로 되어있으니 reshape로 28 * 28 형태로 바꾸어줌. 

그림을 회색조로 나타내려고 cmap = 'gray' 로 설정함.

 

title 함수는 그림에 대한 설명을 넣는 함수임.

format함수를 사용해 {} 안에 값을 넣음.

 

화면에 그림을 보여주는 tight_layout을 사용함.

 

아래는 틀린 데이터 들을 출력하는 코드임.

plt.figure()
for i in range(9):
    plt.subplot(3,3,i+1)
    incorrect = incorrect_indices[i]
    plt.imshow(X_Test[incorrect].reshape(28,28), cmap='gray')
    plt.title("Predicted {}, Class {}".format(predicted_classes[incorrect], y_test[incorrect]))
plt.tight_layout()

인공지능의 성능이 좋아 보이지는 않음.

왜냐하면 모델 학습이 잘 되지 않아서임.

인공지능 모델 학습이 잘 이루어지기 위해선 모델의 학습 횟수를 늘려주어야함.

 

근데 모델의 학습 횟수만 무작정 늘린다고 인공지능 성능이 꾸준히 높아지는건 아님.

과적합(overfitting) 문제가 일어날 수 있기 때문.

 

여기서 오버피팅은 인공지능이 훈련 데이터에만 최적화되서 훈련 데이터만 잘 구분하고, 새로운 데이터인 검증 데이터를 인공지능 모델에 넣으면 구분하지 못하는 현상이 일어날 수 있음. 즉, 성능이 나빠지는 거임.

 

그래서 인공지능 모델을 학습시킬 때에는 무조건 많이가 아닌, 얼마만큼 학습 시켜야 제일 좋을지 결정할 수 있어야하고, 이게 인공지능 모델 설계에서 중요한 부분임.


첫번째 인공지능 제작 완료

728x90