softmax多分类
# X(x1,x2) y(0/1/2/3)
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1)
#高斯模型
x_1 = np.random.normal(-3,1,size=100)
x_2 = np.random.normal(-3,1,size=100)
y=np.zeros(100)
c0 = np.array([x_1,x_2,y]).T #0分类
x_1 = np.random.normal(3,1,size=100)
x_2 = np.random.normal(-3,1,size=100)
y=np.ones(100)
c1 = np.array([x_1,x_2,y]).T #1分类
x_1 = np.random.normal(-3,1,size=100)
x_2 = np.random.normal(3,1,size=100)
y=np.ones(100)*2
c2 = np.array([x_1,x_2,y]).T #2分类
x_1 = np.random.normal(3,1,size=100)
x_2 = np.random.normal(3,1,size=100)
y=np.ones(100)*3
c3 = np.array([x_1,x_2,y]).T #3分类
##构造数据集
all_data=np.concatenate((c0,c1,c2,c3),axis=0)
np.random.shuffle(all_data)
train_data_x=all_data[:300,:2]
train_data_y=all_data[:300,-1]
test_data_x=all_data[300:,:2]
test_data_y=all_data[300:,-1]
train_data_y=np.reshape(train_data_y,(300,1))
test_data_y=np.reshape(test_data_y,(100,1))
#y=w1*x1+w2*x2+b
#定义随机权重
W=np.random.rand(4,2)
Bias=np.random.rand(1,4)
# softmax函数
def softmax_dim1(z):
return np.exp(z)/np.sum(np.exp(z))
def softmax_dim2(z):
exp=np.exp(z)
sum_exp=np.sum(np.exp(z),axis=1,keepdims=True)
return exp/sum_exp
oo=softmax_dim2(test_data_x)
pp=softmax_dim1(test_data_x)
def one_hat(temp):
one_hat=np.zeros((len(temp),len(np.unique(temp))))
one_hat[np.arange(len(temp)),temp.astype(np.int).T]=1
return one_hat
#计算Y值
def compute_y_hat(W,X,b):
return np.dot(X,W.T)+Bias
#计算交叉熵
def cross_entropy(y,y_hat):
loss=-(1/len(y))*np.sum(y*np.log(y_hat))
return loss
lr=0.001
loss_list=[]
W_list=[]
B_list=[]
for i in range(30000):
#计算loss
X=train_data_x
y=one_hat(train_data_y)
y_hat=softmax_dim2(compute_y_hat(W,X,Bias))
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
W_list.append(W)
Bias=Bias-lr*grad_b
B_list.append(Bias)
#输出
if i%100==0:
print("i: %d,loss: %f"%(i,loss))
#plt.plot(loss_list)
plt.scatter(c0[:,0],c0[:,1],marker='o')
plt.scatter(c1[:,0],c1[:,1],marker='*')
plt.scatter(c2[:,0],c2[:,1],marker='s')
plt.scatter(c3[:,0],c3[:,1],marker='+')
x=np.arange(-5,5)
y1=-(W[0,0]*x+Bias[0,0])/W[0,1]
y2=-(W[1,0]*x+Bias[0,1])/W[1,1]
y3=-(W[2,0]*x+Bias[0,2])/W[2,1]
y4=-(W[3,0]*x+Bias[0,3])/W[3,1]
plt.plot(x,y1,'b')
plt.plot(x,y2,'g')
plt.plot(x,y3,'r')
plt.plot(x,y4,'y')
#测试集
def predit(x):
y_hat=softmax_dim2(compute_y_hat(W,X,Bias))
return np.argmax(y_hat,axis=1)
result=np.sum(predit(test_data_x)==test_data_y)/len(test_data_y)