6日目

58343 ワード

データの準備


MNISTデジタル手書きデータセットの読み込み
import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt
import os

print(tf.__version__)   # Tensorflow의 버전을 출력

mnist = keras.datasets.mnist

# MNIST 데이터를 로드. 다운로드하지 않았다면 다운로드까지 자동으로 진행됩니다. 
(x_train, y_train), (x_test, y_test) = mnist.load_data()   

print(len(x_train))  # x_train 배열의 크기를 출력

# 손글자 이미지 출력하기
# MNIST 데이터셋의 X항목(위 코드에서는 x_train, x_test)은 이미지데이터를 담은 행렬(matrix)
plt.imshow(x_train[1],cmap=plt.cm.binary) # 1은 첫번째가 아니라 2번째, 0이 첫번쨰
plt.show()
学習データと試験データ
# mnist.load( ) 함수를 통해 (x_train, y_train)와 (x_test, y_test)를 나누어서 받아들이기
(x_train, y_train), (x_test, y_test) = mnist.load_data()
학습용 데이터만을 가지고 학습시키고, 시험용 데이터로 테스트 할 수 있다

print(x_train.shape) # 학습용 데이터 확인
print(x_test.shape) # 테스트 데이터 확인
プリプロセッシングデータ
# 이미지의 실제 픽셀 값은 0~255 사이의 값을 가집니다
print('최소값:',np.min(x_train), ' 최대값:',np.max(x_train))
# 최소값: 0  최대값: 255

# 인공지능 모델을 훈련시키고 사용할때 정규화 시키기 
# MNIST 데이터는 각 픽셀의 값이 0~255 사이 범위에 있으므로 
x_train_norm, x_test_norm = x_train / 255.0, x_test / 255.0 # 데이터들은 255.0으로 나눔
print('최소값:',np.min(x_train_norm), ' 최대값:',np.max(x_train_norm))
# 최소값: 0.0  최대값: 1.0
# 일반적으로 입력은 0~1 사이의 값으로 정규화 시켜주는 것이 좋습니다

設計深さ学習ネットワーク


シーケンスモデルの使用
model=keras.models.Sequential()
model.add(keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(32, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))

print('Model에 추가된 Layer 개수: ', len(model.layers))

**딥러닝 네트워크 모델을 확인**
model.summary()

ラーニング深さラーニングネットワーク


我々が作成したネットワークの入力形式は,(データ量,画像サイズx,画像サイズy,チャネル数)と同じである.
前のステップで最初のレイヤにinput shape=(28,28,1)を指定したのを覚えていますか?
しかしながらprint(x train.shape)を試みると、(60000,28,28)チャンネル数に関する情報はない.
したがって(60000,28,28,1).チャンネル数1は白黒画像を表す.カラー画像であればR,G,Bの3つの値のため3であるべきである.
# 네트워크 입력형태 알아보기
print("Before Reshape - x_train_norm shape: {}".format(x_train_norm.shape))
print("Before Reshape - x_test_norm shape: {}".format(x_test_norm.shape))

x_train_reshaped=x_train_norm.reshape( -1, 28, 28, 1)  # 데이터갯수에 -1을 쓰면 reshape시 자동계산됩니다.
x_test_reshaped=x_test_norm.reshape( -1, 28, 28, 1)
                # (데이터갯수, 이미지 크기 x, 이미지 크기 y, 채널수)

print("After Reshape - x_train_reshaped shape: {}".format(x_train_reshaped.shape))
print("After Reshape - x_test_reshaped shape: {}".format(x_test_reshaped.shape))

# x_train 학습 데이터로 딥러닝 네트워크를 학습
model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])

model.fit(x_train_reshaped, y_train, epochs=10) 
# model의 입력 정의에 형태를 맞춘 x_train_reshaped가 사용
# epochs=10 은 전체 60,000개의 데이터를 10번 반복 사용해서 학습을 시키라는 뜻

どれほどよくできているかを確かめる

# 테스트 데이터로 성능을 확인해 보자
test_loss, test_accuracy = model.evaluate(x_test_reshaped,y_test, verbose=2)
print("test_loss: {} ".format(test_loss))
print("test_accuracy: {}".format(test_accuracy))

