吴恩达 机器学习第二周 logistic_regression 单层网络梯度下降法实现
程序员文章站
2022-07-13 10:11:51
...
import numpy as np
import matplotlib.pyplot as plt
#--------------------------------------------------------------------
def signomid(z):
'''
This function is used as the activation function
by the logistic regression method
math formula is:
f(z) = 1.0/[1.0+exp(-z)]
input: z real num or array like structure
output: y real or array like structure
'''
z =np.array(z)
y = 1.0/(1.0 + np.exp(-z))
#y += 1.0e-30
assert(y.shape == z.shape)
return y
#--------------------------------------------------------------------
def signomid_backprop(y_label, z):
'''
This is function calculate the dy/dz value,
the deviation of dy/dz
input: y_label, labeled data
input: gz, internal data
output: dy/dz
'''
y_label = np.array(y_label)
gz = signomid(z)
dydz = y_label - gz
assert(dydz.shape == y_label.shape)
assert(dydz.shape == gz.shape)
return dydz
# y = np.array([0,0,1,1,1]).reshape(5,1)
# dz = signomid_backprop(y,a)
# print(dz)
#--------------------------------------------------------------------
def backprop(x,y_label,w,b):
'''
This function do the calculation of all backprop calculation:
input: y_label labeled data
x: features data
w: the weighted values
b: the interception , real number
'''
y_label = np.array(y_label).reshape(-1,1) # shape of m*1
x = np.array(x) #(n,m)
w = np.array(w).reshape(-1,1) # shape(n,1)
m = x.shape[1]
z = np.dot(w.T,x)+b # shape = (1,n)
z = z.reshape(-1,1) # shape = (n,1)
#print(z,z.shape)
dz = signomid_backprop(y_label, z)
dzdw = np.dot(x,dz).reshape(-1,1)
dzdw = dzdw /np.float(m)
dzdb = np.sum(dz)
return -dzdw,-dzdb
#--------------------------------------------------------------------
def get_loss(x,y,w,b):
y = y.reshape(-1,1)
w = w.reshape(-1,1)
z = np.dot(w.T,x) + b # shape = (1,m)
z.reshape(x.shape[1],1) # shape = (m,1)
h = signomid(z).reshape(-1,1)
#h += 1.0e-30
m = x.shape[1] # x.shape = (n,m)
gz1 = np.log(h)
gz2 = np.log(1.0-h)
loss = np.dot(y.T,gz1) + np.dot((1.0 - y).T,gz2)
loss = loss / np.float(m)
return loss
#--------------------------------------------------------------------
def parameter_learning(x,y,w,b,learning_rate):
'''
This is the total learning function
'''
num_iter = 10000
for i in range(num_iter):
loss = get_loss(x,y,w,b)
loss_temp = loss
dw, db = backprop(x,y,w,b)
#print(dw,db)
#print(w,b)
w += -learning_rate*dw
b += -learning_rate*db
loss = get_loss(x,y,w,b)
dloss = abs(loss-loss_temp)
# if dloss <= 1.0e-6:
# print('this is the needed values of w,b', w,b)
# return w,b
print('this is the needed values of w,b', w,b)
return w,b,dloss
# function used to predict
def predict(x,y,w,b):
error_count = 0
m = x.shape[1]
z = np.dot(w.T,x) + b
props = signomid(z).reshape(-1,1)
predictions = np.arange(m)
for i in range(m):
if props[i] >= 0.5:
predictions[i] =1
else:
predictions[i] = 0
#print(predictions,predictions.shape)
#print('this is out of y',y)
for i in range(m):
if predictions[i] != y[i]:
error_count += 1
accuracy =1.0-np.float(error_count)/np.float(m)
print('this accuracy of signomid is:',accuracy)
return accuracy
# the main function
learning_rate = 0.01
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris = load_iris()
train = iris.data
label = iris.target
for i in range(len(label)):
if label[i] == 2 :
label[i] = 1
#print(label)
x_train,x_test,y_train,y_test = train_test_split(train,label, test_size=0.1)
m,n = x_train.shape[0],x_train.shape[1]
print('this is sample, and col:',m,n)
y_train = y_train.reshape(-1,1)
y_test = y_test.reshape(-1,1)
x_train = x_train.T
x_test = x_test.T
max_feature = x_train.max(axis=1)
max_feature = max_feature.reshape(-1,1)
x_train = x_train/max_feature
w = np.random.randn(n).reshape(-1,1)
b = 0.0001
new_w,new_b,dloss = parameter_learning(x_train,y_train, w,b,learning_rate)
print('this is new w:',new_w)
print('this is new b:',new_b)
print('this is dloss:',dloss)
accuracy = predict(x_train,y_train,new_w,new_b)