0414 CNN_tensorflow1.15

wldnjswldnjs·2022년 5월 12일
0

딥러닝

목록 보기
4/10
post-custom-banner

1. channel이 3인 입력 데이터를 convolution 연산

import numpy as np
import tensorflow as tf

# 입력 데이터의 형태
# (이미지의 개수, 이미지의 height, 이미지의 width, channel)
# (1, 3, 3, 3)

image = np.array([[[[1, 2, 3],
                   [1, 2, 3],
                   [1, 2, 3]],
                  [[1, 2, 3],
                   [1, 2, 3],
                   [1, 2, 3]],
                  [[1, 2, 3],
                   [1, 2, 3],
                   [1, 2, 3]]]], dtype=np.float64)
print(image.shape) # (1, 3, 3, 3)

# filter의 형태
# (filter의 height, filter의 width, filter의 channel, filter의 개수)
# (2, 2, 3, 2)
weight = np.array([[[[1,2],
                    [1,2],
                    [1,2]],
                   [[1,2],
                    [1,2],
                    [1,2]]],
                   [[[1,2],
                    [1,2],
                    [1,2]],
                    [[1,2],
                    [1,2],
                    [1,2]]]], dtype=np.float64)
print(weight.shape)

conv2d = tf.nn.conv2d(image,
                      weight,
                      strides=[1,1,1,1],
                      padding='VALID') # no padding

sess = tf.Session()
result=sess.run(conv2d)

print(result) # activation map

2. channel이 3인 이미지 데이터를 convolution 연산

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib.image as img

figure = plt.figure()

ax1 = figure.add_subplot(1,3,1)
ax2 = figure.add_subplot(1,3,2)
ax3 = figure.add_subplot(1,3,3)

ori_image = img.imread('../images/girl-teddy.jpg')
# print(type(ori_image)) # <class 'numpy.ndarray'>
# print(ori_image.shape) # (429, 640, 3) # 흑백인데 3차원 => RGB값이 다 같음

ax1.imshow(ori_image)

# 입력이미지의 형태 => conv 연산하기 위해 4차원으로 변경
# (이미지의 개수, 이미지의 height, 이미지의 width, channel)
# 차원만 높인다.
# (2,)로 하면 이미지가 2장이기 때문에 데이터가 더 필요하므로 X
input_image = ori_image.reshape((1,) + ori_image.shape)
print(input_image.shape) # (1, 429, 640, 3)
input_image = input_image.astype(np.float32) # 데이터를 실수로 변환

# 이미지의 channel을 1채널로 변경
# => color를 날리고 모양만 추출하는 filter를 사용하기 위함
channel_1_input_image = input_image[:,:,:,0:1]
# 4차원을 유지해야 하기 때문에 indexing이 아닌 slicing
print(channel_1_input_image.shape) # (1, 429, 640, 1)
 
# filter의 형태
# (filter의 height, filter의 width, filter의 channel[[]], filter의 개수[])
# (3,3,1,1)
weight = np.array([[[[-1]],[[0]],[[1]]],
                   [[[-1]],[[0]],[[1]]],
                   [[[-1]],[[0]],[[1]]]])
print(weight.shape) # (3, 3, 1, 1)

# stride = 1
# padding = 'VALID'

conv2d = tf.nn.conv2d(channel_1_input_image,
                      weight,
                      strides=[1,1,1,1],
                      padding='VALID')

sess = tf.Session()
result = sess.run(conv2d)
print(result.shape)  # (1, 427, 638, 1)
                     # (이미지 개수, 특징 뽑아낸 이미지 세로, 가로, 필터 개수)

# 이미지 찍으려면 3차원이 되어야 함
t_img = result[0,:,:,:]
print(t_img.shape) # 3차원 (427, 638, 1)
ax2.imshow(t_img) # 윤곽선을 학습

# pooling 처리
pooling_result = tf.nn.max_pool(result,
                                ksize=[1,3,3,1], # 3 x 3 kernel
                                strides=[1,3,3,1], # kernel size와 동일하게 설정
                                padding='VALID')

pool_img = sess.run(pooling_result)
pool_img = pool_img[0,:,:,:]
print(pool_img.shape) # 3차원 (142, 212, 1)
ax3.imshow(pool_img) # 이미지 크기가 줄어들고 윤곽선이 뚜렷해짐

plt.tight_layout()
plt.show()

3. MNIST 예제로 convolution 연산과 pooling 작업

%reset

import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib.image as img

# Raw Data Loading
df = pd.read_csv('../data/mnist/train.csv')
display(df.head())

