SW개발

Python tkinter를 활용한 tensorflow 자동 run 프로그램 만들기

초코쨔응 2019. 3. 6. 23:07

Python tkinter를 활용한 tensorflow 자동 run 프로그램 만들기


구현 목표


GUI로 tensorflow 스터디를 하면서 작성한 테스트용 모델을 돌릴 수 있게 구현해보고자 하였습니다. tensorflow 코드를 한 번 더 수정해보고 tkinter 사용법에 익숙해지고자 하였습니다. 이전에 작성한 tensorflow 테스트용 모델 코드는 다음의 링크에 있습니다. (https://computer-choco.tistory.com/77)



구현 결과물 - GUI


완성된 GUI의 모습은 다음과 같습니다. exe 파일로 변환하는 작업을 거치지 않았기 때문에 현재는 파이썬 스크립트를 돌려야만 다음의 화면을 띄울 수 있습니다.




구현 결과물 - Output File


이전에 사용된 테스트용 모델을 그대로 사용해서 정확도는 매우 낮습니다. test.csv와 train.csv (이 둘의 파일 이름은 상관없음) 을 받아서 동일한 폴더에 있는 submission.csv 라는 파일로 저장되게 합니다. 본 코드를 돌리기 위해서는 input 파일은 첫 번째 칼럼에 target label이 들어오고, 나머지 칼럼들이 input data  칼럼이어야 합니다. 그러면 모델이 예측하는 결과는 submission.csv 에 첫 번째 칼럼에 행의 id, 두번째 칼럼에 예측한 target label이 나옵니다.


# submission.csv



사용된 Python 코드


위의 GUI를 얻기 위해서는 tkinter_test.py를 돌리면 되고, 테스트용 모델의 이름인 tensorflow_model_sample의 mymodel이라는 함수를 import해서 사용하였습니다.


# tkinter_test.py

from tkinter import *

from tkinter import filedialog

from tensorflow_model_sample import mymodel


# tkinter 인스턴스 생성

window = Tk()

window.title("My tensorflow app")

window.configure(background='black')


# train 파일과 test 파일을 불러오기 위한 버튼 액션

def fileopen():

    global train_url, check

    train_url = filedialog.askopenfilename()

    print(train_url)


def fileopen2():

    global train_url, test_url, check

    test_url = filedialog.askopenfilename()

    print(test_url)

    mymodel(train_url, test_url)


# 필요한 텍스트 및 버튼 구현

lbl = Label(window, text="Tensorflow", font=("Arial Bold", 50), bg='black', fg="#ffffff")

lbl.grid(column=0, row=0)

lbl = Label(window, text="", bg='black')

lbl.grid(column=0, row=1)


btn = Button(window, text="Training File", command=fileopen, bg="black", fg='white')

btn.grid(column=0, row=2)

lbl = Label(window, text="", bg='black')

lbl.grid(column=0, row=3)


btn = Button(window, text="Testing File", command=fileopen2, bg='black', fg='white')

btn.grid(column=0, row=4)

lbl = Label(window, text="", bg='black')

lbl.grid(column=0, row=5)


window.mainloop()


# tensorflow_model_sample.py

def mymodel(train_url, test_url):

    

    print("---setting configurations---")

    import tensorflow as tf

    import csv

    

    # 데이터 로드

    train_data = []

    train_label = []

    with open(train_url, 'r') as csvfile:

        csvreader = csv.reader(csvfile)

        next(csvreader) # header jump

        for row in csvreader:

            line = list(map(int, row))

            train_label.append(line[0])

            train_data.append(line[1:])

        

    # 퍼셉트론 입력 크기, 클래스 수, 배치 크기, 반복 또는 배치의 총 개수 선언

    input_size = len(train_data[0])

    no_classes = len(set(train_label))

    batch_size = 100

    total_batches = 200


    # 원-핫 인코딩

    train_label_hot = []

    for row in train_label:

        for num in range(no_classes):

            if row == num:

                one_hot = [0]*no_classes

                one_hot[num] = 1

                train_label_hot.append(one_hot)


    # 입력데이터와 타깃을 위한 플레이스홀더 정의 (None은 어떤 크기든 될 수 있음을 의미)

    x_input = tf.placeholder(tf.float32, shape=[None, input_size])

    y_input = tf.placeholder(tf.float32, shape=[None, no_classes])


    # 단순한 선형 분류자 또는 퍼셉트론을 정의

    weights = tf.Variable(tf.random_normal([input_size, no_classes]))

    bias = tf.Variable(tf.random_normal([no_classes]))

    logits = tf.matmul(x_input, weights) + bias


    # 퍼셉트론으로 생성된 로짓과 원-핫 레비을의 y_input을 비교

    # 비교는 교차 엔트로피와 함께 소프트맥스를 사용

    softmax_cross_entropy = tf.nn.softmax_cross_entropy_with_logits(

        labels=y_input, logits=logits)

    loss_operation = tf.reduce_mean(softmax_cross_entropy)

    optimiser = tf.train.GradientDescentOptimizer(

        learning_rate=0.5).minimize(loss_operation)


    # 모델 훈련을 위한 세션 시작

    session = tf.Session()


    # 전역 변수 초기화 함수를 이용해 변수를 초기화

    print("---run model---")

    session.run(tf.global_variables_initializer())

    _, loss_value = session.run([optimiser, loss_operation], feed_dict={

        x_input: train_data,

        y_input: train_label_hot

    })

    print("loss: ", loss_value)


    # test 데이터 불러오기

    # 데이터 로드

    test_data = []

    with open(test_url, 'r') as csvfile:

        csvreader = csv.reader(csvfile)

        next(csvreader) # header jump

        for row in csvreader:

            test_data.append(list(map(int, row)))

        

    # 정확도를 계산

    predictions = tf.argmax(logits, 1)

    test_label = session.run([predictions], feed_dict={

        x_input: test_data

    })

    print("----saving data----")

    save_url = test_url.split('/')[:-1]

    with open('/'.join(save_url)+'/submission.csv', mode='w', newline='\n') as csvfile:

        tensor_result = csv.writer(csvfile, delimiter=',')

        tensor_result.writerow(['ImageId', 'Label'])

        for line in range(len(test_label[0])):

            tensor_result.writerow([str(line+1), str(test_label[0][line])])


    session.close()

    print("---session closed---")


본 코드는 다음의 주소에 업로드 되어있습니다.

https://github.com/BY1994/TIL/blob/master/Python/SWdevelopment/tkinter_test.py

https://github.com/BY1994/TIL/blob/master/Python/SWdevelopment/tensorflow_model_sample.py

반응형