[텐서플로우] 소프트맥스 회귀 (Softmax Regression) 분류 파이썬 코드

2020. 4. 20. 15:41노트/Python : 프로그래밍

예제 데이터 

x_data = [[1, 2, 1, 1],
          [2, 1, 3, 2],
          [3, 1, 3, 4],
          [4, 1, 5, 5],
          [1, 7, 5, 5],
          [1, 2, 5, 6],
          [1, 6, 6, 6],
          [1, 7, 7, 7]]
y_data = [[0, 0, 1], #원핫인코딩 상태 
          [0, 0, 1],
          [0, 0, 1],
          [0, 1, 0],
          [0, 1, 0],
          [0, 1, 0],
          [1, 0, 0],
          [1, 0, 0]]

 

변수정의 

x= tf.placeholder("float",shape=[None,4])
y= tf.placeholder("float",shape=[None,3])
#3: 분류기의 갯수 (분류 결과 종료의 가짓수)
nb_classes = 3

w=tf.Variable(tf.random_normal([4,3]))
b=tf.Variable(tf.random_normal([3]))

 

모델생성 

hf = tf.nn.softmax((tf.matmul(x,w)+b)) #nn:neural network

cost = tf.reduce_mean( - tf.reduce_sum(y * tf.log(hf) ,axis=1 ))

#모델 생성 
opt =tf.train.GradientDescentOptimizer(0.1).minimize(cost)

 

  • 가설함수 

    $h(x) = { exp^(x_i)  \over \sum_{k=1}^k exp^(x_k) } $
  • 비용함수

    $ -\sum L_i log(S_i)   = - \sum L_i log (\hat{y_i}) = \sum L_i * -log( \hat{y_i}) $ 

 

모델실행

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for step in range(10001):
        _, cv=sess.run([opt,cost], feed_dict={x:x_data, y:y_data})
        if step %1000==0:
            print(step, cv)
    sess.run(hf, feed_dict={x:xdata_new})
 >>>
 0 8.378195
1000 0.2563542
2000 0.16243793
3000 0.11930026
4000 0.09385648
5000 0.07717404
6000 0.0654327
7000 0.056738954
8000 0.050052278
9000 0.044754907
10000 0.040457852

 

모델사용(예측)

xdata_new=[1,11,7,9] 

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for step in range(10001):
        _, cv=sess.run([opt,cost], feed_dict={x:x_data, y:y_data})
        if step %1000==0:
            print(step, cv)
    hfv= sess.run(hf, feed_dict={x:[xdata_new]})
    print(hfv.round(2))
    print("분류 결과: ", sess.run(tf.argmax(hfv,1))) # 가장 높은 확률의 인덱스값 호출
    
 >>>
 0 16.311272
1000 0.23644683
2000 0.15405312
3000 0.11362037
4000 0.089741796
5000 0.07404409
6000 0.06296378
7000 0.054736644
8000 0.048392136
9000 0.04335375
10000 0.03925748
[[0. 1. 0.]]
분류 결과:  [1]
xdata_new2=  [[1,11,7,9],[1,3,4,3],[1,1,0,1]]

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for step in range(10001):
        _, cv=sess.run([opt,cost], feed_dict={x:x_data, y:y_data})
        if step %1000==0:
            print(step, cv)
    hfv= sess.run(hf, feed_dict={x:xdata_new2})
    print(hfv.round(2))
    print("분류 결과: ", sess.run(tf.argmax(hfv,1))) # 가장 높은 확률의 인덱스값 호출 
    
 >>>
 0 8.725246
1000 0.22939917
2000 0.15135157
3000 0.11245334
4000 0.08920952
5000 0.073807895
6000 0.0628777
7000 0.05473045
8000 0.04842999
9000 0.04341583
10000 0.03933265
[[0.   1.   0.  ]
 [0.99 0.01 0.  ]
 [0.   0.   1.  ]]
분류 결과:  [1 0 2]

 

모델 비교

2020/04/14 - [노트/Python : 프로그래밍] - [텐서플로우] 선형회귀분석(Linear Regression) 기본 구조 파이썬 코드

2020/04/16 - [노트/Python : 프로그래밍] - [텐서플로우] 로지스틱 회귀(Logistic Regression) 분류 파이썬 코드

2020/04/17 - [노트/Python : 프로그래밍] - [텐서플로우] 다중회귀분석 (Multi-variable Linear Regression) 파이썬 코드

2020/04/18 - [노트/Python : 프로그래밍] - [텐서플로우] 다중 선형 회귀를 이용한 당뇨병 분류기 파이썬 코드

 

 

 


 

IRIS 데이터 분류하기 

Iris 품종을 'setosa','versicolor','virginica로 분류해보고자한다. 

 

 

 

 

 

 

데이터 

 

iris.csv
0.00MB
iris_softmax.csv
0.00MB

 

import pandas as pd
path = "C:\\Users\\student\\Desktop\\DY\\★ 데이터\\105. deep-learning-dataset\\"

test=pd.read_csv(path+"iris.csv")
train=pd.read_csv(path+"iris_softmax.csv",header=None)

 

원핫인코더가 되어있는 iris_softmax 데이터를 트레이닝 데이터로 쓰고, iris 데이터를 테스트데이터로 사용 

 

 

변수 및 함수 정의 

from sklearn.preprocessing import LabelEncoder

def genToInt(data):
    data['Species']=LabelEncoder().fit(['setosa','versicolor','virginica']).transform(data['Species'])
    return data

testCopy = genToInt(test)

xtrain=train.iloc[:,1:5]
ytrain=train.iloc[:,5:8]

xtest=test.iloc[:,1:5]
ytest=test.iloc[:,5:8]

x 종속변수(입력 값), y 독립변수 (출력 값) 설정 

nb_classes = 3
x= tf.placeholder("float",shape=[None,4])
y= tf.placeholder("float",shape=[None,nb_classes])
#3: 분류기의 갯수 (분류 결과 종료의 가짓수)

w=tf.Variable(tf.random_normal([4,nb_classes]))
b=tf.Variable(tf.random_normal([nb_classes]))

hf = tf.nn.softmax((tf.matmul(x,w)+b)) #nn:neural network

cost = tf.reduce_mean( - tf.reduce_sum(y * tf.log(hf) ,axis=1 ))

가설함수, 비용함수 정의 

 

모델생성 

#모델 생성 
opt =tf.train.GradientDescentOptimizer(0.1).minimize(cost)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for step in range(10001):
        _, cv=sess.run([opt,cost], feed_dict={x:xtrain, y:ytrain})
        if step %1000==0:
            print(step, cv)
    hfv=sess.run(hf, feed_dict={x:xtest})
    res=sess.run(tf.argmax(hfv,1))
    print("분류결과:",res) # 가장 높은 확률의 인덱스값 호출 

>>>
0 6.2653365
1000 0.12287375
2000 0.09537465
3000 0.08398995
4000 0.07744726
5000 0.07307746
6000 0.06989237
7000 0.067433916
8000 0.065458186
9000 0.06382228
10000 0.06243634
분류결과: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1
 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

tf.argmax( hfv값중 가장 높은 값의 위치를 호출 (0인지 1인지 2인지)

 

정확도 측정 

actual=ytest.Species
predict=res

isCorrect = tf.equal(actual , predict)
accuracy = tf.reduce_mean(tf.cast(isCorrect , tf.float32 ))

with tf.Session() as sess:
    av=sess.run(accuracy)
    print("정확도:",av)
    
>>> 정확도: 0.97333336