import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

tf.reset_default_graph() # 1.X 버전에서 충돌 방지

# Raw Data Loading
df = pd.read_csv('../data/mnist/train.csv')
# display(df.head())

# 결측치, 이상치 X

# Data Split
train_x_data , test_x_data, train_t_data, test_t_data = \
train_test_split(df.drop('label', axis=1, inplace=False),
                 df['label'],
                 test_size=0.3,
                 random_state=1,
                 stratify=df['label'])

# x_data 정규화 진행
scaler = MinMaxScaler()
scaler.fit(train_x_data)
norm_train_x_data = scaler.transform(train_x_data)
norm_test_x_data = scaler.transform(test_x_data)

# t_data one-hot encoding
sess = tf.Session()
onehot_train_t_data = sess.run(tf.one_hot(train_t_data, depth=10))
onehot_test_t_data = sess.run(tf.one_hot(test_t_data, depth=10))

# Tensorflow 구현
X = tf.placeholder(shape=[None,784], dtype=tf.float32)
T = tf.placeholder(shape=[None,10], dtype=tf.float32)

# 입력 x_data의 shape 변경
# 행을 None으로 표현해서 이미지 개수를 아직 알 수 없으므로 -1로 표현
# 2차원 이미지를 차원만 높이기 위헤 channel=1
x_img = tf.reshape(X, [-1,28,28,1]) # (이미지 개수, height, width, channel) 

# convolution layer 처리
# filter의 shape => (height, width, channel, filter 개수)
# 이미지의 channel 수와 같아야 함 (= 1)
W2 = tf.Variable(tf.random.normal([3,3,1,32])) # 32 : 내가 정한 값
L1 = tf.nn.conv2d(x_img, W2, strides=[1,1,1,1], padding='SAME')
L1 = tf.nn.relu(L1)
print('L1의 결과 데이터 shape : {}'.format(L1.shape))
# (?, 28, 28, 32)

# Max Pooling
# 이미지 개수가 아닌 size를 줄여서 전체 데이터의 size를 줄인다.
L1 = tf.nn.max_pool(L1, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
print('L1의 pooling 결과 데이터 shape : {}'.format(L1.shape))
# (?, 14, 14, 32)

# 2번째 convolution layer 처리
# filter의 shape => (height, width, channel, filter 개수)
W3 = tf.Variable(tf.random.normal([3,3,32,64]))
L2 = tf.nn.conv2d(L1, W3, strides=[1,1,1,1], padding='SAME')
L2 = tf.nn.relu(L2)
print('L1의 결과 데이터 shape : {}'.format(L2.shape))
# (?, 14, 14, 64)

# 2번째 Max Pooling
# 이미지 개수가 아닌 size를 줄여서 전체 데이터의 size를 줄인다.
L2 = tf.nn.max_pool(L2, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
print('L2의 pooling 결과 데이터 shape : {}'.format(L2.shape))
# (?, 7, 7, 64)

# 이렇게 해서 나온 데이터를 DNN에 넣어서 학습
# 4차원 => 2차원 변경
L2 = tf.reshape(L2, [-1,7*7*64])

# Weight & bias
W4 = tf.get_variable('W4', shape=[7*7*64, 256], # He's 초기법 , 256 (내가 정한 값)
                     initializer=tf.contrib.layers.variance_scaling_initializer())
b4 = tf.Variable(tf.random.normal([256]))

_layer3 = tf.matmul(L2, W4) + b4
layer3 = tf.nn.relu(_layer3)
layer3 = tf.nn.dropout(layer3, rate=0.3)

W5 = tf.get_variable('W5', shape=[256, 10], # 마지막 W : class 개수로 정해줌 
                     initializer=tf.contrib.layers.variance_scaling_initializer())
b5 = tf.Variable(tf.random.normal([10]))

# Hypothesis, model
logit = tf.matmul(layer3, W5) + b5
H =tf.nn.softmax(logit)

# loss function
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logit,
                                                                 labels=T))

# train
train = tf.train.GradientDescentOptimizer(learning_rate=1e-3).minimize(loss)

# session 및 초기화
sess.run(tf.global_variables_initializer())

# 반복학습 (batch처리해서 학습해야 한다. 근데 안 함)
for step in range(200):
    tmp, loss_val = sess.run([train, loss],
                             feed_dict={X:norm_train_x_data,
                                        T:onehot_train_t_data})
    if step % 20 == 0:
        print('loss value: {}'.format(loss_val))
post-custom-banner

0개의 댓글