tf2로0 Alexnet 모형(꽃 분류)을 훈련하는 과정

30683 단어

전언


요즘 TF2.1. 이전에pytorch를 배웠지만 tf를 많이 사용해야 할 것 같아서 2.1버전에 대한 공부를 시작했습니다. 초보자로서 매번의 코드를 기록했습니다. 이번 훈련에서 많은 문제점을 겪었습니다. 이에 기록합니다.
"""GPU  """
from myAlextNet_Module import AlexNet
import tensorflow as tf
import json
import os
import time
import glob
import random
import matplotlib.pylab as plt

os.environ["CUDA_DEVICE_ORDER"] = 'PCI_BUS_ID'
os.environ['CUDA_VISIBLE_DEVICES'] = '0'

# gpus = tf.config.experimental.list_physical_devices("GPU")
gpus = tf.config.experimental.list_physical_devices("GPU")
if gpus:
    try:
        for gpu in gpus:
            tf.config.experimental.set_memory_growth(gpu, True)
    except RuntimeError as e:
        print(e)
        exit(-1)
root = os.path.abspath(os.getcwd())  # get root path

image_path = root + '/' + 'flower_data/'   #       
train_dir = image_path + 'train'
validation_dir = image_path + 'val'

#      ,        
if not os.path.exists('save_weights'):
    os.makedirs("save_weights")

####      
im_height =224
im_width = 224
batch_size = 64
epoch = 10

#       ,{key = "idx': val = 'class_name'},    
data_class = [cla for cla in os.listdir(train_dir)]
class_num = len(data_class)
class_dir = dict(zip(data_class, range(class_num)))
invs_class_dir = dict(zip(range(class_num), data_class))

#    json   
json_str = json.dumps(invs_class_dir, indent=4)  #        
with open("class_indices.json", "w") as json_file:
    json_file.write(json_str)
json_str = json.dumps(invs_class_dir, indent=4)

train_image_list = glob.glob(train_dir + '/*/*.jpg')
random.shuffle(train_image_list)
train_num = len(train_image_list)
#        
train_label_list = [class_dir[path.split(os.path.sep)[-2]] for path in train_image_list]

val_image_list = glob.glob(validation_dir + '/*/*.jpg')
random.shuffle(val_image_list)
val_num = len(train_image_list)
#        
val_label_list = [class_dir[path.split(os.path.sep)[-2]] for path in val_image_list]

def process_path(img_path, label):
    label = tf.one_hot(label, depth=class_num)
    image = tf.io.read_file(img_path)
    image = tf.image.decode_jpeg(image, 0)
    image = tf.image.convert_image_dtype(image, dtype=tf.float32) # [0,1]
    image = tf.image.resize(image, (im_height,im_width))
    return image, label


AUTOTUNE = tf.data.experimental.AUTOTUNE

train_dataset = tf.data.Dataset.from_tensor_slices((train_image_list, train_label_list))
train_dataset = train_dataset.shuffle(buffer_size=train_num)\
    .map(process_path, num_parallel_calls=AUTOTUNE).repeat()\
    .batch(batch_size)

val_dataset = tf.data.Dataset.from_tensor_slices((val_image_list, val_label_list))
val_dataset = val_dataset.shuffle(buffer_size=val_num)\
    .map(process_path, num_parallel_calls=AUTOTUNE).repeat()\
    .batch(batch_size)

#      
model = AlexNet(class_num=5)
model.build((batch_size,224,224,3))
model.summary()

# using keras high level api for training
model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.0005),
    loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False),
    metrics=['accuracy'])

def scheduler(epoch):
    if epoch < 10:
        return 0.01
    else:
        return 0.001 * tf.math.exp(0.1 * (10 - epoch))

callbacks = [tf.keras.callbacks.ModelCheckpoint(filepath='./save_weights/myAlex.h5',
                                                save_best_only=True,
                                                save_weights_only=True,
                                                monitor='val_accuracy'),]


history = model.fit(x=train_dataset,
                    steps_per_epoch=train_num // batch_size,
                    epochs=epoch,
                    validation_data=val_dataset,
                    validation_steps=val_num // batch_size,
                    callbacks=callbacks)

#   loss accuracy   
history_dict = history.history
train_loss = history_dict['loss']
train_accuracy = history_dict['accuracy']
val_loss = history_dict['val_loss']
val_accuracy = history_dict['val_accuracy']

# figure 1
plt.figure()
plt.plot(range(epoch), train_loss, label='train_loss')
plt.plot(range(epoch), val_loss, label='val_loss')
plt.legend()    #     ,label
plt.xlabel('epochs')
plt.ylabel('loss')

# figure 2
plt.figure()
plt.plot(range(epoch), train_accuracy, label='accuracy')
plt.plot(range(epoch), val_accuracy, label='val_accuracy')
plt.legend()
plt.xlabel('epochs')
plt.ylabel('accuracy')

plt.show()

예측 과정: 여기서 주의해야 할 것은 만약에 하위 모델을 사용한다면 실례화할 때 반드시build를 해야 한다.build가 있어야 모델이 진정으로 실례화된다
"""  predict"""
from myAlextNet_Module import AlexNet
from PIL import Image
import numpy as np
import json
import matplotlib.pyplot as plt
import os
import tensorflow as tf
im_height = 224
im_width = 224
batch_size=16
# load image,      
img = Image.open('./159079265_d77a9ac920_n.jpg')
# resize image to 224x224
img = img.resize((im_width, im_height))
plt.imshow(img)

# scaling pixel value to (0-1)
img = np.array(img) / 255.

# Add the image to a batch where it's the only member.
img = (np.expand_dims(img, 0))


#   json    
try:
    json_file = open('./class_indices.json', 'r')
    class_indict = json.load(json_file)
except Exception as e:
    print(e)
    exit(-1)

#     
model = AlexNet(class_num=5)#         
model.build((batch_size,224,224,3))  #            

model.load_weights("./save_weights/myAlex.h5",)
predict = np.squeeze(model.predict(img))
predict_class = np.argmax(predict)
print(class_indict[str(predict_class)], predict[predict_class])
plt.show()

Note: 데이터 읽기 과정에서 tf를 사용합니다.data.keras 아래의 Image DataGenerator가 아닌 Dataset 생성기는 앞의 방법이 속도가 빠르다. 다중 스레드를 사용할 수 있기 때문에 네트워크 훈련 소모 시간에 CPU는 이미지 읽기와 예처리를 담당하고 GPU는 네트워크에 대한 훈련을 담당한다. Keras 데이터 생성기를 사용하면 데이터를 다중 스레드로 읽을 수 없다. GPU는 계산 시간이 매우 빠르고 대부분 시간에 데이터를 읽기 때문에 GPU의 이용률을 크게 낮춘다. 만약에 tf를 사용한다면.data.Dataset은 CPU 멀티스레드를 통해 데이터를 읽을 수 있으므로 GPU 활용도 향상

좋은 웹페이지 즐겨찾기