softmax回归-多分类

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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值