머신러닝

1-6 활성화 함수 Softmax에 의한 XOR 예제 TensorFlow 코딩

coding art 2020. 1. 10. 17:32
728x90

Sigmoid 활성화 함수 대신 Softmax를 사용하여 XOR 예제를 TensorFlow 로 코딩 처리해 보자. Sigmoid 활성화 함수를 사용할 때 생성된 입력 좌표 점들의 수를 pts 라 할 때 해당하는 라벨 데이터의 shape 값이 (pts, 1)이지만 Softmax를 사용할 때는 (pts, 2)인 점이 달라진다. 아래의 코드는 Sigmoid 활성화 함수를 사용할 경우에 해당한다. y_xor 의 값이 “0” 또는 “1”이 된다.



따라서 TensorFlow 코드 헤더 영역에 들어서서 새로이 변수 Y_xor을 도입하여 y_xor “0” 또는 “1”에 대응하여 “10”“01” 로 초기화 한다. 이때에 리스트형 데이터를 사용해야 함에 주의하자. 읽어 들이기 전까지는 파이선 또는NumPy 데이터이지만 읽은 후에는 Tensor가 됨에 유의하자.

한편 random.randn() 명령에 의해 생성된 X_xor 데이터는 float64이므로 다시 float32 로 재정의 하도록 하자. 마찬가지로 y_xor 데이타도 int32 이지만 다시 float32 로 재정의 한다.



Placeholder 정의에서도 라벨 값 입력을 위한 텐서 YSigmoid 함수 사용 시 [None, 1] 이었지만 Softmax 사용 시에는 [None, 2] 로 처리해야 함에 유의하자




다항식 기법을 사용하기 위한 Hypothesis 는 학습과정 및 그래픽 처리과정에서 중복하여 불러 쓸 수 있도록 함수형태로 처리하도록 한다. Softmax 형태의 활성화 함수를 사용하는 Cross Entropy cost 함수를 설정한다. OptimizerGradientDescent 사용 시에는 learning_rate=0.001, Adam Optimizer 경우에는 learning_rate=0.0001을 사용하도록 한다.

아울러 tf.cast 명령 사용에서 hypothesis 의 첫 번째 비트 값만 사용하여 0.5 이하이면 즉 0.0 이므로 자동적으로 두 번째 비트가 1이 된다. “01”이므로 참(True)이 된다. 반대로 첫 번째 비트 값이 0.5 이상이면 즉 1.0 이면 “10”이므로 거짓(False)이 된다. 이렇게 처리하면 shape 값이 (pts, 2)에서 (pts, 1)이 된다.

그렇게 생성된 Graph 상의 predicted를 생성하면 Sigmoid 활성화 함수를 사용한 tf_plot_decision_regions 루틴을 그대로 쓸 수 있는 이점이 있다.    




다음의 결과를 비교해 보자.


SVC 와 다항식(Adam)기법을 비교해 보기 위해서 원점을 중심으로 확대한 결과를 비교해 보자. 오른쪽의 검은색 박스 친 부분이 hyperplane을 중심으로 SVC 에서는 maximum margin 처리가 되었으나 다항식(Adam)기법에서는 maximum margin 처리 알고리듬이 적용되지 않았으므로 처리되지 못한 상황을 보여 준다.


SVC 루틴에서는 학습 횟수를 조절할 수 있는 파라메터가 없으나 TensorFlow 코드에서는 학습 횟수 조절이 가능하므로 20,000에서 50,000으로 변경한 결과를 관찰해보자. SVC에서 misclassification 3개의 샘플 중 2개가 제대로 처리되고 1개가 misclassification 되었음을 관찰할 수 있다.



#SVM_softmax_01.py


from sklearn import __version__ as sklearn_version
from sklearn import datasets
import numpy as np
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
from sklearn.svm import SVC


def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.01):

    # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # plot the decision surface
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    #print(x1_min.shape)
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
    #print('xx1,xx2=',xx1,xx2)
    P=np.array([xx1.ravel(), xx2.ravel()])
    #print('P=',P.T)
    #print(classifier)
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    #print('Z.shape=',Z.shape)
    #print('Z=',Z)
    Z = Z.reshape(xx1.shape)
    #print('Z.reshape',Z)
    plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
    plt.grid(True)
    plt.xlim(xx1.min()+2, xx1.max()-2)
    plt.ylim(xx2.min()+2, xx2.max()-2)

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0],
                    y=X[y == cl, 1],
                    alpha=0.8,
                    c=colors[idx],
                    marker=markers[idx],
                    label=cl,
                    edgecolor='black')

    # highlight test samples
    if test_idx:
        # plot all samples
        X_test, y_test = X[test_idx, :], y[test_idx]

        plt.scatter(X_test[:, 0],
                    X_test[:, 1],
                    c='',
                    edgecolor='black',
                    alpha=1.0,
                    linewidth=1,
                    marker='o',
                    s=100,
                    label='test set')


np.random.seed(1)

pts = 200  # total number of random points
X_xor = np.random.randn(pts, 2)
y_xor = np.logical_xor(X_xor[:, 0] > 0, X_xor[:, 1] > 0)
#print(y_xor)
y_xor = np.where(y_xor, 1, 0)
#print(y_xor)

