from tensorflow.keras.preprocessing.image import ImageDataGenerator
# image 전처리 및 위치, class 분류
# 아주 훌륭한 함수
from tensorflow.keras import models, layers
from tensorflow.keras.applications import ResNet50V2, VGG16, DenseNet121
# 비교를 위해 3개의 trained model을 가져옴
import os
import matplotlib.pyplot as plt
import matplotlib.image as img
from glob import glob
train = 'Train/'
val = 'Validation/'
test = 'Test/'
#데이터 가져오기
train_defective = os.listdir(train+'Defective')
train_non_defective = os.listdir(train+'Non defective')
rows = 2
cols = 2
fig = plt.gcf() # 그릴려고 하는 figure 객체를 구하는 방법
fig.set_size_inches(cols * 5, rows * 5)
# 현재 가지고 있는 사진들에 path를 적용
next_defect = [os.path.join(train+'Defective', name) for name in train_defective[1:5]]
next_non_defect = [os.path.join(train+'Non defective', name) for name in train_non_defective[1:5]]
for i, img_path in enumerate(next_defect + next_non_defect):
sub = plt.subplot(rows+2, cols+2, i+1)
sub.axis('off')
# img -> import matplotlib.image as img
image = img.imread(img_path)
plt.imshow(image)
plt.show()
# 윗 줄은 아무 이상 없는 Rail
#아랫 줄은 고리가 끊어지거나 정비가 필요해 보이는 Rail
image = img.imread(next_defect[0])
plt.imshow(image)
plt.show()
# 이런 데이터 구나 확인하기 위함....
#image.shape -> (721, 960, 3)
train_generator = ImageDataGenerator(rescale = 1./255, # scale 적용
rotation_range = 40, # 회전 각도 범위
width_shift_range=0.2, # 전체 가로 넓이 비율
height_shift_range=0.2, # 전체 세로 넓이 비율
shear_range=0.2, # 반시계 방향 층 밀어내기
zoom_range=0.2, # 무작위 확대하기
horizontal_flip=True, # 무작위로 가로로 뒤집기
vertical_flip=True) # 무작위로 세로로 뒤집기
# 이렇게 다양하게 효과를 주는 이유는
# 사진 1장에 다양한 효과 (노이즈)를 줘서 하나의 이미지에서 다양한 결과를 추출하기 위함
train_gen = train_generator.flow_from_directory(train,
target_size = (300, 300),
batch_size = 16,
color_mode = 'rgb',
shuffle=True, # train에만 shuffle 적용 == test, val 적용하면 결과값이 계속 바뀌는 불상사 발생
seed=42,
class_mode='categorical')
# class_mode = binary 도 있는데 2가지의 클래스를 구분하기 위해 categorical로 적용
# 정답과 정답이 아닌 것을 적용을 하려면 binary
val_generator = ImageDataGenerator(rescale=1./255)
val_gen = val_generator.flow_from_directory(val,
target_size=(300, 300),
batch_size=16,
color_mode='rgb',
shuffle=False,
class_mode='categorical')
test_generator = ImageDataGenerator(rescale=1./255)
test_gen = test_generator.flow_from_directory(test,
target_size=(300, 300),
batch_size=16,
color_mode='rgb',
shuffle=False,
class_mode='categorical')
resnet = ResNet50V2(input_shape = (300, 300, 3), weights='imagenet', include_top=False)
resnet.trainable = False # 가져온 모델이 가중치 업데이트를 하지 못하게 함
#resnet, vgg, densenet 비교하기위함
x=resnet.output
x=layers.GlobalAveragePooling2D()(x)
x=layers.Dense(128,activation='relu')(x)
preds=layers.Dense(2,activation='softmax')(x)
resnet_model=models.Model(inputs=resnet.input,outputs=preds)
resnet_model.summary()
#---------------------------------------------------------------
vgg_model
#vgg = VGG16(input_shape = (300, 300, 3), #weights='imagenet', include_top=False)
#vgg.trainable = False # 가져온 모델이 가중치 업데이트를 하지 못하게 함
#x=vgg.output
#x=layers.GlobalAveragePooling2D()(x)
#x=layers.Dense(128,activation='relu')(x)
#preds=layers.Dense(2,activation='softmax')(x)
#vgg_model=models.Model(inputs=vgg.input,outputs=preds)
#vgg_model.summary()
#-----------------------------------------------------------------
dense_model
#dense = DenseNet121(input_shape = (300, 300, 3), #weights='imagenet', include_top=False)
#dense.trainable = False # 가져온 모델이 가중치 업데이트를 하지 못하게 함
#x=dense.output
#x=layers.GlobalAveragePooling2D()(x)
#x=layers.Dense(128,activation='relu')(x)
#preds=layers.Dense(2,activation='softmax')(x)
#dense_model=models.Model(inputs=dense.input,outputs=preds)
#dense_model.summary()
step_size_train = train_gen.n//train_gen.batch_size # train_gen.n -> .n (이미지 개수) // 16 (batch_size)
step_size_val = val_gen.n // val_gen.batch_size# val_gen.n -> .n (이미지 개수) // 16 (batch_size)
step_size_test = test_gen.n // test_gen.batch_size# test_gen.n -> .n (이미지 개수) // 16 (batch_size)
epochs=20
---------------------------------#밑으로는 모델 변경
resnet_model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
# vgg_model, dense_model
history = resnet_model.fit(train_gen,
steps_per_epoch=step_size_train, # 1번의 epoch 를 18번 반복
epochs=epochs,
validation_data=val_gen,
validation_steps=step_size_val) # 1번의 epoch를 3번 반복
print(history.history.keys())
# model이 돌아갈때 history 변수에 담아줘서 가능함
def show_train_history(hisData,train,val):
plt.plot(hisData.history[train])
plt.plot(hisData.history[val])
plt.title('Training History')
plt.ylabel(train)
plt.xlabel('Epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()
show_train_history(history, 'loss', 'val_loss')
show_train_history(history, 'accuracy', 'val_accuracy')
vgg_model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
history_vgg = vgg_model.fit(train_gen,
steps_per_epoch=step_size_train,
epochs=epochs,
validation_data=val_gen,
validation_steps=step_size_val)
def show_train_history(hisData,train,val):
plt.plot(hisData.history[train])
plt.plot(hisData.history[val])
plt.title('vgg_Training History')
plt.ylabel(train)
plt.xlabel('Epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()
show_train_history(history_vgg, 'loss', 'val_loss')
show_train_history(history_vgg, 'accuracy', 'val_accuracy')
dense_model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
history_dense = dense_model.fit(train_gen,
steps_per_epoch=step_size_train,
epochs=epochs,
validation_data=val_gen,
validation_steps=step_size_val)
def show_train_history(hisData,train,val):
plt.plot(hisData.history[train])
plt.plot(hisData.history[val])
plt.title('Dense_Training History')
plt.ylabel(train)
plt.xlabel('Epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()
show_train_history(history_dense, 'loss', 'val_loss')
show_train_history(history_dense, 'accuracy', 'val_accuracy')
resnet_model_score = resnet_model.evaluate(test_gen, steps=step_size_test)
vgg_model_score = vgg_model.evaluate(test_gen, steps=step_size_test)
dense_model_score = dense_model.evaluate(test_gen, steps=step_size_test)
# score[0] -> loss, score[1] -> accuracy
print(f'Resnet_score : {resnet_model_score}, Vgg_score : {vgg_model_score}, Dense_score : {dense_model_score}')
# 전반적으로 resnet50v2 성능이 좋다라고 보여진다.