[tensorflow](4) 이미지 학습

이런거 해보자

뉴럴네트워크에 이미지를 집어넣어서

손글씨를 구별하는 AI

사물을 인식하는 AI

사진을 어떤 식으로 뉴럴 네트워크에 집어 넣을까?

뉴럴 네트워크에 집어넣을 수 있는 건 무조건 숫자임
근데 이미지의 픽셀 데이터는 숫자로 표현 가능함
픽셀이 몇백만개 모여서 이미지가 되는 것

그래서 어떻게 할건데

1)이미지를 크게 확대해
2)픽셀의 rgb 데이터를 하나의 node, 하나의 input 으로 만들자

칼라사진 : rgb 60, 140, 88
흑백사진 : 0-255 하나의 숫자

여기서는 트레이닝이 쉽게 흑백사진으로 변환해서 해볼것임

플로우
1) 인풋을 넣자
2) 가중치 값들 찾아서 다음 노드로 연산시키기
3) 얘가 강아지일 확률을 예측
4) 예측값과 실제값을 비교해서 총손실값을 계산해보자

tf.keras.datasets.fashion_mnist.load_data()

텐서플로우에서 제공하는 이미지 데이터셋
튜플 형태라서 아래와 같이 받음

(trainX, trainY),(testX, testY) = tf.keras.datasets.fashion_mnist.load_data()

print(trainX[0])

이미지 한개가 하나의 행렬 데이터로 저장되어 있음

print(trainX.shape)


28*28 행렬 데이터가 60000개 있어요
60000개 이미지가 있어요

trainY는 정답을 담고 있음

print(trainY)


10개 카테고리 중 하나에 속하기 때문에 0-9의 값을 담고 있음

이미지 살펴보기

import matplotlib.pyplot as plt

plt.imshow(trainX[0])
plt.gray()
plt.colorbar()
plt.show()

튜플이란?

튜플(tuple)은 몇 가지 점을 제외하곤 리스트와 거의 비슷하며 리스트와 다른 점은 다음과 같다.
리스트는 [ ]으로 둘러싸지만 튜플은 ( )으로 둘러싼다.
리스트는 그 값의 생성, 삭제, 수정이 가능하지만 튜플은 그 값을 바꿀 수 없다.
-점프 투 파이썬

학습 플로우
1. 모델만들고 2. compile 하고 3. fit 하기

모델을 만들자 tf.keras.Sequential([])

원하는 예측 결과는 Tshirt/Trouser/Pullover/Dress ... 일 확률을 계산하는 것
1. 10개의 확률을 계산해주세요 하는 의미로 마지막 레이어의 Dense를 10으로 설정 ex) 출력 예시 [0.2 0.4 0.1 0.1 ...]
2. relu : 음수는 다 0으로 만들어주세요, 확률이니까 음수일수없으므로
3. softmax : 확률이므로 결과를 0-1로 압축
sigmoid도 0-1이지만 binary 예측 문제에 사용함(붙는다/안붙는다 개/고양이 이거다/아니다) -> 마지막 노드개수는 1개
softmax는 카테고리 예측 문제에 사용함 -> 마지막 노드 개수 = 카테고리 개수

model = tf.keras.Sequential([
      tf.keras.layers.Dense(128, activation="relu"),
      tf.keras.layers.Dense(64, activation="relu"),
      tf.keras.layers.Dense(10, activation="softmax"),               
])

compile하자 model.compile(loss="", optimizer="", metrics=[''])

카테고리 예측 문제에서 쓰는 손실함수는 총 두가지
1. sparse_categorical_crossentropy : trainY가 정수로 되어 있을 때
2. categorical_crossentropy : trainY 가 원핫인코딩 되어 있을 때

model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=['accuracy'])

fit하자 model.fit()

model.fit(trainX, trainY, epochs=5)

모델을 잘짰는지 보여줘 model.summary()

내가 디자인한 딥러닝 모델과 레이어들을 보고 싶을때, compile 전에 사용함
Dense에 input_shape=()을 줘야 summary를 볼 수 있음


안주면 에러남

input_shape=(,)은 내가 집어넣을 하나의 노드의 모양!
아까 28*28 행렬임을 확인했으므로 아래와 같이 지정

model = tf.keras.Sequential([
      tf.keras.layers.Dense(128, input_shape=(28,28), activation="relu"),
      tf.keras.layers.Dense(64, activation="relu"),
      tf.keras.layers.Dense(10, activation="softmax"),               
])

model.summary()

Output Shape : 이런 shape의 노드들이 남아요
ex) (None, 28, 128) 128개의 데이터가 28개나 있고 아직 정확히 모르지만 많은것같음

행렬 1차원으로 만들때 tf.keras.layers.Flatten()

근데 마지막 Output이 (None, 28, 10)으로 2D임 -> 우리는 10개의 데이터만 원함!

model = tf.keras.Sequential([
      tf.keras.layers.Dense(128, input_shape=(28,28), activation="relu"),
      tf.keras.layers.Dense(64, activation="relu"),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(10, activation="softmax"),               
])

model.summary()

최종적으로 우리가 원하는 output의 shape이 나옴


accuracy 가 좀 낮은데 어떻게 해야할까 ?

convolution layer 추가하기 tf.keras.layers.Conv2D()

첫번째 레이어를 convolution layer로 바꾸자


model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, (3,3), padding="same", activation="relu", input_shape=(28, 28, 1)),
      #tf.keras.layers.Dense(128, input_shape=(28,28), activation="relu"),
      tf.keras.layers.Dense(64, activation="relu"),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(10, activation="softmax"),               
])
  1. 32 : 32개의 이미지 복사본을 생성해주세요 (다른 kernel)
  2. (3,3) : kernel의 사이즈는 3*3 > 실험적으로 결과 잘 나올때까지 확인하고 조정
  3. padding="same" : 패딩을 넣어서 이미지 사이즈를 동일하게 / conv를 적용하면 이미지 사이즈가 작아질 수밖에 없기 때문

  1. activation="relu" : 이미지 데이터는 0-255 사이 / 음수를 내보내지 않으려고 relu 사용

  1. input_shape=(28, 28, 1) : 데이터 하나의 shape input_shape 값이 없다면 에러가 남
    conv2d는 4차원 데이터를 필요로함 ex) (60000, 28, 28, 1)

Input 0 of layer "conv2d" is incompatible with the layer: expected min_ndim=4, found ndim=3. Full shape received: (32, 28, 28)
number of dimension이 4여야 하는데 3입니다

인풋 데이터 shape 수정 trainX.reshape((,,,))

(28, 28, 1)의 형식

근데 현재 데이터는 이럼

import numpy as np

(trainX, trainY),(testX, testY) = tf.keras.datasets.fashion_mnist.load_data()

print(trainX.shape) ##(60000, 28, 28) 이 출력됨

trainX.reshape((trainX.shape[0], trainX.shape[1], trainX.shape[2], 1)) ##(60000,28,28,1)
testX.reshape((testX.shape[0], testX.shape[1], testX.shape[2], 1))

좋은 웹페이지 즐겨찾기