인공지능/CNN

#2 (#1에서 했던) CNN 코드 Keras 사용해보기

쿠와와 2020. 12. 1. 19:25

각각의 주석이 #1에서 사용했던 것이고 그것을 keras를 이용해서 바꾼 코드입니다.

import tensorflow as tf
# compat 때문에 써줘야함 <- 낮은 버전 쓸것임
import numpy as np

# 21_01 파일을 keras로 바꿀 것임
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

x_train = x_train / 255
x_test = x_test / 255

# 4차원으로 변환
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)

# ------------------------------------------------ #
# filter 는 똑같이 4차원 즉 w = 4차원
# w1 = tf.Variable(tf.random.normal([3, 3, 1, 32]))       # 클래스 개념 존재 마지막 32
#
# # 바이어스
# b1 = tf.Variable(tf.zeros([32]))
# print(w1.shape)
#
# # 필터는 3, 3, 32 // 32의 이유 앞에서 3,3,1 짜리 필터를 32개 만들었으니 깊이는 32가 되는 것임
# w2 = tf.Variable(tf.random.normal([3, 3, 32, 64]))
# b2 = tf.Variable(tf.zeros([64]))
#
# # dense layer
# # 밑에 계산한 p2.shape 따라감
# w3 = tf.Variable(tf.random.normal([7 * 7 * 64, 128]))     # 뒤의 숫자는 자유임
# b3 = tf.Variable(tf.zeros([128]))
#
# w4 = tf.Variable(tf.random.normal([128, 10]))     # 뒤의 숫자는 자유임
# b4 = tf.Variable(tf.zeros([10]))
#
# ------------------------------------------------ #

# 인풋을 정해주는 것임 -> 중간중간의 shape 추적하기 위해
# ph_x = tf.placeholder(tf.float32, shape=[None, 28, 28, 1])  # x_train 형식
# ph_y = tf.placeholder(tf.int32)
#
# c1 = tf.nn.conv2d(ph_x,                  # 행렬 곱셈이라고 생각하면 편함
#                   filter=w1,
#                   strides=[1, 1, 1, 1],     # 가온데 2개만 사용하고 앞(배치 size) 뒤(채널)는 사용 안함, 한번에 얼만큼 움직이는지
#                   padding='SAME')           # 파라미터의 수를 줄여나가는 과정 = padding -> 차원의 크기 유지시켜줌
# #                                           # same : 필터의 사이즈가 k이면 사방으로 k/2 만큼의 패딩을 준다.
# r1 = tf.nn.relu(c1 + b1)                    # 코드가 선명해짐
#
# # 풀링    ( 입력, 커널[ ,커널의 크기 2*2,], strides, padding)
# p1 = tf.nn.max_pool2d(r1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
#
# # 앞쪽의 출력이 뒤쪽이랑 연결시킴
# c2 = tf.nn.conv2d(p1, filter=w2, strides=[1, 1, 1, 1], padding='SAME')
# r2 = tf.nn.relu(c2 + b2)
# p2 = tf.nn.max_pool2d(r2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
#
# print(c1.shape, p1.shape)       # (60000, 28, 28, 32) (60000, 14, 14, 32)
# print(c2.shape, p2.shape)       # (60000, 14, 14, 64) (60000, 7, 7, 64)
#
# # p2 = 4차원 -> 3차원으로 바꿔줘야함
# flat = tf.reshape(p2, shape=[-1, p2.shape[1] * p2.shape[2] * p2.shape[3]])
# print(flat.shape)           # (60000, 3136)
#
# # (60000, 128) = (60000, 3136) @ (3136, 128)
# d3 = tf.matmul(flat, w3) + b3
# r3 = tf.nn.relu(d3)
#
# # 10개의 숫자중 가장 높은 확률인 것을 출력하는 것임
# # (60000, 10) = (60000, 128) @ (128, 10)
# z = tf.matmul(r3, w4) + b4
# hx = tf.nn.softmax(z)

model = tf.keras.Sequential()
model.add(tf.keras.layers.Input(shape=[28, 28, 1]))
# kernel_size=3 <- 똑같은 숫자면 이렇게 가능
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=[3, 3],
                                 strides=[1, 1], padding='same', activation='relu'))    # 앞의 4개 이름 생략가능
model.add(tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=[2, 2], padding='same'))  # 전부다 순서대로쓰면 생략가능
model.add(tf.keras.layers.Conv2D(32, [3, 3], [1, 1], 'same', activation='relu'))    # 이런식으로
model.add(tf.keras.layers.MaxPool2D([2, 2], [2, 2], 'same'))                    # 생략가능

model.add(tf.keras.layers.Flatten())

model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))

# # ------------------------------------------------ # 13_02에서 가져옴
#
# loss_i = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=z, labels=ph_y)
# loss = tf.reduce_mean(loss_i)
# # ------ #
#
# optimizer = tf.compat.v1.train.AdamOptimizer(0.001)
# train = optimizer.minimize(loss)

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001),
              loss=tf.keras.losses.sparse_categorical_crossentropy,
              metrics=['acc'])

# sess = tf.compat.v1.Session()
# sess.run(tf.compat.v1.global_variables_initializer())
#
# # 미니 배취 소스 수정
# epochs = 10         # 전체 데이터 셋을 몇번이나 사용할 것인지
# batch_size = 100        # 한번에 몇개 가져와 사용 할 것인지
# n_iteration = len(x_train) // batch_size    # 몇번 반복을 해야하는지 정수 나눗셈
#
# # 기술이 들어감
# for i in range(epochs):
#     total = 0
#     for j in range(n_iteration):    # 전체 반복 6천번
#         n1 = j * batch_size  # 0 100 200 300
#         n2 = n1 + batch_size  # 100 200 300 400
#
#         xx = x_train[n1:n2]
#         yy = y_train[n1:n2]
#
#         sess.run(train, {ph_x: xx, ph_y: yy})   # weight 업데이트
#         total += sess.run(loss, {ph_x: xx, ph_y: yy})
#
#     print(i, total / n_iteration)

model.fit(x_train, y_train, epochs=10, batch_size=100, verbose=2)
print('-' * 30)

preds = model.predic(x_test)
preds_arg = np.argmax(preds, axis=1)

print('acc :', np.mean(preds_arg == y_test))

# ------------------------------------------------ #







'인공지능 > CNN' 카테고리의 다른 글

이미지 증식  (0) 2020.12.09
이미지 사이즈 조절 및 이미지 분석 (feat. VGG)  (0) 2020.12.04
VGG  (0) 2020.12.04
LeNet5  (0) 2020.12.04
#1. CNN, Keras를 사용하지 않고 내부 살펴보기  (0) 2020.12.01