#print(X_xor.shape)
#print(y_xor.shape)

plt.scatter(X_xor[y_xor == 1, 0], X_xor[y_xor == 1, 1],
            c='b', marker='x', label='1')
plt.scatter(X_xor[y_xor == 0, 0], X_xor[y_xor == 0, 1],
            c='r', marker='s', label='0')

plt.xlim([-3, 3])
plt.ylim([-3, 3])
plt.legend(loc='best')
plt.tight_layout()
plt.show()

#Support Vector Machine "RBF"
svm = SVC(kernel='rbf', random_state=1, gamma=1.0, C=10.0)
svm.fit(X_xor, y_xor)
plot_decision_regions(X_xor, y_xor,classifier=svm)

plt.legend(loc='upper left')
plt.tight_layout()
plt.show()

#Following is method to convert numpy array to tensor
import tensorflow as tf
import time

start_time = time.time()

def fn(X,W1,b1,W2,b2):
    print(X.shape)
    hypothesis =  tf.nn.softmax((tf.matmul(X, W2) + b2)*(tf.matmul(X, W1) + b1))
    return hypothesis


def tf_plot_decision_regions(X_xor, y, hypothesis, predicted, test_idx=None, resolution=0.01):
   
    # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])
    # plot the decision surface
    x1_min, x1_max = X_xor[:, 0].min() - 1, X_xor[:, 0].max() + 1
    x2_min, x2_max = X_xor[:, 1].min() - 1, X_xor[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
    print(xx1.shape)
    XX = np.array([xx1.ravel(), xx2.ravel()]).T
    #print(XX.shape)
    h, p = sess.run([hypothesis, predicted], feed_dict={X: XX })

    #print(p)
    p = p.reshape(xx1.shape)
    plt.contourf(xx1, xx2, p, alpha=0.3, cmap=cmap)
    plt.grid(True)
    plt.xlim(xx1.min()+2, xx1.max()-2)
    plt.ylim(xx2.min()+2, xx2.max()-2)

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X_xor[y == cl, 0],
                    y=X_xor[y == cl, 1],
                    alpha=0.8,
                    c=colors[idx],
                    marker=markers[idx],
                    label=cl,
                    edgecolor='black')

    # highlight test samples
    if test_idx:
        # plot all samples
        X_test, y_test = X_xor[test_idx, :], y[test_idx]

        plt.scatter(X_test[:, 0],
                    X_test[:, 1],
                    c='',
                    edgecolor='black',
                    alpha=1.0,
                    linewidth=1,
                    marker='o',
                    s=100,
                    label='test set')


#Training Data

Y_xor = np.zeros([pts,2])

Y_xor[y_xor == 0] = [1., 0.]
Y_xor[y_xor == 1] = [0., 1.]
#print(Y_xor)

X_xor = np.float32(X_xor)
Y_xor = np.float32(Y_xor)
#print(Y_xor)

#print(X_xor.shape)
#print(Y_xor.shape)

#hyperparameter
learning_rate = 0.0001
training_epochs = 20000
display_steps = 10000

#Network parameters
n_input = 2
dof1 = 2
#Graph Nodes
X = tf.placeholder("float", [None, n_input])
Y = tf.placeholder("float", [None, dof1])

#Weights and Biases, model, loss and optimizer
W1 = tf.Variable(tf.random_normal([n_input, dof1], stddev=0.01))
b1 = tf.Variable(tf.random_normal([dof1], stddev=0.01))
W2 = tf.Variable(tf.random_normal([n_input, dof1], stddev=0.01))
b2 = tf.Variable(tf.random_normal([dof1], stddev=0.01))

#hypothesis =  tf.nn.softmax((tf.matmul(X, W2) + b2)*(tf.matmul(X, W1) + b1))
hypothesis = fn(X,W1,b1,W2,b2)

# cost/loss function
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits
                      (logits=hypothesis, labels=Y))

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(cost)
#optimizer = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(cost)

predicted = tf.cast(hypothesis[:, 0] < 0.5, dtype=tf.float32)
print(predicted.shape)

#predicted =  tf.cast(hypothesis > 0.5, dtype=tf.float32)

accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(hypothesis,1), tf.argmax(Y,1)), dtype=tf.float32))

#Initializing global variables
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
   
    for epoch in range(training_epochs):
        _, c, w1, B1, w2, B2 = sess.run([optimizer, cost, W1, b1, W2, b2], feed_dict={X: X_xor, Y: Y_xor})
        #if(epoch + 1) % display_steps == 0:
            #print( "Epoch: ", (epoch+1), "Cost: ", c, w1, B1, w2, B2 )
    print("Optimization Finished!")

    # Accuracy report
    h, p, a = sess.run([hypothesis, predicted, accuracy],feed_dict={X: X_xor, Y: Y_xor})

    #print("\nHypothesis:\n", h, "\nCorrect:\n", p, "\nAccuracy: ", a)
    #print(p.shape)
    p = p.reshape(pts,1)
    #print(p)
    tf_plot_decision_regions(X_xor, y_xor, hypothesis, predicted)
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()


sess.close()

end_time = time.time()
print( "\nCompleted in ", end_time - start_time , " seconds")