■ 개 고양이 이미지 분류
*개고양이 분류 데이터 전처리 함수 4가지
1. image_load
2. label_load
3. next_batch
4. shuffle_batch
문제68. 개고양이 사진이 있는 d:\\b\\catdog 폴더를 만들고
그 폴더에 개사진 100장과 고양이 사진 100장을 넣고
아래와 같이 불러오는 함수를 생성하시오
*선생님이 catdog 따로 파일 주셨음.
1~100번 : 고양이 사진
101~200번: 개사진
import os
import numpy as np
import cv2
import csv
import random
import re
def image_load(image):
file_list = os.listdir(image)
return file_list
test_image = "d:\\b\\catdog" # 나중에 뒤에 슬래시2개 붙여줘야 함.
print(image_load(test_image))
).jpeg', ' (7).jpeg', ' (70).jpeg', ' (71).jpeg', ' (72).jpeg', ' (73).jpeg', ' (74).jpeg', ' (75).jpeg', ' (76).jpeg', ' (77).jpeg', ' (78).jpeg', ' (79).jpeg', ' (8).jpeg', ' (80).jpeg', ' (81).jpeg', ' (82).jpeg', ' (83).jpeg', ' (84).jpeg', ' (85).jpeg', ' (86).jpeg', ' (87).jpeg', ' (88).jpeg', ' (89).jpeg', ' (9).jpeg', ' (90).jpeg', ' (91).jpeg', ' (92).jpeg', ' (93).jpeg', ' (94).jpeg', ' (95).jpeg', ' (96).jpeg', ' (97).jpeg', ' (98).jpeg', ' (99).jpeg']
문제69. 위의 결과를 아래와 같이 숫자만 출력되게 하시오
import os
import numpy as np
import cv2
import csv
import random
import re
def image_load(image):
file_list = os.listdir(image)
file_list = [ int(re.sub('[^0-9]','',i)) for i in file_list ]
return file_list
test_image = "d:\\b\\catdog"
print(image_load(test_image))
[1, 10, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 11, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 12, 120, 121, 122, 123, 124, 125, 126, 127, 12
문제70. 위 숫자를 정렬해서 출력하시오
import os
import numpy as np
import cv2
import csv
import random
import re
def image_load(image):
file_list = os.listdir(image)
file_list = [ int(re.sub('[^0-9]','',i)) for i in file_list ]
file_list.sort()
return file_list
test_image = "d:\\b\\catdog"
print(image_load(test_image))
문제71. 각각의 숫자값에 '.jpeg'를 붙여서 출력하시오
문제72. 절대경로를 붙이시오.
문제73. cv2.imread 를 이용하시오.
import os
import numpy as np
import cv2
import csv
import random
import re
def image_load(image):
file_list = os.listdir(image)
file_list = [ int(re.sub('[^0-9]','',i)) for i in file_list ]
file_list.sort()
file_list2 = [image+str(i)+'.jpeg' for i in file_list]
image_list = np.array( [cv2.imread(k) for k in file_list2] )
return image_list
test_image = "d:\\b\\catdog\\"
print(image_load(test_image))
[[255 252 255]
[255 253 255]
[255 255 255]
...
[255 255 254]
[251 255 255]
[246 255 255]]
[[255 252 255]
[255 253 255]
[255 255 255]
...
[255 255 254]
[251 255 255]
[246 255 255]]
[[255 252 255]
[255 253 255]
[255 255 255]
...
[255 255 254]
[251 255 255]
[246 255 255]]]]
문제74. darkmaner.exe 라는 프로그램을 이용해서 (1).jpeg 를
1.jpeg 로 일괄 변경하시오
문제75. 위의 숫자 list를 numpy 배열로 변환해서 출력되게 하시오
문제76. 라벨값을 불러오시오
def label_load(path):
file = open(path)
label_data = csv.reader(file)
label_list = [i for i in label_data]
#label_data = np.array(label_data.astype(int))
#labeldata = np.array(list(csv.reader(open(path)))).astype(int)
#return np.eye(10)[labeldata].reshape(-1,10)
return label_list
test_label = "d:\\b\\cat_dog_label.csv"
print(label_load(test_label))
문제77. 리스트를 넘파이 배열로 변환하시오
import re
import cv2
import numpy as np
import csv
test_image='d:\\b\\catdog\\'
test_label='d:\\b\\cat_dog_label.csv'
def label_load(path):
file = open(path)
labeldata = csv.reader(file)
labellist = []
for i in labeldata:
labellist.append(i)
return np.array(labellist)
print ( label_load(test_label))
■ 개고양이의 one hot encoding
mnist : [ 0 0 0 1 0 0 0 0 0 0 ]
개고양이:[ 1 0 ]
문제78. label_load 함수를 아래와 같이 one hot encoding 된 결과로
출력되겠금 코드를 추가하시오
import re
import cv2
import numpy as np
import csv
test_image='d:\\b\\catdog\\'
test_label='d:\\b\\cat_dog_label.csv'
def label_load(path):
file = open(path)
labeldata = csv.reader(file)
labellist = []
for i in labeldata:
labellist.append(i)
label = np.array(labellist)
label = label.astype(int)
label = np.eye(2)[label]
return label
print ( label_load(test_label))
[[1. 0.]]
[[1. 0.]]
[[1. 0.]]
[[1. 0.]]]
=============다른코드
def label_load(label):
label_data = open(label)
label_data = csv.reader(label_data)
label_list = np.array( [i for i in label_data] )
label_list = label_list.astype(int)
label_list = np.eye(2)[label_list]
return label_list
print(label_load(test_label))
문제79. 위의 라벨은 3차원인데 cnn 신경망에 사용되려면 2차원으로 줄여야 한다
그래서 차원을 줄이는 코드를 추가하시오
(200, 1, 2) ------------->(200, 2)
import re
import cv2
import numpy as np
import csv
test_image='d:\\b\\catdog\\'
test_label='d:\\b\\cat_dog_label.csv'
def label_load(path):
file = open(path)
labeldata = csv.reader(file)
labellist = []
for i in labeldata:
labellist.append(i)
label = np.array(labellist)
label = label.astype(int)
label = np.eye(2)[label]
return label.reshape(-1,2)
print ( label_load(test_label).shape)
문제80. (오늘의 마지막 문제)
위의 4개의 함수를 loader3.py 로 생성해서 아래와 같이 실행되게 해보시오
import loader3
import time
train_image = 'd:\\b\\train_4000\\'
train_label = 'd:\\b\\train_label_4000.csv'
print("LOADING DATA")
start = time.time()
trainX = loader3.image_load(train_image)
print(trainX.shape) #(4000, 128, 128, 3)
trainY = loader3.label_load(train_label)
print(trainY.shape) #(40000, 2)
지금까지 사용한 데이터셋:
(또는 지금까지 구현한 코드들)
-mnist : 훈련 6만장, 테스트 1만장
-cifar10 : 훈련 5만장, 테스트 1만장
-개/고양이 : 훈련 4천장중 3900장, 테스트는 훈련에서 100장 빼와서.
-폐사진( 의료용 데이터 )
-이파리(안산시내에 상품포장지, 공업용 재료의 품질여부 검사)
-최종 포트폴리오
-신경망이 분류 못하는 이미지들은 사람이 분류할 수 있도록
별도의 폴더에 분류하는 코드 작성
-적은 데이터를 늘리는 방법
1. 이미지 회전
2. 이미지 명암 조절
모델
-Lnet 모델(cnn -> pooling -> fully connected)
1988년에 나온 모델
-VGG 모델(conv1 --> conv2 --> pooling --> conv3 --> conv4 -->pooling-->
fc1 --> fc2 -->fc3 )
-추가로 구현하고 싶은 모델?
구글에서 만든 Inception 모델.
문제81. 개/고양이 훈련 데이터 4천장 중에 개사진50장과 고양이50장을
따로 별도의 폴더에 옮기시오
훈련데이터 4000장
고양이 사진: 1~2000
개 사진: 2001~4000
↓ (각각 50장씩 빼서)
훈련데이터 3900장
고양이 사진: 1~1950
개 사진: 2001~3950
(각각 빼낸 50장씩= 100장)
테스트 데이터 100장
고양이 사진: 1951~2000
개 사진: 3951~4000
import loader3
import time
train_image = 'd:\\b\\train_4000\\'
train_label = 'd:\\b\\train_label_4000.csv'
test_image = 'd:\\b\\test_100\\'
test_label = 'd:\\b\\test_label.csv'
print("LOADING DATA")
start = time.time()
trainX = loader3.image_load(train_image)
print(trainX.shape) #(4000, 128, 128, 3)
trainY = loader3.label_load(train_label)
print(trainY.shape) #(40000, 2)
testX = loader3.image_load(test_image)
print(testX.shape) # (100, 128, 128, 3)
testY = loader3.label_load(test_label)
print(testY.shape)# (100, 2)
LOADING DATA
(3900, 128, 128, 3)
(4000, 2)
(100, 128, 128, 3)
(100, 2)
※ 신경망에 데이터를 입력하기 위해 만들어야하는 함수 4가지
1. image_load
2. label_load
3. next_batch
4. shuffle_batch
문제82. 지난번 cifar10 이미지 신경망 생성할 때 사용했던
next_batch 함수를 가지고와서 개/고양이 사진이 100개씩
배치되도록 next_batch 함수를 만들고 실행해보시오
*cifar10 때 썼던거 그대로 이용.
print(loader3.next_batch(testX, testY, 0, 100))
문제83. cifar10 때 사용했던 shuffle_batch 함수를 가져와서
개/고양이의 훈련 데이터가 잘 섞이는지 확인해보시오
print(loader3.shuffle_batch(trainX, trainY))
문제84. 개고양이 사진이 128x128 인데 너무커서 컴퓨터가 멈춘다.
32x32 로 resize 해서 별도의 폴더에 저장하시오
1. 훈련 데이터
기존 128 사이즈의 폴더(훈련) ---> 32x32 사이즈 폴더
2. 테스트 데이터
기존 128 사이즈 폴더(테스트) ---> 32x32 사이즈 폴더
import os
import cv2
path = "d:\\b\\test_100"
try:
os.mkdir("d:\\b\\test100_resize")
except:
0
file_list = os.listdir(path)
file_name = sorted([int(i[:-4]) for i in file_list])
file_list = [path+'\\'+str(i)+'.jpg' for i in file_name]
for j,i in enumerate(file_list):
img = cv2.imread(i)
width, height = img.shape[:2]
resize = cv2.resize(img, (int(width / 4), int(height / 4)), interpolation=cv2.INTER_CUBIC)
#원하는게 32*32 라서 4로 나눠준다.
cv2.imwrite("d:\\b\\test100_resize\\" + str(j+1) + '.jpg',resize)
문제85.(점심시간 문제)
32*32 로 줄인 개고양이 사진을 지난번 cifar10 할때 만들었던 vgg 코드에
입력해서 훈련시키고 테스트를 입력해서 정확도를 확인하시오
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
import matplotlib.pyplot as plt
tf.reset_default_graph()
import loader3
import time
import csv
import os
import re
import cv2
import random
train_image = 'd:\\b\\train3900_resize\\'
train_label = 'd:\\b\\train_label_4000.csv'
test_image = 'd:\\b\\test100_resize\\'
test_label = 'd:\\b\\test_label.csv'
start = time.time()
trainX = loader3.image_load(train_image)#print(trainX.shape) # (50000, 32, 32,3)
trainY = loader3.label_load(train_label)#print(trainY.shape) # (50000, 10)
testX = loader3.image_load(test_image)#print(testX.shape) # (10000,32, 32, 3)
testY = loader3.label_load(test_label)#print(testY.shape) # (10000, 10)
tf.reset_default_graph()
"""
LOADING DATA
(3900, 32, 32, 3)
(4000, 2)
(100, 32, 32, 3)
(100, 2)
"""
#입력층
x = tf.placeholder("float",[None, 32, 32, 3]) # mnist 는 처음부터 flatten 하게 제공.
x = tf.reshape(x,[-1, 32, 32, 3] ) # -1 -> 3900
#원래 사이즈가 128 인데, 너무커서 컴퓨터 뻥나간다.
#그래서 32로 resize 시킨다.
#conv1
b1 = tf.Variable(tf.ones([128]))
W1 = tf.Variable(tf.random_normal([3,3,3,128],stddev = 0.01))
y1 = tf.nn.conv2d(x, W1, strides=[1,1,1,1], padding = 'SAME')
y1 = y1 + b1
y1 = tf.nn.relu(y1)
W1_2 = tf.Variable(tf.random_normal([3,3,128,128], stddev = 0.01))
y1_2 = tf.nn.conv2d(y1, W1_2, strides=[1,1,1,1], padding = 'SAME')
y1 = tf.nn.max_pool(y1_2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'SAME') #16
# 배치정규화
y1 = tf.contrib.layers.batch_norm(y1,scale=True)
#conv2
b2 = tf.Variable(tf.ones([256]))
W2 = tf.Variable(tf.random_normal([3,3,128,256],stddev = 0.01))
y2 = tf.nn.conv2d(y1, W2, strides=[1,1,1,1], padding = 'SAME')
y2 = y2 + b2
y2 = tf.nn.relu(y2)
W2_2 = tf.Variable(tf.random_normal([3,3,256,256],stddev = 0.01))
y2_2 = tf.nn.conv2d(y2, W2_2, strides=[1,1,1,1], padding = 'SAME')
y2 = tf.nn.max_pool(y2_2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'SAME') #8
y2 = tf.contrib.layers.batch_norm(y2,scale=True)
#conv3
b3 = tf.Variable(tf.ones([512]))
W3 = tf.Variable(tf.random_normal([3,3,256,512],stddev = 0.01))
y3 = tf.nn.conv2d(y2, W3, strides=[1,1,1,1], padding = 'SAME')
y3 = y3 + b3
y3 = tf.nn.relu(y3)
W3_2 = tf.Variable(tf.random_normal([3,3,512,512],stddev = 0.01))
y3_2 = tf.nn.conv2d(y3, W3_2, strides=[1,1,1,1], padding = 'SAME')
y3 = tf.nn.max_pool(y3_2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'SAME') #4*4*512
y3 = tf.contrib.layers.batch_norm(y3,scale=True)
#fC1
b4 = tf.Variable(tf.ones([1024]))
W4 = tf.get_variable(name='W4', shape=[4*4*512, 1024], initializer=tf.contrib.layers.variance_scaling_initializer())
y4 = tf.reshape(y3, [-1, 4*4*512])
y4 = tf.matmul(y4,W4) + b4
y4 = tf.nn.relu(y4)
y4 = tf.contrib.layers.batch_norm(y4,True)
# 배치정규화 코드
batch_x1 = tf.contrib.layers.batch_norm(y4, True)
y4 = tf.nn.relu(batch_x1) # relu 활성화 함수 사용
#드롭아웃
keep_prob = tf.placeholder("float")
y4_drop = tf.nn.dropout(y4, keep_prob)
#fc2
b5 = tf.Variable(tf.ones([1024]))
W5 = tf.get_variable(name='W5', shape=[1024, 1024], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 초기값
y5 = tf.matmul(y4_drop,W5) + b5
y5 = tf.contrib.layers.batch_norm(y5,True)
#출력층
b6 = tf.Variable(tf.ones([2])) # 개,고양이 단 2개라서
W6 = tf.get_variable(name='W6', shape=[1024, 2], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 초기값
y6 = tf.matmul(y5,W6) + b6
y6 = tf.contrib.layers.batch_norm(y6,True)
y_hat = tf.nn.softmax(y6) #(100,10)
#예측값
y_predict = tf.argmax(y_hat,1)
# 라벨을 저장하기 위한 변수 생성
y_onehot = tf.placeholder("float",[None,2])
y_label = tf.argmax(y_onehot, axis = 1)
# 정확도를 출력하기 위한 변수 생성
correct_prediction = tf.equal(y_predict, y_label)
accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
# 교차 엔트로피 오차 함수
loss = -tf.reduce_sum(y_onehot * tf.log(y_hat), axis = 1)
# SGD 경사 감소법
# optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.05)
# Adam 경사 감소법
optimizer = tf.train.AdamOptimizer(learning_rate=0.001)
# 학습 오퍼레이션 정의
train = optimizer.minimize(loss)
# 변수 초기화
init = tf.global_variables_initializer()
train_acc_list = []
test_acc_list = []
with tf.Session() as sess:
sess.run(init)
for i in range(39*25):
train_xs, train_ys = loader3.shuffle_batch(trainX, trainY)
train_xs, train_ys = loader3.next_batch(train_xs, train_ys, 0, 100)
sess.run(train,feed_dict={x:train_xs, y_onehot:train_ys, keep_prob:0.9})
if i%39==0: # 600번마다 정확도 출력
train_acc_list.append(sess.run(accuracy,feed_dict={x:train_xs, y_onehot:train_ys, keep_prob:1.0}))
print("train %d 에폭 정확도 %.2f" %(i//39+1,train_acc_list[-1]), end="\t")
test_xs, test_ys = loader3.shuffle_batch(testX, testY)
test_xs, test_ys = loader3.next_batch(test_xs, test_ys, 0, 100)
test_acc_list.append(sess.run(accuracy,feed_dict={x:test_xs, y_onehot:test_ys, keep_prob:1.0}))
print("test %d 에폭 정확도 %.2f" %(i//39+1,test_acc_list[-1]))
# 테스트가 100장 밖에 없어서 for문으로 여러번 돌릴 필요가 없다.
#마지막에 한번 나오면 됨.
markers = {'train': 'o', 'test': 's'}
x = np.arange(len(train_acc_list))
plt.plot()
plt.plot(x, train_acc_list, label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(min(min(train_acc_list),min(test_acc_list))-0.1, 1.1)
plt.legend(loc='lower right')
plt.show()
■ 이미지를 회전시켜서 데이터를 늘리는 방법
openCV _.ipynb.txt <--- 파일
1. conda install -c menpo opnecv
2. 사진 D:\\1.png 로 저장한다
3. txt 지우고
쥬피터 노트 첫 화면에서 opneCV_.ipynb 를 로드한다
*홈화면에서 업로드 눌러서 위 오픈씨브이 가져와 업로드 시키고
쥬피터에서 그거 찾아서 더블클릭해서 열것.
■ 소현이가 보내준 코드(회전, 명암)
#%%
import cv2 as cv
import matplotlib.pyplot as plt
# 이미지 회전
img = plt.imread("D:\\11.png")
plt.imshow(img)
#%%
img = plt.imread("D:\\11.png")
img = cv.rotate(img, cv.ROTATE_180)
#img = cv.rotate(img, 1)
plt.imshow(img)
#%%
img = plt.imread("D:\\11.png")
img = cv.rotate(img, cv.ROTATE_90_CLOCKWISE)
#img = cv.rotate(img, 2)
plt.imshow(img)
#%%
img = plt.imread("D:\\11.png")
img = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE) #역시계방향
#img = cv.rotate(img, 0)
plt.imshow(img)
#%%
img = plt.imread("D:\\11.png")
img = cv.flip(img, 1)
plt.imshow(img)
#%%
img = plt.imread("D:\\11.png")
img = cv.flip(img, 0) # 거울효과
plt.imshow(img)
#%%
import numpy as np
img = cv.imread("D:\\11.png",0) # 사진을 흑백으로 저장
rows, cols = img.shape[0],img.shape[1]
img_0 = np.zeros(shape=(rows,cols),dtype=np.uint8)
img_1 = np.full(shape=(rows,cols),fill_value=80, dtype=np.uint8)
img_2 = np.full(shape=(rows,cols),fill_value=160, dtype=np.uint8)
img0 = cv.add(img,img_0)
img1 = cv.add(img,img_1)
img2 = cv.add(img,img_2)
cv.imshow("add_0",img0)
cv.imshow("add_80",img1)
cv.imshow("add_160",img2)
cv.waitKey()
cv.destroyAllWindows()
문제86. 이미지를 회전시키는 아래의 코드를 이용해서 개사진 1950장을
회전시킨 1950장을 생성하시오
원본이미지 train_4000 ---------> 회전시킨이미지 train_3900_rotate
import os
import cv2
path = "d:\\b\\train_4000"
try:
os.mkdir("d:\\b\\train_3900_rotate")
except:
0
file_list = os.listdir(path)
file_name = sorted([int(i[:-4]) for i in file_list])
file_list = [path+'\\'+str(i)+'.jpg' for i in file_name]
for j,i in enumerate(file_list):
img = cv2.imread(i)
width, height = img.shape[:2]
rotate = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE)
cv2.imwrite("d:\\b\\train_3900_rotate\\" + str(j+1) + '.jpg',rotate)
=============================================
import os
import cv2
path = "d:\\b\\32F_dog_train_1950"
try:
os.mkdir("d:\\b\\32F_dog_train_1950_clockwise_rotate")
except:
0
file_list = os.listdir(path)
file_name = sorted([int(i[:-4]) for i in file_list])
file_list = [path+'\\'+str(i)+'.jpg' for i in file_name]
for j,i in enumerate(file_list):
img = cv2.imread(i)
width, height = img.shape[:2]
rotate = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE)
#원하는게 32*32 라서 4로 나눠준다.
cv2.imwrite("d:\\b\\32F_dog_train_1950_clockwise_rotate\\" + str(j+1) + '.jpg',rotate)
문제87.원본과 회진시킨 사진을 합쳐서 7800장으로 다시 VGG 모델에 넣고
학습시켜서 테스트 데이터의 정확도가 올라가는지 확인하시오
고양이: 1~3900 -----> 1
(고양이 원본: 1~1950// 로테이션 1951~3900)
개: 3901 ~ 7800------> 0 (3901~5851 체인지. 5851~7800)
LOADING DATA
(7800, 32, 32, 3)
(7800, 2)
(100, 32, 32, 3)
(100, 2)
이하 긴 코드 복붙
문제88.(오늘의 마지막 문제)
카톡에 첨부한 JH_catdog2 이미지를 다운받아 VGG9 신경망에 넣어 학습시킨다.
준하가 32*32 리사이즈 작업 한 사진.
개 고양이
훈련 데이터: 1~14927 14978~32757
테스트데이터: 14928~14977 32758~32807
위 자료에서 각각 뒤에서 50장씩 총 100장을 빼와서 test 데이터 만들 것.
LOADING DATA
(32707, 32, 32, 3)
(32707, 2)
(100, 32, 32, 3)
(100, 2)
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
import matplotlib.pyplot as plt
tf.reset_default_graph()
import loader3
import time
import csv
import os
import re
import cv2
import random
train_image = 'D:\\b\\JH_catdog2\\resize\\'
train_label = 'D:\\b\\JH_catdog2\\catdog_train_label_del100.csv'
test_image = 'D:\\b\\JH_catdog2\\test2\\'
test_label = 'D:\\b\\JH_catdog2\\catdog_test_label.csv'
start = time.time()
trainX = loader3.image_load(train_image)#print(trainX.shape) # (50000, 32, 32,3)
trainY = loader3.label_load(train_label)#print(trainY.shape) # (50000, 10)
testX = loader3.image_load(test_image)#print(testX.shape) # (10000,32, 32, 3)
testY = loader3.label_load(test_label)#print(testY.shape) # (10000, 10)
tf.reset_default_graph()
print(trainX.shape)
print(trainY.shape)
print(testX.shape)
print(testY.shape)
"""
LOADING DATA
(3900, 32, 32, 3)
(4000, 2)
(100, 32, 32, 3)
(100, 2)
"""
#입력층
x = tf.placeholder("float",[None, 32, 32, 3]) # mnist 는 처음부터 flatten 하게 제공.
x = tf.reshape(x,[-1, 32, 32, 3] ) # -1 -> 3900
#원래 사이즈가 128 인데, 너무커서 컴퓨터 뻥나간다.
#그래서 32로 resize 시킨다.
#conv1
b1 = tf.Variable(tf.ones([128]))
W1 = tf.Variable(tf.random_normal([3,3,3,128],stddev = 0.01))
y1 = tf.nn.conv2d(x, W1, strides=[1,1,1,1], padding = 'SAME')
y1 = y1 + b1
y1 = tf.nn.relu(y1)
W1_2 = tf.Variable(tf.random_normal([3,3,128,128], stddev = 0.01))
y1_2 = tf.nn.conv2d(y1, W1_2, strides=[1,1,1,1], padding = 'SAME')
y1 = tf.nn.max_pool(y1_2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'SAME') #16
# 배치정규화
y1 = tf.contrib.layers.batch_norm(y1,scale=True)
#conv2
b2 = tf.Variable(tf.ones([256]))
W2 = tf.Variable(tf.random_normal([3,3,128,256],stddev = 0.01))
y2 = tf.nn.conv2d(y1, W2, strides=[1,1,1,1], padding = 'SAME')
y2 = y2 + b2
y2 = tf.nn.relu(y2)
W2_2 = tf.Variable(tf.random_normal([3,3,256,256],stddev = 0.01))
y2_2 = tf.nn.conv2d(y2, W2_2, strides=[1,1,1,1], padding = 'SAME')
y2 = tf.nn.max_pool(y2_2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'SAME') #8
y2 = tf.contrib.layers.batch_norm(y2,scale=True)
#conv3
b3 = tf.Variable(tf.ones([512]))
W3 = tf.Variable(tf.random_normal([3,3,256,512],stddev = 0.01))
y3 = tf.nn.conv2d(y2, W3, strides=[1,1,1,1], padding = 'SAME')
y3 = y3 + b3
y3 = tf.nn.relu(y3)
W3_2 = tf.Variable(tf.random_normal([3,3,512,512],stddev = 0.01))
y3_2 = tf.nn.conv2d(y3, W3_2, strides=[1,1,1,1], padding = 'SAME')
y3 = tf.nn.max_pool(y3_2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'SAME') #4*4*512
y3 = tf.contrib.layers.batch_norm(y3,scale=True)
#fC1
b4 = tf.Variable(tf.ones([1024]))
W4 = tf.get_variable(name='W4', shape=[4*4*512, 1024], initializer=tf.contrib.layers.variance_scaling_initializer())
y4 = tf.reshape(y3, [-1, 4*4*512])
y4 = tf.matmul(y4,W4) + b4
y4 = tf.nn.relu(y4)
y4 = tf.contrib.layers.batch_norm(y4,True)
# 배치정규화 코드
batch_x1 = tf.contrib.layers.batch_norm(y4, True)
y4 = tf.nn.relu(batch_x1) # relu 활성화 함수 사용
#드롭아웃
keep_prob = tf.placeholder("float")
y4_drop = tf.nn.dropout(y4, keep_prob)
#fc2
b5 = tf.Variable(tf.ones([1024]))
W5 = tf.get_variable(name='W5', shape=[1024, 1024], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 초기값
y5 = tf.matmul(y4_drop,W5) + b5
y5 = tf.contrib.layers.batch_norm(y5,True)
#출력층
b6 = tf.Variable(tf.ones([2])) # 개,고양이 단 2개라서
W6 = tf.get_variable(name='W6', shape=[1024, 2], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 초기값
y6 = tf.matmul(y5,W6) + b6
y6 = tf.contrib.layers.batch_norm(y6,True)
y_hat = tf.nn.softmax(y6) #(100,10)
#예측값
y_predict = tf.argmax(y_hat,1)
# 라벨을 저장하기 위한 변수 생성
y_onehot = tf.placeholder("float",[None,2])
y_label = tf.argmax(y_onehot, axis = 1)
# 정확도를 출력하기 위한 변수 생성
correct_prediction = tf.equal(y_predict, y_label)
accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
# 교차 엔트로피 오차 함수
loss = -tf.reduce_sum(y_onehot * tf.log(y_hat), axis = 1)
# SGD 경사 감소법
# optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.05)
# Adam 경사 감소법
optimizer = tf.train.AdamOptimizer(learning_rate=0.001)
# 학습 오퍼레이션 정의
train = optimizer.minimize(loss)
# 변수 초기화
init = tf.global_variables_initializer()
train_acc_list = []
test_acc_list = []
with tf.Session() as sess:
sess.run(init)
for i in range(39*25):
train_xs, train_ys = loader3.shuffle_batch(trainX, trainY)
train_xs, train_ys = loader3.next_batch(train_xs, train_ys, 0, 100)
sess.run(train,feed_dict={x:train_xs, y_onehot:train_ys, keep_prob:0.9})
if i%39==0: # 600번마다 정확도 출력
train_acc_list.append(sess.run(accuracy,feed_dict={x:train_xs, y_onehot:train_ys, keep_prob:1.0}))
print("train %d 에폭 정확도 %.2f" %(i//39+1,train_acc_list[-1]), end="\t")
test_xs, test_ys = loader3.shuffle_batch(testX, testY)
test_xs, test_ys = loader3.next_batch(test_xs, test_ys, 0, 100)
test_acc_list.append(sess.run(accuracy,feed_dict={x:test_xs, y_onehot:test_ys, keep_prob:1.0}))
print("test %d 에폭 정확도 %.2f" %(i//39+1,test_acc_list[-1]))
# 테스트가 100장 밖에 없어서 for문으로 여러번 돌릴 필요가 없다.
#마지막에 한번 나오면 됨.
markers = {'train': 'o', 'test': 's'}
x = np.arange(len(train_acc_list))
plt.plot()
plt.plot(x, train_acc_list, label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(min(min(train_acc_list),min(test_acc_list))-0.1, 1.1)
plt.legend(loc='lower right')
plt.show()
■ 포트폴리오를 더 빛내기 위한 Tip 구현
분류가 잘 안되는 사진을 따로 골라내서 그 사진들은 사람이 분류하게 하고
분류가 잘되는 수많은 사진들은 컴퓨터가 분류하게끔 코드를 구현.
보유기술: 딥러닝 신경망 구축
1. mnist 정확도 : 모델:
2. cifar10 정확도 : 모델:
3. 개/고양이 정확도 : 모델:
4. 폐사진 정확도: 모델:
5. 이파리 정확도: 모델:
■ 개고양이 사진에서 컴퓨터가 분류하기 어려워하는 사진을
골라내는 작업
"분류가 잘 안되는 사진을 따로 골라내서 그 사진들은
사람이 분류하게 하고 분류가 잘되는 수많은 사진들은
컴퓨터가 분류하게끔 코드를 구현"
1. 소프트맥스 함수를 통과한 결과
개사진 --> 신경망 --> [ 0.8 , 0.2 ]
↑ ↑
개 고양이
사람도 분류하기 어려운 사진 -> 신경망 -> [ 0.52 , 0.48 ]
(개/고양이) ↑ ↑
개 고양이
이런건 사람이 분류한다 !
문제89. 아래의 소프트 맥스 함수를 통과한 결과 데이터를 가지고
아래의 결과를 출력하시오
결과 :
[ 0.1 0.05 0.1 0. 0.05 0.7 0. 0.1 0. 0. ] 0.7
[ 0.1 0.05 0.2 0. 0.05 0.1 0. 0.6 0. 0. ] 0.6
[ 0. 0.05 0.3 0. 0.05 0.1 0. 0.6 0. 0. ] 0.6
[ 0. 0.05 0.4 0. 0.05 0. 0. 0.5 0. 0. ] 0.5
[ 0. 0.05 0.5 0. 0.05 0. 0. 0.4 0. 0. ] 0.5
[ 0. 0.05 0.6 0. 0.05 0. 0. 0.3 0. 0. ] 0.6
[ 0. 0.05 0.7 0. 0.05 0. 0. 0.2 0. 0. ] 0.7
[ 0. 0.1 0.8 0. 0.1 0. 0. 0.2 0. 0. ] 0.8
[ 0. 0.05 0.9 0. 0.05 0. 0. 0. 0. 0. ] 0.9
for i in range(len(x)):
print(x[i] , np.max(x,axis=1)[i])
문제90. 아래와 같이 순서번호와 최대값이 출력되게 하시오
0 0.7
1 0.6
2 0.6
3 0.5
4 0.5
5 0.6
6 0.7
7 0.8
8 0.9
여러방법들:
for i in range(len(x)):
print(i, np.max(x, axis=1)[i])
for idx, re in enumerate(x):
print(idx, re[np.argmax(re)] )
for idx, re in enumerate(x):
print(idx, np.max(re))
문제91.
0.5 ~ 0.6 사이의 확률을 갖는 이미지의 번호와 확률을 출력하시오
for idx, re in enumerate(x):
if 0.5 <= np.max(re) <= 0.6:
print(idx, np.max(re))
위 if 절 조건을 바로 print 시키면
0 False
0 0.7
1 True
1 0.6
2 True
2 0.6
3 True
3 0.5
4 True
4 0.5
5 True
5 0.6
6 False
6 0.7
7 False
7 0.8
8 False
8 0.9
문제92. 어제 완성한 개고양이 VGG 모델을 저장하시오
파이썬을 이용했을 때는
최종 갱신된 가중치와 바이어스를 pickle로 내렸는데
텐써플로우는 아래의 코드를 이용해서 모델을 저장한다
*아래 컬러 항목만 추가했음.
b1 = tf.Variable(tf.ones([128]), name='b1')
#변수명 지정 꼭 해줘야 한다함.
#모델 저장
saver = tf.train.Saver()
# 변수 초기화
init = tf.global_variables_initializer()
train_acc_list = []
test_acc_list = []
with tf.Session() as sess:
sess.run(init)
for j in range(20):
for i in range(327):
trainX , trainY = loader2.shuffle_batch(trainX, trainY)
train_xs, train_ys = loader2.next_batch(trainX, trainY, 0, 100)
sess.run(train, feed_dict={x: train_xs, y_onehot: train_ys, keep_prob: 0.8})
if i == 0:
train_acc = sess.run(accuracy, feed_dict={x: train_xs, y_onehot: train_ys, keep_prob: 1.0})
train_acc_list.append(train_acc)
print('훈련', str(j + 1) + '에폭 정확도 :', train_acc)
#모델 저장
saver.save(sess, 'd:\\catdog\\model\\model')
#catdog 디렉토리까지는 만들어야 함
화면 캡처: 2019-02-12 오전 10:53
참고사이트:
https://goodtogreate.tistory.com/entry/Saving-and-Restoring
문제93. 개고양이가 아닌 사진들을 훈련 데이터에서 빼내고
테스트 데이터에 포함시키시오
JH_catdog2\\resize 에서 찾으시오
개사진: 3297, 3299, 3302, 3300, 8362
이걸 찾아내서
트레인 -5
테스트 폴더에 +5
라벨도 각각 +-5
문제94. GPU PC 에서 20에폭 돌린 모델은 저장하고
그 모델을 CPU PC 로 옮겨서 테스트 데이터의 정확도를 확인하시오
32707개를 20에폭 돌려서 정확도 100% 나옴 (준하피셜)
소현이가 보내준 tensor.save 폴더(c 파일)
checkpoint <--------------binary 파일로 weights, biases, gradients 등을
저장한다.(변수의 값을 저장하는 파일)
(파일을 저장하고 실험을 통해 모델을 만들면
더 많은 학습이 가능해진다)
model.data-00000-of-00001 <----training variable 을 가지고 있다.
model.index
model.meta <------------------Tensorflow graph 를 저장하게 된다.
즉 all variables, operations, collections 등을
저장한다.
*모델 불러오는 방법
saver = tf.train.Saver()
# 변수 초기화
#init = tf.global_variables_initializer()
with tf.Session() as sess:
saver.restore(sess, 'd:\\catdog\\model\\model')
소현 save, 선혜 코드
#######################################################
import tensorflow as tf
import matplotlib.pyplot as plt
import loader3
import numpy as np
tf.reset_default_graph()
train_image = 'D:\\b\\JH_catdog2\\resize\\'
train_label = 'D:\\b\\JH_catdog2\\catdog_train_label_del100.csv'
test_image = 'D:\\b\\JH_catdog2\\test\\'
test_label = 'D:\\b\\JH_catdog2\\catdog_test_label.csv'
trainX = loader3.image_load(train_image)
trainY = loader3.label_load(train_label)
testX = loader3.image_load(test_image)
testY = loader3.label_load(test_label)
print(trainX.shape)
print(trainY.shape)
print(testX.shape)
print(testY.shape)
print('model loading')
tf.reset_default_graph()
hidden_layer1 = 1024
hidden_layer2 = 1024
# input
x= tf.placeholder(tf.float32, [None,32,32,3]) #
y_onehot = tf.placeholder(tf.float32, [None,2]) # onehot target값을 담는 바구니
keep_prob = tf.placeholder('float')
y_label = tf.argmax(y_onehot, axis = 1) # target 값 하나를 배출해서 담은 것
# conv1_1
W1_1 = tf.Variable(tf.random_normal(shape=[3,3,3,128], stddev=0.01), name='W1_1') # he 가중치 가로 세로 채널 갯수
L1_1 = tf.nn.conv2d(x,W1_1,strides=[1,1,1,1], padding='SAME')
b1_1 = tf.Variable(tf.ones([128]), name='b1_1') # 편향
L1_1 = L1_1 + b1_1
batch_z1_1 = tf.contrib.layers.batch_norm(L1_1, scale=True) # 배치정규화
y1_1_relu = tf.nn.leaky_relu(batch_z1_1) # relu
# conv1_2
W1_2 = tf.Variable(tf.random_normal(shape=[3,3,128,128], stddev=0.01), name='W1_2') # he 가중치
L1_2 = tf.nn.conv2d(y1_1_relu,W1_2,strides=[1,1,1,1], padding='SAME')
b1_2 = tf.Variable(tf.ones([128]), name='b1_2') # 편향
L1_2 = L1_2 + b1_2
batch_z1_2 = tf.contrib.layers.batch_norm(L1_2, scale=True) # 배치정규화
y1_2_relu = tf.nn.leaky_relu(batch_z1_2) # relu
L1_2 = tf.nn.max_pool(y1_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# conv2_1
W2_1 = tf.Variable(tf.random_normal(shape=[3,3,128,256], stddev=0.01), name='W2_1') # he 가중치
L2_1 = tf.nn.conv2d(L1_2,W2_1,strides=[1,1,1,1], padding='SAME')
b2_1 = tf.Variable(tf.ones([256]), name='b2_1') # 편향
L2_1 = L2_1 + b2_1
batch_z2_1 = tf.contrib.layers.batch_norm(L2_1, scale=True) # 배치정규화
y2_1_relu = tf.nn.leaky_relu(batch_z2_1) # relu
# conv2_2
W2_2 = tf.Variable(tf.random_normal(shape=[3,3,256,256], stddev=0.01), name='W2_2') # he 가중치
L2_2 = tf.nn.conv2d(y2_1_relu,W2_2,strides=[1,1,1,1], padding='SAME')
b2_2 = tf.Variable(tf.ones([256]), name='b2_2') # 편향
L2_2 = L2_2 + b2_2
batch_z2_2 = tf.contrib.layers.batch_norm(L2_2, scale=True) # 배치정규화
y2_2_relu = tf.nn.leaky_relu(batch_z2_2) # relu
L2_2 = tf.nn.max_pool(y2_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# conv3_1
W3_1 = tf.Variable(tf.random_normal(shape=[3,3,256,512], stddev=0.01), name='W3_1') # he 가중치
L3_1 = tf.nn.conv2d(L2_2,W3_1,strides=[1,1,1,1], padding='SAME')
b3_1 = tf.Variable(tf.ones([512]), name='b3_1') # 편향
L3_1 = L3_1 + b3_1
batch_z3_1 = tf.contrib.layers.batch_norm(L3_1, scale=True) # 배치정규화
y3_1_relu = tf.nn.leaky_relu(batch_z3_1) # relu
# conv3_2
W3_2 = tf.Variable(tf.random_normal(shape=[3,3,512,512], stddev=0.01), name='W3_2') # he 가중치
L3_2 = tf.nn.conv2d(y3_1_relu,W3_2,strides=[1,1,1,1], padding='SAME')
b3_2 = tf.Variable(tf.ones([512]), name='b3_2') # 편향
L3_2 = L3_2 + b3_2
batch_z3_2 = tf.contrib.layers.batch_norm(L3_2, scale=True) # 배치정규화
y3_2_relu = tf.nn.leaky_relu(batch_z3_2) # relu
L3_2 = tf.nn.max_pool(y3_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# FC1
W4 = tf.get_variable(name='W4', shape=[4*4*512, hidden_layer1], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 가중치
b4 = tf.Variable(tf.ones([hidden_layer1]), name='W4') # 편향
L4 = tf.reshape(L3_2,[-1,4*4*512])
y4= tf.matmul(L4,W4) + b4 # 내적
batch_z4 = tf.contrib.layers.batch_norm(y4, scale=True) # 배치정규화
y4_relu = tf.nn.leaky_relu(batch_z4) # relu
r4_drop = tf.nn.dropout(y4_relu, keep_prob)
#FC2
W5 = tf.get_variable(name='W5', shape=[hidden_layer1, hidden_layer2], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 가중치
b5 = tf.Variable(tf.ones([hidden_layer2]), name='b5') # 편향
y5= tf.matmul(r4_drop,W5) + b5 # 내적
batch_z5 = tf.contrib.layers.batch_norm(y5, scale=True) # 배치정규화
y5_relu = tf.nn.leaky_relu(batch_z5) # relu
r5_drop = tf.nn.dropout(y5_relu, keep_prob)
# output
W6 = tf.get_variable(name='W6', shape=[hidden_layer2, 2], initializer=tf.contrib.layers.variance_scaling_initializer())
b6 = tf.Variable(tf.ones([2]), name='b6')
y6= tf.matmul(r5_drop,W6) + b6
y_hat = tf.nn.softmax(y6)
y_predict = tf.argmax(y_hat, axis=1) # 예측값을 추출
correction_prediction = tf.equal( y_predict, y_label ) # 비교
accuracy = tf.reduce_mean( tf.cast( correction_prediction, 'float' ) ) # 정확도 출력
loss = -tf.reduce_sum( y_onehot*tf.log(y_hat), axis=1 ) # 손실함수
optimizer = tf.train.AdamOptimizer(learning_rate=0.001)
train = optimizer.minimize(loss)
saver = tf.train.Saver()
# 변수 초기화
#init = tf.global_variables_initializer()
train_acc_list = []
test_acc_list = []
with tf.Session() as sess:
saver.restore(sess, 'd:\\catdog\\model\\model')
test_xs, test_ys = next_batch(testX,testY,0,105)
test_acc_list.append(sess.run(accuracy,feed_dict={x:test_xs, y_onehot:test_ys, keep_prob:1.0}))
print("test 에폭 정확도 %.2f" %(test_acc_list[-1]))
print(sess.run(W1_1).shape)
print(sess.run(W1_2).shape)
print(sess.run(W2_1).shape)
print(sess.run(W2_2).shape)
print(sess.run(W3_1).shape)
print(sess.run(W3_2).shape)
(32707, 32, 32, 3)
(32707, 2)
(100, 32, 32, 3)
(100, 2)
model loading
INFO:tensorflow:Restoring parameters from d:\catdog\model\model
test 에폭 정확도 0.91
(3, 3, 3, 128)
(3, 3, 128, 128)
(3, 3, 128, 256)
(3, 3, 256, 256)
(3, 3, 256, 512)
(3, 3, 512, 512)
문제95. 개와 고양이 사진 한 장을 신경망에 입력해서 개인지 고양이인지
잘 맞추는지 확인하시오
RESIZE
import tensorflow as tf
import matplotlib.pyplot as plt
import loader3
import numpy as np
import os
import cv2
path = 'D:\\b\\odd'
file_list = os.listdir(path)
file_name = sorted([int(i[:-4]) for i in file_list])
# int 처리할거라서 사진이름은 숫자만 !
file_list = [path+'\\'+str(i)+'.jpg' for i in file_name]
# print(file_list)
# ['D:\\b\\odd\\1.jpg']
for j,i in enumerate(file_list):
img = cv2.imread(i)
width, height = img.shape[:2]
resize = cv2.resize(img, (int(width/5), int(height/5)), interpolation=cv2.INTER_CUBIC)
#원하는게 32*32 라서 4로 나눠준다.
cv2.imwrite("d:\\b\\odd\\" + str(j+1) + '.jpg',resize)
(구글에서 개 또는 고양이 사진을 한 장 다운받아서 32x32 로 줄여서
신경망에 입력하시오)
목표: 개인지 고양이인지 컴퓨터도 잘 구분 못하는 사진은 사람이 구분하게끔
별도의 폴더에 저장하는 코드 구현 !
import tensorflow as tf
import matplotlib.pyplot as plt
import loader3
import numpy as np
tf.reset_default_graph()
train_image = 'D:\\b\\JH_catdog2\\resize_del5\\'
train_label = 'D:\\b\\JH_catdog2\\catdog_train_label_del100_del5.csv'
test_image = 'D:\\b\\JH_catdog2\\test2\\'
test_label = 'D:\\b\\JH_catdog2\\catdog_test_label.csv'
trainX = loader3.image_load(train_image)
trainY = loader3.label_load(train_label)
testX = loader3.image_load(test_image)
testY = loader3.label_load(test_label)
print(trainX.shape)
print(trainY.shape)
print(testX.shape)
print(testY.shape)
print('model loading')
tf.reset_default_graph()
hidden_layer1 = 1024
hidden_layer2 = 1024
# input
x= tf.placeholder(tf.float32, [None,32,32,3]) #
y_onehot = tf.placeholder(tf.float32, [None,2]) # onehot target값을 담는 바구니
keep_prob = tf.placeholder('float')
y_label = tf.argmax(y_onehot, axis = 1) # target 값 하나를 배출해서 담은 것
# conv1_1
W1_1 = tf.Variable(tf.random_normal(shape=[3,3,3,128], stddev=0.01), name='W1_1') # he 가중치 가로 세로 채널 갯수
L1_1 = tf.nn.conv2d(x,W1_1,strides=[1,1,1,1], padding='SAME')
b1_1 = tf.Variable(tf.ones([128]), name='b1_1') # 편향
L1_1 = L1_1 + b1_1
batch_z1_1 = tf.contrib.layers.batch_norm(L1_1, scale=True) # 배치정규화
y1_1_relu = tf.nn.leaky_relu(batch_z1_1) # relu
# conv1_2
W1_2 = tf.Variable(tf.random_normal(shape=[3,3,128,128], stddev=0.01), name='W1_2') # he 가중치
L1_2 = tf.nn.conv2d(y1_1_relu,W1_2,strides=[1,1,1,1], padding='SAME')
b1_2 = tf.Variable(tf.ones([128]), name='b1_2') # 편향
L1_2 = L1_2 + b1_2
batch_z1_2 = tf.contrib.layers.batch_norm(L1_2, scale=True) # 배치정규화
y1_2_relu = tf.nn.leaky_relu(batch_z1_2) # relu
L1_2 = tf.nn.max_pool(y1_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# conv2_1
W2_1 = tf.Variable(tf.random_normal(shape=[3,3,128,256], stddev=0.01), name='W2_1') # he 가중치
L2_1 = tf.nn.conv2d(L1_2,W2_1,strides=[1,1,1,1], padding='SAME')
b2_1 = tf.Variable(tf.ones([256]), name='b2_1') # 편향
L2_1 = L2_1 + b2_1
batch_z2_1 = tf.contrib.layers.batch_norm(L2_1, scale=True) # 배치정규화
y2_1_relu = tf.nn.leaky_relu(batch_z2_1) # relu
# conv2_2
W2_2 = tf.Variable(tf.random_normal(shape=[3,3,256,256], stddev=0.01), name='W2_2') # he 가중치
L2_2 = tf.nn.conv2d(y2_1_relu,W2_2,strides=[1,1,1,1], padding='SAME')
b2_2 = tf.Variable(tf.ones([256]), name='b2_2') # 편향
L2_2 = L2_2 + b2_2
batch_z2_2 = tf.contrib.layers.batch_norm(L2_2, scale=True) # 배치정규화
y2_2_relu = tf.nn.leaky_relu(batch_z2_2) # relu
L2_2 = tf.nn.max_pool(y2_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# conv3_1
W3_1 = tf.Variable(tf.random_normal(shape=[3,3,256,512], stddev=0.01), name='W3_1') # he 가중치
L3_1 = tf.nn.conv2d(L2_2,W3_1,strides=[1,1,1,1], padding='SAME')
b3_1 = tf.Variable(tf.ones([512]), name='b3_1') # 편향
L3_1 = L3_1 + b3_1
batch_z3_1 = tf.contrib.layers.batch_norm(L3_1, scale=True) # 배치정규화
y3_1_relu = tf.nn.leaky_relu(batch_z3_1) # relu
# conv3_2
W3_2 = tf.Variable(tf.random_normal(shape=[3,3,512,512], stddev=0.01), name='W3_2') # he 가중치
L3_2 = tf.nn.conv2d(y3_1_relu,W3_2,strides=[1,1,1,1], padding='SAME')
b3_2 = tf.Variable(tf.ones([512]), name='b3_2') # 편향
L3_2 = L3_2 + b3_2
batch_z3_2 = tf.contrib.layers.batch_norm(L3_2, scale=True) # 배치정규화
y3_2_relu = tf.nn.leaky_relu(batch_z3_2) # relu
L3_2 = tf.nn.max_pool(y3_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# FC1
W4 = tf.get_variable(name='W4', shape=[4*4*512, hidden_layer1], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 가중치
b4 = tf.Variable(tf.ones([hidden_layer1]), name='W4') # 편향
L4 = tf.reshape(L3_2,[-1,4*4*512])
y4= tf.matmul(L4,W4) + b4 # 내적
batch_z4 = tf.contrib.layers.batch_norm(y4, scale=True) # 배치정규화
y4_relu = tf.nn.leaky_relu(batch_z4) # relu
r4_drop = tf.nn.dropout(y4_relu, keep_prob)
#FC2
W5 = tf.get_variable(name='W5', shape=[hidden_layer1, hidden_layer2], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 가중치
b5 = tf.Variable(tf.ones([hidden_layer2]), name='b5') # 편향
y5= tf.matmul(r4_drop,W5) + b5 # 내적
batch_z5 = tf.contrib.layers.batch_norm(y5, scale=True) # 배치정규화
y5_relu = tf.nn.leaky_relu(batch_z5) # relu
r5_drop = tf.nn.dropout(y5_relu, keep_prob)
# output
W6 = tf.get_variable(name='W6', shape=[hidden_layer2, 2], initializer=tf.contrib.layers.variance_scaling_initializer())
b6 = tf.Variable(tf.ones([2]), name='b6')
y6= tf.matmul(r5_drop,W6) + b6
y_hat = tf.nn.softmax(y6)
y_predict = tf.argmax(y_hat, axis=1) # 예측값을 추출
correction_prediction = tf.equal( y_predict, y_label ) # 비교
accuracy = tf.reduce_mean( tf.cast( correction_prediction, 'float' ) ) # 정확도 출력
loss = -tf.reduce_sum( y_onehot*tf.log(y_hat), axis=1 ) # 손실함수
#optimizer = tf.train.AdamOptimizer(learning_rate=0.001)
#train = optimizer.minimize(loss)
# SGD 경사 감소법
# optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.05)
#텐써플로우 문제96
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
# Ensures that we execute the update_ops before performing the train_step
train = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
saver = tf.train.Saver()
# 변수 초기화
#init = tf.global_variables_initializer()
train_acc_list = []
test_acc_list = []
with tf.Session() as sess:
saver.restore(sess, 'd:\\catdog\\model\\model')
#적정 가중치 찾았으니 셔플쓰면 안됨 !
test_xs, test_ys = loader3.next_batch(testX,testY,0,105)
test_acc_list.append(sess.run(accuracy,feed_dict={x:test_xs, y_onehot:test_ys, keep_prob:1.0}))
print("test 에폭 정확도 %.2f" %(test_acc_list[-1]))
print("예상값:", sess.run(y_hat, feed_dict={x:test_xs, y_onehot:test_ys, keep_prob:1.0}).round(3) )
print(sess.run(W1_1).shape)
print(sess.run(W1_2).shape)
print(sess.run(W2_1).shape)
print(sess.run(W2_2).shape)
print(sess.run(W3_1).shape)
print(sess.run(W3_2).shape)
예상값: [[0.022 0.978] # 고양이로 판단함 !
문제96. 훈련할 때 사용했던 배치 정규화의 감마, 베타 값이 테스트 할 때도
사용할 수 있도록 아래의 코드를 훈련할 때 추가해서 다시 모델을 만들고
모델을 배포하시오
# SGD 경사 감소법
# optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.05)
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
# Ensures that we execute the update_ops before performing the train_step
train = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
■ 훈련할 때 98% 이상 정확도를 보였던 모델이 테스트할 때
멍청해진 이유는?
training = tf.palceholder(tf.bool , name='training')
batch_z4 = tf.contrib.layers.batch_norm(y4, scale=True, is_training=training)
#배치정규화
# is_training = training 을 안쓰면 default 값을 쓴다. 디폴트는 True
# 이제껏 우리는 테스트 돌릴 때 새로운 트레이닝 값으로 돌린거다.
# 그래서 테스트할 때 멍청해진거다.
맨 아래 코드:
# 테스트 할때는 False 로 두고
print( sess.run(y_hat, feed_dict={x:test_txs, keep_prob:1.0, training:False}) )
# 훈련 시킬때는 True 로 둔다.
print( sess.run(y_hat, feed_dict={x:test_txs, keep_prob:1.0, training:True}) )
# 배치정규화는?
가중치 값들이 훈련할 때 계속 정규 분포를 유지하도록
각 층에서 강제화 하는 방법.
훈련할 때 정규 분포를 유지하도록 만들어낸
감마값(평균), 베타값(분산)을 가지고 테스트할 때
사용해야 하는데 할려면 아래와 같이 코드를 작성해야 한다.
문제98.(오늘의 마지막 문제)
테스트 데이터 100장을 테스트 할 때 소프트맥스를 통과한 확률값이
0.4~0.6 사이인 이미지의 이미지 번호를 출력하고
사람이 봐도 개인지 고양이인지 구분이 어려운지 확인하시오
import tensorflow as tf
import matplotlib.pyplot as plt
import loader3
import numpy as np
tf.reset_default_graph()
train_image = 'D:\\b\\JH_catdog2\\resize_del5\\'
train_label = 'D:\\b\\JH_catdog2\\catdog_train_label_del100_del5.csv'
test_image = 'D:\\b\\JH_catdog2\\test2\\'
test_label = 'D:\\b\\JH_catdog2\\catdog_test_label.csv'
trainX = loader3.image_load(train_image)
trainY = loader3.label_load(train_label)
testX = loader3.image_load(test_image)
testY = loader3.label_load(test_label)
"""
print(trainX.shape)
print(trainY.shape)
print(testX.shape)
print(testY.shape)
"""
print('model loading')
#trainX, trainY = loader3.shuffle_batch(trainX, trainY)
#trainX, trainY = loader3.next_batch(trainX, trainY, 0, 100)
#testX, testY = loader3.next_batch(testX, testY, 0, 100)
#훈련때문에 필요한거. 지금은 노필요.
tf.reset_default_graph()
hidden_layer1 = 1024
hidden_layer2 = 1024
# input
x= tf.placeholder(tf.float32, [None,32,32,3]) #
y_onehot = tf.placeholder(tf.float32, [None,2]) # onehot target값을 담는 바구니
keep_prob = tf.placeholder('float')
training = tf.placeholder(tf.bool, name='training' )
y_label = tf.argmax(y_onehot, axis = 1) # target 값 하나를 배출해서 담은 것
# conv1_1
W1_1 = tf.Variable(tf.random_normal(shape=[3,3,3,128], stddev=0.01), name='W1_1') # he 가중치 가로 세로 채널 갯수
L1_1 = tf.nn.conv2d(x,W1_1,strides=[1,1,1,1], padding='SAME')
b1_1 = tf.Variable(tf.ones([128]), name='b1_1') # 편향
L1_1 = L1_1 + b1_1
batch_z1_1 = tf.contrib.layers.batch_norm(L1_1, scale=True, is_training=training) # 배치정규화
y1_1_relu = tf.nn.leaky_relu(batch_z1_1) # relu
#%%
# conv1_2
W1_2 = tf.Variable(tf.random_normal(shape=[3,3,128,128], stddev=0.01), name='W1_2') # he 가중치
L1_2 = tf.nn.conv2d(y1_1_relu,W1_2,strides=[1,1,1,1], padding='SAME')
b1_2 = tf.Variable(tf.ones([128]), name='b1_2') # 편향
L1_2 = L1_2 + b1_2
batch_z1_2 = tf.contrib.layers.batch_norm(L1_2, scale=True, is_training=training) # 배치정규화
y1_2_relu = tf.nn.leaky_relu(batch_z1_2) # relu
L1_2 = tf.nn.max_pool(y1_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# conv2_1
W2_1 = tf.Variable(tf.random_normal(shape=[3,3,128,256], stddev=0.01), name='W2_1') # he 가중치
L2_1 = tf.nn.conv2d(L1_2,W2_1,strides=[1,1,1,1], padding='SAME')
b2_1 = tf.Variable(tf.ones([256]), name='b2_1') # 편향
L2_1 = L2_1 + b2_1
batch_z2_1 = tf.contrib.layers.batch_norm(L2_1, scale=True, is_training=training) # 배치정규화
y2_1_relu = tf.nn.leaky_relu(batch_z2_1) # relu
# conv2_2
W2_2 = tf.Variable(tf.random_normal(shape=[3,3,256,256], stddev=0.01), name='W2_2') # he 가중치
L2_2 = tf.nn.conv2d(y2_1_relu,W2_2,strides=[1,1,1,1], padding='SAME')
b2_2 = tf.Variable(tf.ones([256]), name='b2_2') # 편향
L2_2 = L2_2 + b2_2
batch_z2_2 = tf.contrib.layers.batch_norm(L2_2, scale=True, is_training=training) # 배치정규화
y2_2_relu = tf.nn.leaky_relu(batch_z2_2) # relu
L2_2 = tf.nn.max_pool(y2_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# conv3_1
W3_1 = tf.Variable(tf.random_normal(shape=[3,3,256,512], stddev=0.01), name='W3_1') # he 가중치
L3_1 = tf.nn.conv2d(L2_2,W3_1,strides=[1,1,1,1], padding='SAME')
b3_1 = tf.Variable(tf.ones([512]), name='b3_1') # 편향
L3_1 = L3_1 + b3_1
batch_z3_1 = tf.contrib.layers.batch_norm(L3_1, scale=True, is_training=training) # 배치정규화
y3_1_relu = tf.nn.leaky_relu(batch_z3_1) # relu
# conv3_2
W3_2 = tf.Variable(tf.random_normal(shape=[3,3,512,512], stddev=0.01), name='W3_2') # he 가중치
L3_2 = tf.nn.conv2d(y3_1_relu,W3_2,strides=[1,1,1,1], padding='SAME')
b3_2 = tf.Variable(tf.ones([512]), name='b3_2') # 편향
L3_2 = L3_2 + b3_2
batch_z3_2 = tf.contrib.layers.batch_norm(L3_2, scale=True, is_training=training) # 배치정규화
y3_2_relu = tf.nn.leaky_relu(batch_z3_2) # relu
L3_2 = tf.nn.max_pool(y3_2_relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
#%%
# FC1
W4 = tf.get_variable(name='W4', shape=[4*4*512, hidden_layer1], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 가중치
b4 = tf.Variable(tf.ones([hidden_layer1]), name='b4') # 편향
L4 = tf.reshape(L3_2,[-1,4*4*512])
y4= tf.matmul(L4,W4) + b4 # 내적
batch_z4 = tf.contrib.layers.batch_norm(y4, scale=True, is_training=training) # 배치정규화
y4_relu = tf.nn.leaky_relu(batch_z4) # relu
r4_drop = tf.nn.dropout(y4_relu, keep_prob)
#FC2
W5 = tf.get_variable(name='W5', shape=[hidden_layer1, hidden_layer2], initializer=tf.contrib.layers.variance_scaling_initializer()) # he 가중치
b5 = tf.Variable(tf.ones([hidden_layer2]), name='b5') # 편향
y5= tf.matmul(r4_drop,W5) + b5 # 내적
batch_z5 = tf.contrib.layers.batch_norm(y5, scale=True, is_training=training) # 배치정규화
y5_relu = tf.nn.leaky_relu(batch_z5) # relu
r5_drop = tf.nn.dropout(y5_relu, keep_prob)
#%%
# output
W6 = tf.get_variable(name='W6', shape=[hidden_layer2, 2], initializer=tf.contrib.layers.variance_scaling_initializer())
b6 = tf.Variable(tf.ones([2]), name='b6')
y6= tf.matmul(r5_drop,W6) + b6
y_hat = tf.nn.softmax(y6)
y_predict = tf.argmax(y_hat, axis=1) # 예측값을 추출
correction_prediction = tf.equal( y_predict, y_label ) # 비교
accuracy = tf.reduce_mean( tf.cast( correction_prediction, 'float' ) ) # 정확도 출력
loss = -tf.reduce_sum( y_onehot*tf.log(y_hat), axis=1 ) # 손실함수
#optimizer = tf.train.AdamOptimizer(learning_rate=0.001)
#train = optimizer.minimize(loss)
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
# Ensures that we execute the update_ops before performing the train_step
train = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
"""
#훈련_실행부
init = tf.global_variables_initializer()
train_acc_list = []
test_acc_list = []
with tf.Session() as sess:
sess.run(init)
for i in range(1,10000+1):
trainX, trainY = loader3.shuffle_batch(trainX, trainY)
testX, testY = loader3.shuffle_batch(testX, testY)
train_xs, train_ys = loader3.next_batch(trainX, trainY,0,100)
test_xs, test_ys = loader3.next_batch(testX, testY,0,100)
sess.run(train, feed_dict={x: train_xs, y_onehot: train_ys, keep_prob:0.9, training:True})
if i % 300 == 0:
print ( i/300 , 'train ecpo acc:' ,sess.run(accuracy,feed_dict={x:train_xs, y_onehot: train_ys, keep_prob:1.0, training:True}))
print ( i/300 , 'test ecpo acc:' ,sess.run(accuracy,feed_dict={x:test_xs, y_onehot: test_ys, keep_prob:1.0, training:False}))
train_acc_list.append(sess.run(accuracy,feed_dict={x:train_xs, y_onehot: train_ys, keep_prob:1.0, training:False}))
testX, testY = loader3.shuffle_batch(testX, testY)
test_xs, test_ys = loader3.next_batch(testX, testY,0,100)
print ("=========================================================")
if float( sess.run(accuracy,feed_dict={x:train_xs, y_onehot: train_ys, keep_prob:1.0, training:True}) ) >= 0.95 and\
float( sess.run(accuracy,feed_dict={x:test_xs, y_onehot: test_ys, keep_prob:1.0, training:False}) ) >= 0.92:
#모델 저장
saver.save(sess, 'D:\\catdog\final_weight\\model')
#확장자 뗀 model 까지 붙여야 돌아감
break
"""
#모델 저장
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, 'D:\\catdog\\final_weight\\model')
#test_txs, test_tys = loader3.next_batch(test_img, test_lb,0,3)
# 라벨 필요없는 이유_최적의 가중치(saver)로 출력시키는거라서
test_txs = testX
result = sess.run(y_hat, feed_dict={x:test_txs, keep_prob:1.0, training:False}).round(4)
# y_hat 은 소프트맥스 통과한 확률값
for idx, r in enumerate(result,1): # test니까 100개
if 0.4 <= r[np.argmax(idx)] <= 0.6:
print('----------------------------')
print(idx, r)
model loading
INFO:tensorflow:Restoring parameters from D:\catdog\final_weight\model
----------------------------
64 [0.4461 0.5539]
----------------------------
74 [0.4902 0.5098]
■ 딥러닝 마무리 목표
1. 모델 저장과 모델 불러오는 방법
2. 배치정규화를 훈련때는 켜고 테스트때 끄는 방법
3. VGG9 모델을 가지고 개, 고양이 사진을 분류
정확도: 훈련100%, 테스트 90%
포트폴리오를 빛내기 위한 TIP
컴퓨터가 분류하기 어려운 사진들은 사람이 분류할 수 있도록
별도의 폴더로 사진을 옮기는 코드 구현
■ 수아랩에서 이미지 데이터 전처리
1. 훈련하는 신경망에 입력할 이미지 중에 아웃라이어(개고양이 사진중 남자속옷사진)가 섞여있으면 아무리 학습해도 정확도가 더 개선이 안 된다.
아웃라이어 데이터를 제거하는 작업
아웃라이더 데이터를 제거하는 자동화 코드 구현(최근에)
↓
[0.51, 0.49] <---애매한 사진
사람사진(라벨 -> 0) ---> [0.2, 0.8]
개 ↑
테스트 데이터에서 못 맞춘 사진들을
따로 분석한다
별도의 폴더에 들어간 사진이 전혀 다른 사진이다.
즉 사람 사진이다 라면 아예 삭제해 버린다.
개 사진인데 확률이 0.2 이하로 나와서 신경망이 계속 못맞추면
그 사진과 비슷한 사진을 더 모아서 훈련 데이터에 입력한다
(회전, 명암 조절등을 해서 비슷한 사진의 데이터를 늘린다)
문제99. 문제98번 코드로 테스트 데이터 100장을 다시 테스트 하는데
테스트 데이터 중에 못 맞춘 사진의 번호가 어떻게 되는지 출력하시오
0또는 1이 나오는 predict 값과 label 값을 비교해서
불일치 하는 값을 갖고 오는 코드
#모델 저장
saver = tf.train.Saver()
with tf.Session() as sess:
test_acc_list = []
saver.restore(sess, 'D:\\catdog\\final_weight\\model')
#test_txs, test_tys = loader3.next_batch(test_img, test_lb,0,3)
# 라벨 필요없는 이유_최적의 가중치(saver)로 출력시키는거라서
test_txs = testX
test_label = testY
test_acc_list.append(sess.run(accuracy, feed_dict={x: test_txs, y_onehot: test_label, keep_prob: 1.0, training:False}))
# 정확도
print(test_acc_list)
l = sess.run(y_label, feed_dict={x: test_txs, y_onehot: test_label, keep_prob: 1.0, training: False})
p = sess.run(y_predict, feed_dict={x:test_txs, keep_prob:1.0, training:False}).round(4)
w = []
for x in range(len(p)):
if p[x] != l[x] :
w.append(x+1)
print(w)
print(len(w))
INFO:tensorflow:Restoring parameters from D:\catdog\final_weight\model
[12, 28, 47, 48, 52, 63, 81, 83, 93, 96, 97, 99, 100]
13
문제100.
틀린 사진만 D:\\wrong_image 라는 폴더에 옮겨지게 하시오
#모델 저장
saver = tf.train.Saver()
with tf.Session() as sess:
test_acc_list = []
saver.restore(sess, 'D:\\catdog\\final_weight\\model')
#test_txs, test_tys = loader3.next_batch(test_img, test_lb,0,3)
test_txs = testX
test_label = testY
test_acc_list.append(sess.run(accuracy, feed_dict={x: test_txs, y_onehot: test_label, keep_prob: 1.0, training:False}))
print("정확도:",test_acc_list)
l = sess.run(y_label, feed_dict={x: test_txs, y_onehot: test_label, keep_prob: 1.0, training: False})
p = sess.run(y_predict, feed_dict={x:test_txs, keep_prob:1.0, training:False}).round(4)
w = []
for x in range(len(p)):
if p[x] != l[x] :
w.append(x+1)
#w = [ x+1 for x in range(len(p)) if p[x] != l[x] ]
print("불일치 사진:",w)
print("불일치 갯수:",len(w))
import cv2
path = 'D:\\b\\JH_catdog2\\test2\\'
for i in w:
image = cv2.imread('{}{}.jpeg'.format(path, i) )
cv2.imwrite('D:\\b\\wrong_img\\{}.jpeg'.format(i), image)
print('complite')
문제101.
못맞춘 이미지 중에 확률이 0.2 이하인 것만 wrong_img 폴더에 옮겨지게 하시오
#모델 저장
saver = tf.train.Saver()
with tf.Session() as sess:
test_acc_list = []
saver.restore(sess, 'D:\\catdog\\final_weight\\model')
#test_txs, test_tys = loader3.next_batch(test_img, test_lb,0,3)
test_txs = testX
test_label = testY
test_acc_list.append(sess.run(accuracy, feed_dict={x: test_txs, y_onehot: test_label, keep_prob: 1.0, training:False}))
print("정확도:",test_acc_list)
l = sess.run(y_label, feed_dict={x: test_txs, y_onehot: test_label, keep_prob: 1.0, training: False})
p = sess.run(y_predict, feed_dict={x:test_txs, keep_prob:1.0, training:False}).round(4)
h = sess.run(y_hat, feed_dict={x:test_txs, keep_prob:1.0, training:False}).round(4)
# print(h.shape) (100,2)
w = []
for x in range(len(p)):
if p[x] != l[x] :
w.append(x+1)
#w = [ x+1 for x in range(len(p)) if p[x] != l[x] ]
print("라벨과 불일치 사진:",w)
print("라벨과 불일치 갯수:",len(w))
wrong_image_list=[]
for x in range(len(p)):
if p[x] != l[x] and np.min(h[x])<=0.2:
# 불일치라서 min 값을 쓴다.
wrong_image_list.append(x+1)
print("불일치and틀린 확률이 0.2이하 사진:",wrong_image_list)
print("불일치and틀린 확률0.2이하 사진 갯수:",len(wrong_image_list))
model loading
INFO:tensorflow:Restoring parameters from D:\catdog\final_weight\model
정확도: [0.87]
라벨과 불일치 사진: [12, 28, 47, 48, 52, 63, 81, 83, 93, 96, 97, 99, 100]
라벨과 불일치 갯수: 13
불일치and틀린 확률이 0.2이하 사진: [12, 28, 47, 52, 63, 81, 83, 93, 97, 99, 100]
불일치and틀린 확률0.2이하 사진 갯수: 11
'tensorflow' 카테고리의 다른 글
5. 실습-폐사진 (0) | 2019.03.31 |
---|---|
3. 텐써플로우 다층신경망 구성 (0) | 2019.03.31 |
2. 텐써플로우 단층신경망 구성 (0) | 2019.03.31 |
1. 텐써플로우 소개 (0) | 2019.03.31 |