import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
np.random.seed(0)
num = 100
x_1 = np.random.normal(-3, 1, size=(num))
x_2 = np.random.normal(-3, 1, size=(num))
y = np.zeros(num)
c_0 = np.array([x_1, x_2, y]) #0分类
x_1 = np.random.normal(3, 1, size=(num))
x_2 = np.random.normal(-3, 1, size=(num))
y = np.zeros(num)
c_1 = np.array([x_1, x_2, y]) #1分类
x_1 = np.random.normal(-3, 1, size=(num))
x_2 = np.random.normal(3, 1, size=(num))
y = np.zeros(num)*2
c_2 = np.array([x_1, x_2, y]) #2分类
x_1 = np.random.normal(3, 1, size=(num))
x_2 = np.random.normal(3, 1, size=(num))
y = np.zeros(num)*3
c_3 = np.array([x_1, x_2, y]) #3分类
c_0 = c_0.T
c_1 = c_1.T
c_2 = c_2.T
c_3 = c_3.T
all_data = np.concatenate((c_0, c_1, c_2, c_3))
np.random.shuffle(all_data)
train_data_x = all_data[:300, :2]
train_data_y = all_data[:300, -1].reshape(300, 1)
test_data_x = all_data[300:, :2]
test_data_y = all_data[300:, -1].reshape(100, 1)
#y = w1*x1+w2*x2+b
W = np.random.rand(4, 2)
b = np.random.rand(1, 4)
plt.scatter(c_0[:, 0], c_0[:, 1], marker='o')
plt.scatter(c_1[:, 0], c_1[:, 1], marker='.')
plt.scatter(c_2[:, 0], c_2[:, 1], marker='v')
plt.scatter(c_3[:, 0], c_3[:, 1], marker='s')
x = np.arange(-5, 5)
y0 = -(W[0, 0] * x + b[0, 0])/W[0, 1]
y1 = -(W[1, 0] * x + b[0, 1])/W[1, 1]
y2 = -(W[2, 0] * x + b[0, 2])/W[2, 1]
y3 = -(W[3, 0] * x + b[0, 3])/W[3, 1]
plt.plot(x, y0, 'b')
plt.plot(x, y1, 'y')
plt.plot(x, y2, 'g')
plt.plot(x, y3, 'r')
plt.show()
def softmax(z):
exp = np.exp(z)
sum_exp = np.sum(np.exp(z), axis=1, keepdims=True)
return exp/sum_exp
def one_hot(temp):
one_hot = np.zeros((len(temp), len(np.unique(temp))))
one_hot[np.arange(len(temp)), temp.astype(np.int).T] = 1
return one_hot
#计算y_hat
def compute_y_hat(W, X, b):
return np.dot(X, W.T) + b
#计算交叉熵
def cross_entropy(y, y_hat):
loss = -(1/len(y))*np.sum(y*np.log(y_hat))
return loss
lr = 0.001
loss_list = []
for i in range(1000):
#计算loss
X = train_data_x
y = one_hot(train_data_y)
y_hat = softmax(compute_y_hat(W, X, b))
loss = cross_entropy(y, y_hat)
loss_list.append(loss)
#计算梯度
grad_w = (1/len(X))*np.dot(X.T, (y_hat - y))
grad_b = (1/len(X))*np.sum(y_hat - y)
#更新参数
W = W - lr * grad_w.T
b = b - lr * grad_b
#输出
if i % 100 == 1:
print("i: %d, loss: %f" % (i, loss))
plt.plot(loss_list)
plt.show()
plt.scatter(c_0[:, 0], c_0[:, 1], marker='o')
plt.scatter(c_1[:, 0], c_1[:, 1], marker='.')
plt.scatter(c_2[:, 0], c_2[:, 1], marker='v')
plt.scatter(c_3[:, 0], c_3[:, 1], marker='s')
x = np.arange(-5, 5)
y0 = -(W[0, 0] * x + b[0, 0])/W[0, 1]
y1 = -(W[1, 0] * x + b[0, 1])/W[1, 1]
y2 = -(W[2, 0] * x + b[0, 2])/W[2, 1]
y3 = -(W[3, 0] * x + b[0, 3])/W[3, 1]
plt.plot(x, y0, 'b')
plt.plot(x, y1, 'y')
plt.plot(x, y2, 'g')
plt.plot(x, y3, 'r')
plt.show()
i: 1, loss: 9.400959
i: 101, loss: 8.592559
i: 201, loss: 7.921779
i: 301, loss: 7.383603
i: 401, loss: 6.964679
i: 501, loss: 6.646839
i: 601, loss: 6.410712
i: 701, loss: 6.238248
i: 801, loss: 6.113970
i: 901, loss: 6.025326