#model.evaluate() 대신 model.predict()를 사용하면 
#model이 입력값을 보고 실제로 추론한 확률분포를 출력
# 어떤 데이터를 잘못 추론했을까? 눈으로 확인해 보자
predicted_result = model.predict(x_test_reshaped)  # model이 추론한 확률값. 
predicted_labels = np.argmax(predicted_result, axis=1)

idx=0  #1번째 x_test를 살펴보자. 
print('model.predict() 결과 : ', predicted_result[idx])
print('model이 추론한 가장 가능성이 높은 결과 : ', predicted_labels[idx])
print('실제 데이터의 라벨 : ', y_test[idx])
# model.predict() 결과 :  [4.4240073e-10 4.4173629e-10 2.0993063e-09 1.7357339e-10 6.0176732e-11
#   9.8950177e-13 1.2083153e-17 1.0000000e+00 8.8245072e-10 1.0810760e-08]
# model이 추론한 가장 가능성이 높은 결과 :  7
# 실제 데이터의 라벨 :  7

# model이 추론한 결과가 7일 확률이 1.00에 근접하고 있다, 
# 즉 이 model은 입력한 이미지가 숫자 7이라는 걸 아주 확신하고 있다는 뜻

plt.imshow(x_test[idx],cmap=plt.cm.binary) # 7이 맞는지 확인
plt.show() 

# model이 추론해 낸 숫자와 실제 라벨의 값이 다른 경우도 직접 확인해 볼 수도 있겠습니다
import random
wrong_predict_list=[]
for i, _ in enumerate(predicted_labels):
    # i번째 test_labels과 y_test이 다른 경우만 모아 봅시다. 
    if predicted_labels[i] != y_test[i]:
        wrong_predict_list.append(i)

# wrong_predict_list 에서 랜덤하게 5개만 뽑아봅시다.
samples = random.choices(population=wrong_predict_list, k=5)

for n in samples:
    print("예측확률분포: " + str(predicted_result[n]))
    print("라벨: " + str(y_test[n]) + ", 예측결과: " + str(predicted_labels[n]))
    plt.imshow(x_test[n], cmap=plt.cm.binary)
    plt.show()

より良いネットワークの作成


深度ラーニングネットワーク設計で表示されるスーパーパラメータの変更
# 바꿔 볼 수 있는 하이퍼파라미터들
n_channel_1=16
n_channel_2=32
n_dense=32
n_train_epoch=10

