( ※ 본 포스팅은 저자 개인의 한정적인 지식을 바탕으로 쓰여진 글입니다. 내용의 오류나, 오타 등을 언제든지 알려주시면 감사하겠습니다.)
파이썬(python)에서 텐서플로우(TensorFlow)를 이용해 학습한 모델을 자바에서도 사용할 수 있습니다.
언제부터인지는 정확히 모르지만, 안드로이드에서도 텐서플로우를 사용해서 어플리케이션을 만들 수 있는 것 같아요.
정말 인공지능 서비스가 빠르게 확산될 것 같습니다...
이번에는 파이썬으로 간단한 신경망을 구현하고 학습시킨 모델을 저장하고
자바에서 불러와 사용해 보려고 합니다.
실행환경
- OS : 윈도우7 (Windows 7 64bit)
- 아나콘다 (Anaconda 4.4.0 64-bit)
- 이클립스 (Eclipse Jee Oxygen)
- 파이썬 (python 3.6.1)
- 자바 (Java 1.8.0)
- 텐서플로우 (TensorFlow 1.4.0)
1. 파이썬 신경망 학습 및 모델 저장
먼저 파이썬에서 신경망을 구현해야겠죠?
회기분석(Regression)을 간단한 NN(neural network)로 구현해 보았습니다.
python 코드는 아래와 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import tensorflow as tf import numpy as np tf.set_random_seed(777)# for reproducibility # Parameters learning_rate = 0.3 training_epochs = 500 # real data data = np.loadtxt('./data/train.csv', delimiter=',', dtype=str).astype(np.float32) input = data[:,:-1] output = data[:,-1].reshape([len(data),1]) features = input.shape[1] test_data = np.loadtxt('./data/test.csv', delimiter=',', dtype=str).astype(np.float32) test_data = test_data.reshape([-1, features]) # make uniform shape print (input.shape, output.shape) # placeholders for train X = tf.placeholder(tf.float32, shape=[None, features], name='x') Y = tf.placeholder(tf.float32, shape=[None, 1], name='y') # Set model weights W = tf.Variable(tf.random_normal([features, 1],dtype='float'), name='weight') b = tf.Variable(tf.random_normal([1],dtype='float'), name='bias') # Construct a linear model hypothesis = tf.matmul(X, W) + b h = tf.identity(hypothesis, name='h') # Mean squared error cost = tf.reduce_mean(tf.square(hypothesis - Y)) # accuracy acc = tf.equal(tf.round(hypothesis), Y) acc = tf.reduce_mean(tf.cast(acc, tf.float32)) # Minimize optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate) train = optimizer.minimize(cost) # Launch the graph in a session. sess = tf.Session() # Initializes global variables in the graph. sess.run(tf.global_variables_initializer()) for step in range(training_epochs): sess.run(train, feed_dict={X: input, Y: output}) if(step%100==0): cost_val, hy_val = sess.run([cost, hypothesis], feed_dict={X: input, Y: output}) if step==0: print("[",step+1,"] Cost:", cost_val) else: print("[",step,"] Cost:", cost_val) print("=============TRAIN END==============") for i in range(len(data)): hy_val = sess.run(hypothesis, feed_dict={X: input[i,:].reshape([1,features])}) print(" Answer:", output[i], " Prediction:", round(hy_val[0,0])) cost_val, acc_val = sess.run([cost,acc], feed_dict={X: input, Y: output}) print(" Cost:", cost) print(" Acc:", acc_val) print("=============PREDICT==============") for i in range(test_data.shape[0]): pre = sess.run(hypothesis, feed_dict={X: test_data[i].reshape(1,features)}) print(test_data[i],"==> ", pre[0]) builder = tf.saved_model.builder.SavedModelBuilder("/tmp/fromPython") builder.add_meta_graph_and_variables(sess,[tf.saved_model.tag_constants.SERVING]) builder.save() | cs |
임의로 생성한 데이터를 500 epoch 학습 시킨 모델 이며,
C:/tmp/fromPython 파일 위치에 학습된 모델이 저장 됩니다.
실행 후 아래와 같이 출력됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | (19, 4) (19, 1) ==> input, output 데이터 shape [ 1 ] Cost: 737.868 ==> 학습 과정에서 cost 값 [ 100 ] Cost: 1.91863 [ 200 ] Cost: 1.91846 [ 300 ] Cost: 1.91846 [ 400 ] Cost: 1.91846 =============TRAIN END============== ==> 학습 완료 후 학습했던 데이터를 넣어봄 Answer: [ 75.] Prediction: 74.0 ==> 실제 정답과 모델 예측 결과 Answer: [ 75.] Prediction: 75.0 Answer: [ 100.] Prediction: 99.0 Answer: [ 100.] Prediction: 99.0 Answer: [ 99.] Prediction: 99.0 Answer: [ 95.] Prediction: 99.0 Answer: [ 76.] Prediction: 75.0 Answer: [ 25.] Prediction: 26.0 Answer: [ 0.] Prediction: 1.0 Answer: [ 3.] Prediction: 1.0 Answer: [ 25.] Prediction: 26.0 Answer: [ 25.] Prediction: 24.0 Answer: [ 0.] Prediction: 1.0 Answer: [ 24.] Prediction: 24.0 Answer: [ 23.] Prediction: 24.0 Answer: [ 50.] Prediction: 50.0 Answer: [ 50.] Prediction: 50.0 Answer: [ 52.] Prediction: 50.0 Answer: [ 51.] Prediction: 50.0 Cost: Tensor("Mean:0", shape=(), dtype=float32) Acc: 0.263158 =============PREDICT============== ==> 임의의 데이터 넣어 출력해봄 [ 1. 0. 0. 0.] ==> [ 74.21125793] [ 0. 1. 0. 0.] ==> [ 74.7183075] [ 1. 1. 0. 0.] ==> [ 99.11267853] [ 1. 1. 0. 0.] ==> [ 99.11267853] |
2. Java 에서 python 모델 사용
이클립스 환경에 tensorflow를 사용할 수 있도록 셋팅 되어있는 상태에서 시작하겠습니다.
(혹시 세팅이 되어있지 않은 분들은 아래 포스팅을 참고하시기 바랍니다.)
2017/12/11 - [TensorFlow] - 텐서플로우(TensorFlow) 자바(Java) 설치 및 실행방법
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public static void main(String[] args) throws IOException{ System.out.println("TensorFlow version : "+TensorFlow.version()); String filePath = "./data/test.csv"; //get shape of data getDataSize(filePath); System.out.print("[number of row] ==> "+ ROW); System.out.println(" / [number of feature] ==> "+ FEATURE); float[][] testInput = new float[ROW][FEATURE]; //insert csv data to matrix csvToMtrx(filePath, testInput); printMatrix(testInput); //load the model bundle try(SavedModelBundle b = SavedModelBundle.load("/tmp/fromPython", "serve")){ //create a session from the Bundle Session sess = b.session(); //create an input Tensor Tensor x = Tensor.create(testInput); //run the model and get the result float[][] y = sess.runner() .feed("x", x) .fetch("h") .run() .get(0) .copyTo(new float[ROW][1]); //print out the result for(int i=0; i<y.length;i++) System.out.println(y[i][0]); } } | cs |
정확히 이해한게 맞는지는 모르겠지만,
제 이해 기준으로 잠시 코드를 간략히? 설명하고 넘어가겠습니다.
(* 데이터 및 전체 코드는 맨 아래 github 주소에 들어가시면 확인하실 수 있습니다.)
line 2 : tensorflow의 버전 출력
line 7 : 파일 경로를 getDataSize() 파라미터로 전달하는 메소드를 이용해 데이터의 행, 열 길이를 구함 (여기서 행 = ROW, 열 = FEATURE 전역변수를 사용했습니다.)
line 10 : 데이터를 담기 위한 ROW, FEATURE 크기의 배열 생성
line 13 : csvToMtrx() 메소드로 데이터를 배열에 담음
line 14 : 확인용 배열 데이터 출력 메소드 printMatrix() 호출
line 17 : 저장된 모델을 로드
line 20 : session 생성
line 23 : 데이터를 담고 있는 2차원 배열로 Tensor 생성
line 26 : 학습 모델의 결과를 담을 배열 생성, 세션 실행
line 27 : tensorflow의 feed_dict와 같이 python 에서 name='x'로 정해준 변수에 line 23에서 생성한 Tensor x를 feed
line 28 : python에서 name='h'로 정해준 연산에 적용
line 29,30 : 실행, 결과 가져옴
line 31 : 결과를 [ROW,1] 크기 배열에 넣음
자바 실행 결과는 다음과 같이 나오게 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | TensorFlow version : 1.4.0 [number of row] ==> 5 / [number of feature] ==> 4 ============ARRAY VALUES============ [[1.0][0.0][0.0][0.0] [0.0][1.0][0.0][0.0] [1.0][1.0][0.0][0.0] [1.0][1.0][0.0][0.0] [1.0][1.0][0.0][0.0]] [1.0,0.0,0.0,0.0] ==> 74.21125793457031 [0.0,1.0,0.0,0.0] ==> 74.71830749511719 [1.0,1.0,0.0,0.0] ==> 99.11267852783203 [1.0,1.0,0.0,0.0] ==> 99.11267852783203 [1.0,1.0,0.0,0.0] ==> 99.11267852783203 | cs |
3. Python, Java 결과 비교
같은 결과를 확인할 수 있습니다.
처음에 자바에서 시도했을 때 결과가 다르게 나왔었는데...
원인은 파이썬과 자바에서 사용하는 연산명의 설정을 잘못해주었기 때문 이었습니다.
간단한 예제로 학습된 신경망 모델을 자바에서 실행시켜보았습니다.
도움이 되셨기 바랍니다.
데이터와 소스코드 풀 버전은 아래 링크에 있습니다.
https://github.com/joyspark/TensorFlow
읽어주셔서 감사합니다. : )
텐서플로우 inter_op_parallelism_threads (2) | 2019.08.09 |
---|---|
윈도우에서 텐서플로우 원하는 버전 설치방법 (0) | 2018.08.17 |
텐서플로우(TensorFlow) 예제코드와 머신러닝(Machine Learning)학습 개념 (2) | 2018.01.31 |
텐서플로우 Java 실행 방법 (0) | 2017.12.11 |
텐서플로우 윈도우즈 설치 방법 (0) | 2017.12.06 |