pyL 1 Week 2 02 用神经网络思想实现Logistic回归
#导入数据
import h5py
#通过h5 选择加载数据的方式 加载规则 并且根据训练集和测试集分别存放
#查看关键key
for key in train_data.keys():
print(key)
#查看关于key的这样一个维度
train_data['train_set_x'].shape
train_data['train_set_y'].shape
test_data['test_set_x'].shape
test_data['test_set_y'].shape
#取出训练集以及测试集
train_data_org = train_data['train_set_x'][:]
train_labels_org = train_data['train_set_y'][:]
test_data_org = train_data['test_set_x'][:]
test_labels_org = train_data['test_set_y'][:]
#查看图片
import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(train_data_org[148])
#数据维度的处理
#获取样本的维度个数
m_train = train_data_org.shape[0]
m_test = train_data_org.shape[0]
train_data_tran = train_data_org.reshape(m_train,-1).T
#-1的意思是将后面的三列转变成一列
test_data_tran = test_data_org.reshape(m_test,-1).T
print(train_data_tran.shape , test_data_tran.shape)
#同样对标签数据也进行处理
#这里使用了np内置的一个工具 目的是增加一个维度
import numpy as np
train_labels_tran = train_labels_org[np.newaxis,:]
test_labels_tran = test_labels_org[np.new axis,:]
#标准化数据
#原因在于像素值一般是大小不均匀的 因为像素值是在0-255之间 所以需要归一化 标准化到0-1之间
#多种方法 按照量程区间
train_data_sta = train_data_tran / 255
test_data_sta = test_data_tran / 255
梯度下降推导 求w以及b的参数值
#定义sigmoid函数
def sigmoid(z):
a = 1 / (1 + np.exp(-z))
return a
#定义前向传播函数 初始化参数
n_dim = train_data_sta.shape[0]
w = np.zeros((n_dim,1))
b=0
#定义前向传播函数、代价函数以及梯度下降
def propagate(w,b,X,Y):
#1.前向传播函数 np.dot() = np的矩阵相乘
Z = np.dot(w.T,X) + b
A = sigmoid(Z)
#2.代价函数
m = X.shape[1]
J = -1/m * np.sum(Y * np.log(A) + (1-Y) * np.log(1-A))
axis = 0 (等于0 按列(默认) 等于1 按行)
#3.梯度下降
dw = 1 / m * np.dot(X,(A-Y).T)
db = 1 / m * np.sum(A-Y)
grands = {'dw' : dw , 'db' : db}
return grands,J
#优化部分
def optimize(w,b,X,y,alpha,n_iters,print_cost):
costs = []
for i in range(n_iters):
grands,J = propagate(w,b,X,Y)
dw = grands['dw']
db = grands['db']
w = w - alpha * dw
b = b - alpha * db
if i % 100 == 0:
costs.append(J)
if print_cost:
print('n_iters is ' , i , 'cost is ' , J)
grands = {'dw' : dw , 'db' : db}
params = {'dw' : w , 'db' : b}
return grand,params,costs
#预测部分
#流程主要就是 通过算出的w,b带入前向传播函数之后 得到Z 以及A A最终是一个概率值(表示一张图的可能性有多大)
def predict(w,b,x_test):
Z = np.dot(w.T,x_test) + b
A = sigmoid(Z)
m = X_test.shape[1] #一共有多少个样本
y_pred = np.zeros((1,m)) #放预测值
for i in range(m):
if A[:,i] > 0.5:
y_pred[:i] = 1
else:
y_pred[:i] = 0
return y_pred
#模型整合
#将预测和优化整合到一个模型里面 之后只需要调用模型即可
def model(w,b,X_train,y_train,X_tese,y_test,alpha,n_iters,print_cost):
grand,params,costs = optimize(w,b,X_train,y_train,alpha,n_iters,print_cost)
w = params['w']
b = params['b']
y_pred_train = predict(w,b,x_train)
y_pred_test = predict(w,b,x_test)
print('The train acc is',np.mean(y_pred_train == y_train) * 100 , '%')
print('The test acc is',np.mean(y_pred_test == y_test) * 100 , '%')
d={
'w' : w,
'b' : b,
'costs' : costs,
'y_pred_train' : y_pred_train,
'y_pred_test' : y_pred_test,
'alpha' : alpha
}
#预测准确率、代价曲线、单个样本测试
d = model(w,b,train_data_sta,train_labels_tran,test_data_sta,test_labels,alpha = 0.05,n_iters = 2000)
#得到的结果有些过拟合
#代价函数的趋势
plt.plot(d['costs'])
plt.xlabel('per hundred iters')
plt.ylabel('cost')
#取其中图片 看是否一致 修改index 进行查看结果
index = 1
print('y is ',test_labels_tran[0,index])
print('y_prediction is ',int(b['y_pred_test'][0,index])
plt.imshow(test_data_org[index])
#选取不同的alpha下的区别
alphas = [0.01,0.001,0.0001]
for i in alphas:
print('alpha = ',i)
d = model(w,b,train_data_sta,train_labels_tran,test_data_sta,test_labels,alpha = i,n_iters = 2000,print_cost = true)
print('===================================')
plt.plot(d['costs'],label = str(i))
plt.xlabel('per hundred iters')
plt.ylabel('cost')
plt.legend()
#预测新图片 下载一个新的图片 给出一个路径
fname = '路径'
image = plt.imread(fname)
plt.imshow()
#尺寸不一致 所以导入skimage导入包 改变图片的尺寸
from skimage import transform
image_tran = transform.resize(image,(64,64,3)).reshape(64*64*3,1)
image_tran.shape
#加入预测函数之后进行预测即可
y = predict(d['w'],d['b'],image_tran)
print(int(y))
Offer