이전부터 간단한 머신러닝 기법(Decision tree, Random forest, XGBoost, ..)은 활용할 수 있었지만, 딥러닝을 공부해보고 싶은 욕심에 조금 더 다양하고 기본이 되는 알고리즘을 공부해보고 있습니다. 이를 위해 한국어 글로는 조대협님의 블로그 글을 읽고 좀 더 자세한 정보를 위해서는 Andrew Ng의 Machine learning 강의를 보면서 Machine learning을 공부하고 있습니다.

Logistic regression 알고리즘은 classification에서 쉽게 사용할 수 있는 알고리즘이지만 위 블로그의 글에 tensorflow를 이용해서 구현해본 예제가 없어서(Linear regression은 있습니다.) jupyter로 구현한 코드를 포스팅합니다.

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

normalize

s = np.random.normal(loc=0, scale=1.0, size=1000)
_ = plt.hist(s, 30, normed=True)

_ = plt.hist(np.abs(s), normed=True)

데이터를 가정해봅니다.

zs = np.array([[10 - np.random.rand() * 2, 0] for _ in range(10)])
os = np.array([[np.random.rand() * 2 + 10, 1] for _ in range(10)])
plt.plot(zs[:, 0], zs[:, 1], 'ro')
plt.plot(os[:, 0], os[:, 1], 'g^')

Sigmoid

xs = np.array(range(-20, 20))
sigmoid = lambda xs: 1 / (1 + np.exp(-1 * xs))
plt.plot(xs, sigmoid(xs))

g(z)를 sigmod함수라 가정하면,

가정(hypothesis) 함수는 아래와 같이 표현된다.

위 데이터의 경우에는 W = 1, b = -2로 가정합니다.

plt.plot(zs[:, 0], zs[:, 1], 'ro')
plt.plot(os[:, 0], os[:, 1], 'g^')
plt.plot(xs, sigmoid(xs - 10))
plt.xlim(5, 15)
(5, 15)

cost function

if y = 1, cost function is

w = np.arange(0, 1, step=0.01)
f = lambda _w: np.sum(-np.log2(sigmoid(_w * os[:, 0] - 10))) / len(os)
vf = np.vectorize(f)
cost = vf(w)
plt.plot(w, cost)

else if y = 0, cost function is

w = np.arange(0, 1, step=0.01)
f = lambda _w: np.sum(-np.log2(1 - sigmoid(_w * zs[:, 0] - 10))) / len(zs)
vf = np.vectorize(f)
cost = vf(w)
plt.plot(w, cost)

따라서 cost function은,

w = np.arange(0, 2, step=0.1)
orgs = np.concatenate((os, zs), axis=0)
f = lambda _w: np.sum(
    -orgs[:, 1] * np.log2(sigmoid(_w * orgs[:, 0] - 10)) - \
    (1 - orgs[:, 1]) * np.log2(1 - sigmoid(_w * orgs[:, 0] - 10))
) / orgs.size
cost_vf = np.vectorize(f)
cost = cost_vf(w)
plt.plot(w, cost)

요소가 다양한경우

요소로 정의된 x가 다수일때,

위의 예제 데이터에 반영해보기 위해서 theta값을 정의해보면

n_random = lambda: np.abs(np.random.normal(loc=0, scale=5))

zs = np.array([(n_random(), n_random()) for _ in range(100)])
os = np.array([(20 - n_random(), 20 - n_random()) for _ in range(100)])
plt.plot(zs[:, 0], zs[:, 1], 'ro')
plt.plot(os[:, 0], os[:, 1], 'g^')

bound_x = np.array(range(20))
plt.plot(bound_x, -1 * bound_x + 20)
plt.plot(zs[:, 0], zs[:, 1], 'ro')
plt.plot(os[:, 0], os[:, 1], 'g^')

cost function

w = np.arange(-2, 0.89, step=0.001)
_os = np.zeros((len(os), 3))
_os[:, :-1] = os
_zs = np.ones((len(zs), 3))
_zs[:, :-1] = zs

orgs = np.concatenate((_os, _zs), axis=0)
f = lambda _w: np.sum(
    -orgs[:, 2] * np.log2(sigmoid(_w * orgs[:, 0] + _w * orgs[:, 1])) - \
    (1 - orgs[:, 2]) * np.log2(1 - sigmoid(_w * orgs[:, 0]  + _w * orgs[:, 1]))
) / len(orgs)
cost_vf = np.vectorize(f)
cost = cost_vf(w)
plt.plot(w, cost)

tensorflow로 cost function 구하기

import tensorflow as tf
from tensorflow import Variable
w1 = Variable(tf.random_uniform(shape=[1], minval=-1, maxval=1), name="weight1")
w2 = Variable(tf.random_uniform(shape=[1], minval=-1, maxval=1), name="weight2")
b = Variable(tf.zeros(shape=[1]), name="biases")
# hypothesis linear regression

t_sigmoid = lambda xs: 1 / (1 + tf.exp(-1 * xs))
dy = -orgs[:, 2] * tf.log(t_sigmoid(w1 * orgs[:, 0] + w2 * orgs[:, 1] + b)) - \
    (1 - orgs[:, 2]) * tf.log(1 - t_sigmoid(w1 * orgs[:, 0] + w2 * orgs[:, 1] + b))
delta = tf.reduce_mean(dy)

Optimize

optimize = tf.train.GradientDescentOptimizer(learning_rate=0.015)
train = optimize.minimize(delta)
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for step in range(10000):
    sess.run(train)
    delta_r = sess.run(delta)
    w1_r = sess.run(w1)
    w2_r = sess.run(w2)
    b_r = sess.run(b)
print(w1_r, w2_r, b_r)
fig = plt.figure(1, figsize=(20, 20))
plt.plot(bound_x, (-w1_r * bound_x - b_r) / w2_r, label='predict')
plt.plot(zs[:, 0], zs[:, 1], 'ro', label='data_0')
plt.plot(os[:, 0], os[:, 1], 'g^', label='data_1')
plt.xlabel('x1')
plt.ylabel('x2')
plt.legend()
plt.show()
[-0.34513682] [-0.36142468] [ 6.304564]