인공지능/이론 정리

밑바닥부터 시작하는 딥러닝 : MNIST 데이터 Google Colab 에서 로드하기

고등어찌짐 2022. 1. 9. 23:35

MNIST 데이터를 Google Colab 으로 로드하는 방법 ?

 밑바닥부터 시작하는 딥러닝 교재의 3장에서 MNIST 데이터를 사용해 손글씨를 인식하는 실습이 있다.  책은 로컬 컴퓨터에서 실습 폴더를 가져와 사용하는 방법을 설명하고 있으므로,  코랩에서 그대로 코드를 실행하려고 하면 에러가 나며 실행이 불가하다. 그래서 코랩에서 이를 실행하려면 다른 방법을 사용해야한다. 


첫번째 방법. 넘파이 reshape 활용

어차피 책에서 인터넷의 mnist 데이터를 똑같이 끌어다 사용하는 것이므로 다른 곳에서 제공하는 데이터셋을 다운한다.

케라스 라이브러리를 활용하면 쉽게 다운받을 수 있다. 

from keras.datasets import mnist​
(train_X, train_y), (test_X, test_y) = mnist.load_data()

 

현재 train_X 의 shape 은 (60000, 28, 28) 이고, test_X 의 shape 은 (10000, 28, 28) 이다. 

하지만 책의 shape은 각각 (60000, 784), (10000, 784) 로 다르다. 

책에서는 미리 제공하는 파일의 코드로 2차원의 이미지를 1차원 데이터로 축약해 제공했기 때문이다.  ( flatten ) 
따라서 책의 shape 과 같은 shape 을 만들어주기 위해 numpy reshape 을 활용한다. 

※ 여기서 직접 flatten 을 사용하면 안된다. flatten 을 사용하면 3차원을 다 flat 하게 만들어 한번에 1차원으로 만들어버린다.

# 책과 같은 차원으로 reshape
import numpy as np
train_X = train_X.reshape(60000, 784)
test_X = test_X.reshape(10000, 784)

train_X 의 개수가 60000개, 2차원 28x28 의 이미지였으므로 책과 같은 형태인 60000개, 1차원 748 (28x28) 의 이미지로 reshape 하면 된다. test_X 데이터도 마찬가지이다. 

label 데이터들은 라벨 정보 하나만 가져 같은 차원이기에 reshape 할 필요가 없다. 

 

데이터가 똑같이 잘 들어있는지 확인해보고싶은데.... 책처럼 Pillow 를 활용할 수 없다. 

colab 환경에서는 PIL 로 이미지를 출력할 수 없다. IPython 환경에서는 불가능하므로 다른 방법이 필요하다. 

from matplotlib.pyplot import imshow
imshow(train_X[0].reshape(28, 28))

matplotlib 의 imshow 를 사용하면 된다. 1차원으로 줄어든 6만개의 이미지 중 첫번째 이미지를 꺼내서, 

다시 28 x 28 로 reshape 하고 imshow 를 통해 그려주었다. 

잘 출력되는 걸 볼 수 있다. 

 

 

+++ ) 책의 chapter 4 로 넘어가게 되면, label 데이터들로 원핫 인코딩의 형태로 변형해주어야 한다. 

 

train_y 의 현재 형태는 (60000, ) 이지만 원핫 인코딩한다면 (60000, 10) 의 모습이 된다. 

test_y 도 개수만 10000개로 다를 뿐, 모두 마찬가지이다.  

# index 로 이루어진 label 을 one hot encoding 변환
train_shape = (train_y.size, train_y.max()+1) # (60000, 10)
test_shape = (test_y.size, test_y.max()+1) # (10000, 10)

 

원 핫 인코딩한 결과를 저장할 새로운 zero array 들을 위에서 계산한 shape 대로 생성한다. 

# one hot encoding 할 zero arr 들을 생성
train_onehot = np.zeros(train_shape)
test_onehot = np.zeros(test_shape)

 

원 핫 인코딩을 할 때, (60000, 10) 의 데이터에서 (0, 10) 즉 0번 열부터, (1,10) 1번 열 ... (60000, 10) 60000번째 열까지 차례대로
원 핫 인코딩 해 나갈 것이다. 그렇기 때문에 차례대로 계산해야할 각 열의 넘버를 생성한다. 

# 아래 rows 에 생성된 순서대로 원핫인코딩 해나갈 것임
train_rows = np.arange(train_y.size)
test_rows = np.arange(test_y.size)

 

위에서 만든 zero array 에, train_rows 의 열 순서대로 ( 즉 0번 열부터 차례대로 계산하게 된다. ) 원핫 인코딩 해나간다. 
train_onehot 배열의 train_rows 원소 번째 열에서 train_y 원소 값에 해당하는 값에 1을 삽입한다는 의미이다.  

# train_rows 의 원소 수에 해당하는 행에서, train_y 인덱스 값과 일치하는 컬럼에 1을 표기해 차례대로 원핫 인코딩 해나간다
train_onehot[train_rows, train_y] = 1
test_onehot[test_rows, test_y] = 1

 

그러면 인덱스로 이루어진 데이터를 원핫 인코딩의 형식으로 변환할 수 있다. 

 

 


두번째 방법. mnist.py 파일 임포트 

두 번째 방법은 책에서 제공한 mnist.py 파일을 colab 의 파일 창에 넣어서, 같은 경로 내에서 실행되도록 하는 것이다. 

아래 링크에서 실습에 필요한 코드들을 Code > Download Zip 을 통해 다운받을 수 있다. 

https://github.com/youbeebee/deeplearning_from_scratch

 

GitHub - youbeebee/deeplearning_from_scratch: 밑바닥부터 시작하는 딥러닝 정리

밑바닥부터 시작하는 딥러닝 정리. Contribute to youbeebee/deeplearning_from_scratch development by creating an account on GitHub.

github.com

 

다운받은 폴더의 dataset > mnist.py 파일만 필요한 곳에 옮겨주면 된다. 

코랩을 실행하면, 옆 창에 다음과 같은 파일 창을 열 수 있다. 

현재 코랩 파일이 실행되고 있는 위치이므로, 여기에 mnist.py 파일을 드롭해서 업로드하면 된다. 

그럼 이제 책처럼 mnist 파일의 load_data 함수를 임포트해서 사용할 수 있다. 

from mnist import load_mnist
(x_train, y_train), (x_test, y_test) = load_mnist(flatten=True, normalize=False)

# 참조 

밑바닥부터 시작하는 딥러닝
How to Load and Plot the MNIST dataset in Python? 
https://www.askpython.com/python/examples/load-and-plot-mnist-dataset-in-python

How to do one-hot encoding with numpy in Python

https://www.kite.com/python/answers/how-to-do-one-hot-encoding-with-numpy-in-python
How to flatten only some dimensions of a numpy array 

https://stackoverflow.com/questions/18757742/how-to-flatten-only-some-dimensions-of-a-numpy-array
Colab, Jupyter notebook에서 PIL 명령어 show로는 이미지가 안열리는 현상 해결 
https://lapina.tistory.com/81