이미지를 학습하는 가장 기본적인 딥러닝 모델로는 CNN이 있다.
Flatten layer를 활용한 이미지 학습 모델을 실습해보자.
종속변수와 독립변수를 선언하고 독립변수와 종속변수의 shape를 화면에 출력해보자.
(독립,종속),_ = tf.keras.datasets.mnist.load_data()
print(독립.shape, 종속.shape)
결과 : (60000,28,28) (60000,)
이렇게 불러오면, 링크 형태로 불러오게 되는데 독립변수와 종속변수가 표 형태가 아니므로 두 개를 모두 표 형태로 만들어야한다.
따라서 독립변수를 reshape라는 도구를 이용해서 (60000,784)형태의 표로 만들고 종속변수를 원핫인코딩 해야한다.
이때 원핫인코딩은 판다스의 get_dummies 함수를 이용한다.
독립 = 독립.reshape(60000,784)
종속 = pd.get_dummies(종속)
print(독립.shape,종속.shape)
결과 : (60000,784) (60000,10)
그 결과 우리가 원하는 형태의 784개의 칼럼을 가진 독립변수와 10개의 칼럼을 가진 종속변수로 만들어진 것을 확인할 수 있다.
X = tf.keras.layers.Input(shape=[784])
이렇게 Input레이어의 shape를 784개로 지정하고 히든레이어를 하나 추가하자.
H = tf.keras.layers.Dense(84, activation='swish')(X)
84개짜리 히든 레이어를 추가하고 활성화 함수로는 'swish'를 지정했다.
Y = tf.keras.layers.Dense(10, activation='softmax')(H)
model = tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy', metrics='accuracy')
히든레이어에 10개의 분류를 만들어주고, 활성화함수는 softmax, 손실은 categorical_crossentropy, 메트릭은 accuracy로 지정해서 모델을 만들었다.
model.fit(독립, 종속, epochs=10)
독립변수와 종속변수를 넣고 에포크를 10번만 돌려도 학습이 어느정도 이루어진다. 그 결과 정확도가 95%에 가깝게 학습이 되었고, 이는 학습이 참 잘 된 것이라고 할 수 있다.
pred = model.predict(독립[0:5])
pd.DataFrame(pred).round(2)
독립변수의 앞의 다섯개의 데이터만을 들고와 예측결과를 출력해서 이미지를 확인해보았다. 보기 좋도록 데이터 프레임으로 출력을 하고 소수점 둘째자리에서 반올림을 하였다.
print(종속[0:5])
실제 정답을 출력해서 비교해봐도 예측이 잘 된 것을 확인할 수 있다.
이번에는 reshape를 사용하지 않고 flatten 레이어를 이용해 모델을 만들어보자.
#독립 = 독립.reshape(60000,784)
종속 = pd.get_dummies(종속)
print(독립.shape,종속.shape)
결과 : (60000,28,28) (60000,10)
입력 이미지의 데이터를 한줄로 펴주는 reshape작업을 하지 않을 것이므로 해당 행은 주석 처리해준다. 실행하면 데이터가 펴진 상태가 아니라 이미지 상태 그대로 준비된다.
X = tf.keras.layers.Input(shape=[28,28])
reshape를 하지 않았기 때문에 shape는 784가 아니라 (28,28)을 따르게 된다.
H = tf.keras.layers.Flatten()(X)
H = tf.keras.layers.Dense(84, activation='swish')(H)
(28,28)에서 바로 84로 넘어가면 안되고, 한줄로 펴줘야한다. 따라서 Flatten레이어를 만들면 데이터가 한줄로 펴지게 된다.
Y = tf.keras.layers.Dense(10,activations='softmax')(H)
model=tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy',metrics='accuracy')
그리고 Flatten레이어인 H를 다음 레이어의입력으로 넣으면 모델이 완성된다.
model.fit(독립, 종속, epochs=5)
독립변수와 종속변수를 넣고, 다섯번만 학습을 해보자.
pred = model.predict(독립[0:5])
print(pd.DataFrame(pred).round(2))
print(종속[0:5])
독립변수의 앞의 다섯개의 데이터만을 들고와 예측결과를 출력해서 이미지를 확인해보았다. 보기 좋도록 데이터 프레임으로 출력을 하고 소수점 둘째자리에서 반올림을 하였다.
이미지 데이터를 표 형태의 데이터로 바꿔서 표를 학습하는 모델에 넣고 학습을 시켰다.
'특징 자동 추출기'는 픽셀을 한 줄로 펴고 그 픽셀들을 가지고 새로운 특징 84개를 컴퓨터가 스스로 찾았고, 이렇게 찾은 특징으로 다시 10개의 숫자 이미지를 분류했다. 따라서, 84개의 특징은 10개의 분류를 만들기 위해 제일 좋은 특징 84개를 찾았다고 해석할 수 있다.
히든 레이어가 없는 모델은 첫번째 결과가 0인지 아닌지를 판단하는 수식에서 입력층 노드의 모든 입력에 가중치를 붙여서 판단하게 된다. 이는 모든 픽셀값에 대해 가중치를 학습하게 되는 것이다.
학습이 끝났을 때 가중치가 높게 부여된 픽셀은 0이라고 판단하는 데 중요한 픽셀이고 가중치가 0에 가까운 픽셀은 0이라고 판단하는 데 불필요한 픽셀임을 해석할 수 있다.
84개의 노드를 가진 히든 레이어를 추가하여 모델을 만들면, 중간 결과로 칼럼 84개를 가진 표가 만들어진다. 히든 레이어가 있을 때는 첫번째 결과가 0인지 아닌지를 판단하는 수식에서 히든 레이어의 모든 노드가 입력으로 사용되고, 모든 입력의 가중치를 붙여서 판단하게 된다. 이 84개의 중간 결과는 인공신경망 구조 안에서 가중치 학습을 통해 컴퓨터 스스로 만들어낸 값이다.
각 칼럼의 특징 84개는 컴퓨터가 인공신경망 구조 안에서 학습을 통해 스스로 찾은 것이다. 노드가 84개 있는 은닉층을 추가한 행동은 "컴퓨터야, 0에서 9까지 숫자 중에서 어떤 숫자인지 분류하는 데 가장 좋은 특징 84개를 찾아줘"라고 명령하는 것이다.
즉, 최종 결과를 더 잘 만들어낼 수 있는 특징 84개를 인경 신경망이 찾는 것이고, 이를 특징 자동 추출기라고 부른다.