조이 생각

반응형

( ※ 본 포스팅은 저자 개인의 한정적인 지식을 바탕으로 쓰여진 글입니다. 내용의 오류나, 오타 등을 언제든지 알려주시면 감사하겠습니다.)



파이썬(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
= tf.placeholder(tf.float32, shape=[None, features], name='x')
= tf.placeholder(tf.float32, shape=[None, 1], name='y')
 
# Set model weights
= tf.Variable(tf.random_normal([features, 1],dtype='float'), name='weight')
= tf.Variable(tf.random_normal([1],dtype='float'), name='bias')
 
# Construct a linear model
hypothesis = tf.matmul(X, W) + b
= 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
(194) (191) ==> 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]
1.  1.  0.  0.==>  [ 99.11267853]Colored by Color Scripter

cs




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




읽어주셔서 감사합니다. : )





반응형

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band
loading