EduCoder:机器学习—神经网络
第1关:什么是神经网络
第2关:神经元与感知机
编程要求:
根据提示,在右侧编辑器补充 python 代码,构建一个感知机模型,底层代码会调用您实现的感知机模型进行训练,并对一个特征值分别为青绿、稍蜷、沉闷(即特征向量为[0,2,2])的西瓜的好坏进行预测,预测正确则通关。
代码如下:
#encoding=utf8
import numpy as np
#构建感知机算法
class Perceptron(object):
def __init__(self, learning_rate = 0.01, max_iter = 200):
self.lr = learning_rate
self.max_iter = max_iter
def fit(self, data, label):
'''
input:data(ndarray):训练数据特征
label(ndarray):训练数据标签
output:w(ndarray):训练好的权重
b(ndarry):训练好的偏置
'''
#编写感知机训练方法,w为权重,b为偏置
self.w = np.random.randn(data.shape[1])
self.b = np.random.rand(1)
#********* Begin *********#
for i in range(len(label)):
while label[i]*(np.matmul(self.w,data[i])+self.b)<=0:
self.w=self.w+self.lr*(label[i]*data[i])
self.b=self.b+self.lr*label[i]
#********* End *********#
return None
def predict(self, data):
'''
input:data(ndarray):测试数据特征
'''
#编写感知机预测方法,若是正类返回1,负类返回-1
#********* Begin *********#
yc=np.matmul(data,self.w)+self.b
for i in range(len(yc)):
if(yc[i])>=0:
yc[i]=1
else:
yc[i]=-1
predict=yc
return predict
#********* End *********#
第3关:激活函数
编程要求:
根据提示,在右侧编辑器补充Python代码,实现relu激活函数,底层代码会调用您实现的relu激活函数来进行测试。
测试说明:
输入:9
预期输出:9
输入:-1
预期输出:0
代码如下:
#encoding=utf8
def relu(x):
'''
input:x(ndarray)输入数据
'''
#********* Begin *********#
if x<=0:
return 0
else:
return x
#********* End *********#
第4关:反向传播算法
编程要求:
根据提示,在右侧编辑器补充 python 代码,你需要完成神经网络的前向传播、反向传播以及梯度下降部分,然后用训练好的神经网络对鸢尾花进行分类。
测试说明:
只需返回预测结果即可,程序内部会检测您的代码,预测正确率高于90%视为过关。
代码如下:
#encoding=utf8
import numpy as np
from math import sqrt
#bp神经网络训练方法
def bp_train(feature,label,n_hidden,maxcycle,alpha,n_output):
'''
计算隐含层的输入
input:feature(mat):特征
label(mat):标签
n_hidden(int)隐藏层的节点个数
maxcycle(int):最大迭代次数
alpha(float):学习率
n_output(int):输出层的节点个数
output:w0(mat):输入层到隐藏层之间的权重
b0(mat):输入层到隐藏层之间的偏置
w1(mat):隐藏层到输出层之间的权重
b1(mat):隐藏层到输出层之间的偏置
'''
m,n = np.shape(feature)
#初始化
w0 = np.mat(np.random.rand(n,n_hidden))
w0 = w0*(8.0*sqrt(6)/sqrt(n+n_hidden))-\
np.mat(np.ones((n,n_hidden)))*\
(4.0*sqrt(6)/sqrt(n+n_hidden))
b0 = np.mat(np.random.rand(1,n_hidden))
b0 = b0*(8.0*sqrt(6)/sqrt(n+n_hidden))-\
np.mat(np.ones((1,n_hidden)))*\
(4.0*sqrt(6)/sqrt(n+n_hidden))
w1 = np.mat(np.random.rand(n_hidden,n_output))
w1 = w1*(8.0*sqrt(6)/sqrt(n_hidden+n_output))-\
np.mat(np.ones((n_hidden,n_output)))*\
(4.0*sqrt(6)/sqrt(n_hidden+n_output))
b1 = np.mat(np.random.rand(1,n_output))
b1 = b1*(8.0*sqrt(6)/sqrt(n_hidden+n_output))-\
np.mat(np.ones((1,n_output)))*\
(4.0*sqrt(6)/sqrt(n_hidden+n_output))
#训练
i = 0
while i <= maxcycle:
#********* Begin *********#
#前向传播
#计算隐藏层的输入
hidden_input=hidden_in(feature,w0,b0)
#计算隐藏层的输出
hidden_output=hidden_out(hidden_input)
#计算输出层的输入
output_in=predict_in(hidden_output,w1,b1)
#计算输出层的输出
output_out=predict_out(output_in)
#反向传播
#隐藏层到输出层之间的残差
delta_output=-np.multiply((label-output_out),partial_sig(output_in))
#输入层到隐藏层之间的残差
delta_hidden=np.multiply((delta_output*w1.T),partial_sig(hidden_input))
#更新权重与偏置
w1=w1-alpha*(hidden_output.T*delta_output)
b1=b1-alpha*np.sum(delta_output,axis=0)*(1.0/m)
w0=w0-alpha*(feature.T*delta_hidden)
b0=b0-alpha*np.sum(delta_hidden,axis=0)*(1.0/m)
#********* End *********#
i +=1
return w0,w1,b0,b1
#计算隐藏层的输入函数
def hidden_in(feature,w0,b0):
m = np.shape(feature)[0]
hidden_in = feature*w0
for i in range(m):
hidden_in[i,] += b0
return hidden_in
#计算隐藏层的输出函数
def hidden_out(hidden_in):
hidden_output = sig(hidden_in)
return hidden_output
#计算输出层的输入函数
def predict_in(hidden_out,w1,b1):
m = np.shape(hidden_out)[0]
predict_in = hidden_out*w1
for i in range(m):
predict_in[i,] +=b1
return predict_in
#计算输出层的输出的函数
def predict_out(predict_in):
result = sig(predict_in)
return result
#sigmoid函数
def sig(x):
return 1.0/(1+np.exp(-x))
#计算sigmoid函数偏导
def partial_sig(x):
m,n = np.shape(x)
out = np.mat(np.zeros((m,n)))
for i in range(m):
for j in range(n):
out[i,j] = sig(x[i,j])*(1-sig(x[i,j]))
return out
第5关:Dropout
编程要求:
根据提示,在右侧编辑器补充Python代码,实现Dropout方法,底层代码会调用您实现的Dropout方法来进行测试。
测试说明:
输入:[0,1,2,3,4,5,6,7,8,9]
预期输出:[0 0 0 3 0 0 6 7 0 9]
输入:[10,11,12,13,14,15,16,17,18,19]
预期输出:[11 0 0 14 0 0 17 18 0 20]
代码如下:
#encoding=utf8
import numpy as np
#由于Dropout方法输出存在随机性,我们已经设置好随机种子,你只需要完成Dropout方法就行。
class Dropout:
def __init__(self,dropout_ratio=0.5):
self.dropout_ratio = dropout_ratio
self.mask = None
def forward(self,x,train_flg=True):
'''
前向传播中self.mask会随机生成和x形状相同的数组,
并将值比dropout_ratio大的元素设为True,
x为一个列表。
'''
#********* Begin *********#
if train_flg:
self.mask=np.random.rand(*x.shape)>self.dropout_ratio
return x*self.mask
else:
return x*(1.0-self.dropout_ratio)
#********* End *********#
def backward(self,dout):
'''
前向传播时传递了信号的神经元,
反向传播时按原样传递信号。
前向传播没有传递信号的神经元,
反向传播时信号就停在那里。
dout为一个列表。
'''
#********* Begin *********#
return dout*self.mask
#********* End *********#
第6关:sklearn中的神经网络
编程要求:
填写iris_predict(train_sample, train_label, test_sample)函数完成鸢尾花分类任务,其中:
- train_sample:训练样本
- train_label:训练标签
- test_sample:测试样本
测试说明:
只需返回预测结果即可,程序内部会检测您的代码,预测正确率高于95%视为过关。
代码如下:
#encoding=utf8
from sklearn.neural_network import MLPClassifier
def iris_predict(train_sample, train_label, test_sample):
'''
实现功能:1.训练模型 2.预测
:param train_sample: 包含多条训练样本的样本集,类型为ndarray
:param train_label: 包含多条训练样本标签的标签集,类型为ndarray
:param test_sample: 包含多条测试样本的测试集,类型为ndarry
:return: test_sample对应的预测标签
'''
#********* Begin *********#
tree_clf=MLPClassifier(solver='lbfgs',alpha=1e-5,random_state=1)
trre_clf=tree_clf.fit(train_sample,train_label)
y_pred=tree_clf.predict(test_sample)
return y_pred
#********* End *********#