model=keras.models.Sequential() # 네트워크 설계
model.add(keras.layers.Conv2D(n_channel_1, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(n_channel_2, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(n_dense, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))

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

# 모델 훈련
model.fit(x_train_reshaped, y_train, epochs=n_train_epoch)

# 모델 시험
test_loss, test_accuracy = model.evaluate(x_test_reshaped, y_test, verbose=2)
print("test_loss: {} ".format(test_loss))
print("test_accuracy: {}".format(test_accuracy))

ミニアイテム:石ハサミ布分類器を作る


≪データの作成|Create Data|oraolap≫:ハサミ・ストーン・クロス・フォルダを作成し、ハサミ・ストーン・クロスを別々に撮影してデータを入れます.
データの読み込み+Resize
# 사이즈 변경하기
def resize_images(img_path):
	images=glob.glob(img_path + "/*.jpg")  
    
	print(len(images), " images to be resized.")

    # 파일마다 모두 28x28 사이즈로 바꾸어 저장합니다.
	target_size=(28,28)
	for img in images:
		old_img=Image.open(img)
		new_img=old_img.resize(target_size,Image.ANTIALIAS)
		new_img.save(img, "JPEG")
    
	print(len(images), " images resized.")
	
# 가위 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/scissor"
resize_images(image_dir_path)

print("가위 이미지 resize 완료!")

# 가위, 바위, 보 데이터를 읽을 수 있는 load_data() 함수를 만들어야 한다
import numpy as np

def load_data(img_path, number_of_data=300):  # 가위바위보 이미지 개수 총합에 주의하세요.
    # 가위 : 0, 바위 : 1, 보 : 2
    img_size=28
    color=3
    #이미지 데이터와 라벨(가위 : 0, 바위 : 1, 보 : 2) 데이터를 담을 행렬(matrix) 영역을 생성합니다.
    imgs=np.zeros(number_of_data*img_size*img_size*color,dtype=np.int32).reshape(number_of_data,img_size,img_size,color)
    labels=np.zeros(number_of_data,dtype=np.int32)

    idx=0
    for file in glob.iglob(img_path+'/scissor/*.jpg'):
        img = np.array(Image.open(file),dtype=np.int32)
        imgs[idx,:,:,:]=img    # 데이터 영역에 이미지 행렬을 복사
        labels[idx]=0   # 가위 : 0
        idx=idx+1

    for file in glob.iglob(img_path+'/rock/*.jpg'):
        img = np.array(Image.open(file),dtype=np.int32)
        imgs[idx,:,:,:]=img    # 데이터 영역에 이미지 행렬을 복사
        labels[idx]=1   # 바위 : 1
        idx=idx+1  
    
    for file in glob.iglob(img_path+'/paper/*.jpg'):
        img = np.array(Image.open(file),dtype=np.int32)
        imgs[idx,:,:,:]=img    # 데이터 영역에 이미지 행렬을 복사
        labels[idx]=2   # 보 : 2
        idx=idx+1
        
    print("학습데이터(x_train)의 이미지 개수는", idx,"입니다.")
    return imgs, labels

image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper"
(x_train, y_train)=load_data(image_dir_path)
x_train_norm = x_train/255.0   # 입력은 0~1 사이의 값으로 정규화

print("x_train shape: {}".format(x_train.shape))
print("y_train shape: {}".format(y_train.shape))

# 이미지 불러와서 확인하자
plt.imshow(x_train[0])
print('라벨: ', y_train[0])

# 딥러닝 네트워크 설계하기
n_channel_1=16
n_channel_2=32
n_dense=32
n_train_epoch=10

# model을 직접 만들어 보세요.
# Hint! model의 입력/출력부에 특히 유의해 주세요. 가위바위보 데이터셋은 MNIST 데이터셋과 어떤 점이 달라졌나요?
model=keras.models.Sequential()
model.add(keras.layers.Conv2D(n_channel_1, (3,3), activation='relu', input_shape=(28,28,3)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(n_channel_2, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(n_dense, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
print('Model에 추가된 Layer 개수: ', len(model.layers))

model.summary()

# 딥러닝 네트워크 학습시키기

print("Before Reshape - x_train_norm shape: {}".format(x_train_norm.shape))
x_train_reshaped=x_train_norm.reshape( -1, 28, 28, 3)  # 데이터갯수에 -1을 쓰면 reshape시 자동계산됩니다.
print("After Reshape - x_train_reshaped shape: {}".format(x_train_reshaped.shape))

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

model.fit(x_train_reshaped, y_train, epochs=n_train_epoch)

# 잘만들었는지 테스트하기

# 테스트 가위바위보 이미지 크기 맞추기
image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/test/scissor"
resize_images(image_dir_path)
print("가위 이미지 resize 완료!")

image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/test/rock"
resize_images(image_dir_path)
print("바위 이미지 resize 완료!")

image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/test/paper"
resize_images(image_dir_path)
print("보 이미지 resize 완료!")

image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/test"
(x_test, y_test)=load_data(image_dir_path)
x_test_norm = x_test/255.0

print("x_test shape: {}".format(x_test.shape))
print("y_test shape: {}".format(y_test.shape))

print("Before Reshape - x_test_norm shape: {}".format(x_test_norm.shape))
x_test_reshaped=x_test_norm.reshape( -1, 28, 28, 3)
print("After Reshape - x_test_reshaped shape: {}".format(x_test_reshaped.shape))

# 테스트 시키기
model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])

model.fit(x_test_reshaped, y_test, epochs=10)

# model을 학습시키는 코드를 직접 작성해 보세요.
# Hint! model.evaluate()을 사용해 봅시다.

test_loss, test_accuracy = model.evaluate(x_test_reshaped,y_test, verbose=2)
print("test_loss: {} ".format(test_loss))
print("test_accuracy: {}".format(test_accuracy))
import os
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
import numpy as np