其他
【强基固本】基础算法:使用numpy实现逻辑回归随机梯度下降(附代码)
深度学习算法工程师面试,记录一道较为基础的笔试题:
输入:目标向量Y(N*1),矩阵X(N*K);输出:使用随机梯度下降求得的逻辑回归系数W(K+1)。
分析:该问题需要先列出逻辑回归的函数解析式,再选择损失函数,最后算出损失函数关于更新参数的导数,即可开始随机梯度下降。
地址:https://www.zhihu.com/people/thisiszhou
01
逻辑回归解析式
02
Loss函数
03
关于更新参数的导数
04
参数更新(梯度下降)
05
代码实现
import numpy as np
from random import shuffle
# sigmoid函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 交叉熵函数
def ce(y, y_label):
return -y_label*np.log(y) - (1-y_label)*np.log(1-y)
# 交叉熵函数导数
def ce_grad(y, y_label):
return -y_label/y + (1-y_label)/(1-y)
# 确定随机性唯一
np.random.seed(32)
n = 6
k = 7
# 随机初始化输入与参数
X = np.random.rand(n,k)
y_label = np.random.randint(0,2,size=(n,1)).astype(np.float32)
w = np.random.rand(k,1)
b = np.random.rand(1,1)
def forward(X, w, b):
y1 = np.dot(X, w) + b
y2 = sigmoid(y1)
y3 = ce(y2,y_label)
loss = sum(y3)
return y1, y2, y3, loss
def gradients(y1, y2, y3, X, y_label):
grad1 = np.ones(len(y3))
grad2 = ce_grad(y2, y_label)
grad3 = sigmoid(y1)*(1-sigmoid(y1))
grad4_w = X
grad4_b = 1
return (
np.dot(grad1, grad2*grad3*grad4_w),
np.dot(grad1, grad2*grad3*grad4_b)
)
array([2.34286961, 2.97101168, 1.98692618, 1.81275096, 2.52826215,
2.42595535, 1.9706045 ])
import tensorflow as tf
def ce(y, y_label):
return -y_label*tf.log(y) - (1-y_label)*tf.log(1-y)
X = tf.Variable(X)
w = tf.Variable(w)
b = tf.Variable(b)
y1 = tf.matmul(X, w) + b
y2 = tf.sigmoid(y1)
y3 = ce(y2, y_label)
loss = tf.reduce_sum(y3)
grad = tf.gradients(loss, w)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
ret = sess.run(grad)
array([[2.34286961],
[2.97101168],
[1.98692618],
[1.81275096],
[2.52826215],
[2.42595535],
[1.9706045 ]])
yita = 1e-2
train_num = 10000
for i in range(train_num):
y1, y2, y3, loss = forward(X, w, b)
g_w, g_b = gradients(y1, y2, y3, X, y_label)
w -= yita*g_w.reshape([-1, 1])
b -= yita*g_b
if i % 1000 == 0:
print("loss:", loss)
loss: [11.6081676]
loss: [1.18844796]
loss: [0.71728752]
loss: [0.49936237]
loss: [0.37872785]
loss: [0.30340733]
loss: [0.25233963]
loss: [0.21561081]
loss: [0.18800623]
loss: [0.16654284]
>>> forward(X, w, b)[1]
array([[0.01485668],
[0.00538101],
[0.01436137],
[0.01684294],
[0.0247247 ],
[0.93002105]])
>>> y_label
array([[0.],
[0.],
[0.],
[0.],
[0.],
[1.]], dtype=float32)
06
总结
本文目的在于学术交流,并不代表本公众号赞同其观点或对其内容真实性负责,版权归原作者所有,如有侵权请告知删除。
直播预告
历史文章推荐
【CVPR 2020 Tutorial】如何写好论文和评审(概述)
太牛逼了!一位中国博士把整个CNN都给可视化了,每个细节看的清清楚楚!
Nature发表牛津博士建议:我希望在读博士之初时就能知道的20件事
沈向洋、华刚:读科研论文的三个层次、四个阶段与十个问题
如何看待2021年秋招算法岗灰飞烟灭?
独家解读 | ExprGAN:基于强度可控的表情编辑
独家解读 | 矩阵视角下的BP算法
独家解读 | Capsule Network深度解读
独家解读 | Fisher信息度量下的对抗攻击
论文解读 | 知识图谱最新研究综述
你的毕业论文过了吗?《如何撰写毕业论文?》
卡尔曼滤波系列——经典卡尔曼滤波推导
分享、点赞、在看,给个三连击呗!