Python-神经网络
目的
根据体重、身高来判断性别
导入模块
import numpy as np
from matplotlib import pyplot as plt
激活函数: f(x) = 1 / (1 + e^(-x))
def sigmoid(x):
return 1 / (1 + np.exp(-x))
激活函数导数
def deriv_sigmoid(x):
fx = sigmoid(x)
return fx * (1 - fx)
使用方差作为损失函数
def mse_loss(y_true, y_pred):
return ((y_true - y_pred) ** 2).mean()
神经网络
class OurNeuralNetwork:
‘’’
神经网络:
- 两个输入层(x[0],x[1])
- 隐含层两个神经元 (h1,h2)
- 输出层一个神经元 (o1)
*** 免责声明 ***:
下面的代码旨在简单和具有教育意义,而不是最佳的。
真正的神经网络代码看起来不像这样。 不要使用此代码。
相反,请阅读/运行它以了解此特定网络的工作原理。
‘’’
# 随机初始化权重和截距函数
def init(self):
# 权重,Weights
self.w1 = np.random.normal()
self.w2 = np.random.normal()
self.w3 = np.random.normal()
self.w4 = np.random.normal()
self.w5 = np.random.normal()
self.w6 = np.random.normal()
# 截距,Biases
self.b1 = np.random.normal()
self.b2 = np.random.normal()
self.b3 = np.random.normal()
#前馈函数
def feedforward(self, x):
# x 是一个有 2 个元素的 numpy 数组
h1 = sigmoid(self.w1 * x[0] + self.w2 * x[1] + self.b1)
h2 = sigmoid(self.w3 * x[0] + self.w4 * x[1] + self.b2)
o1 = sigmoid(self.w5 * h1 + self.w6 * h2 + self.b3)
return o1
#训练函数
def train(self, data, all_y_trues):
‘’’
- 数据是一个 (n x 2) numpy 数组,n是数据集中的样本数。
- all_y_trues 是一个具有 n 个元素的 numpy 数组,其中的元素对应于数据中的元素。
‘’’
learn_rate = 0.1 # 学习率
epochs = 1000 # 循环遍历整个数据集的次数(迭代次数)
for epoch in range(epochs):
for x, y_true in zip(data, all_y_trues):
# --- 做一个前馈
sum_h1 = self.w1 * x[0] + self.w2 * x[1] + self.b1
h1 = sigmoid(sum_h1)
sum_h2 = self.w3 * x[0] + self.w4 * x[1] + self.b2
h2 = sigmoid(sum_h2)
sum_o1 = self.w5 * h1 + self.w6 * h2 + self.b3
o1 = sigmoid(sum_o1)
y_pred = o1
# --- 计算偏导数
# --- 命名:d_L_d_w1 代表"L对w1的偏导"
d_L_d_ypred = -2 * (y_true - y_pred)
# 神经元 o1
d_ypred_d_w5 = h1 * deriv_sigmoid(sum_o1)
d_ypred_d_w6 = h2 * deriv_sigmoid(sum_o1)
d_ypred_d_b3 = deriv_sigmoid(sum_o1)
d_ypred_d_h1 = self.w5 * deriv_sigmoid(sum_o1)
d_ypred_d_h2 = self.w6 * deriv_sigmoid(sum_o1)
# 神经元 h1
d_h1_d_w1 = x[0] * deriv_sigmoid(sum_h1)
d_h1_d_w2 = x[1] * deriv_sigmoid(sum_h1)
d_h1_d_b1 = deriv_sigmoid(sum_h1)
# 神经元 h2
d_h2_d_w3 = x[0] * deriv_sigmoid(sum_h2)
d_h2_d_w4 = x[1] * deriv_sigmoid(sum_h2)
d_h2_d_b2 = deriv_sigmoid(sum_h2)
# --- 更新权重和截距
# 神经元 h1
self.w1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w1
self.w2 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w2
self.b1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_b1
# 神经元 h2
self.w3 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_w3
self.w4 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_w4
self.b2 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_b2
# 神经元 o1
self.w5 -= learn_rate * d_L_d_ypred * d_ypred_d_w5
self.w6 -= learn_rate * d_L_d_ypred * d_ypred_d_w6
self.b3 -= learn_rate * d_L_d_ypred * d_ypred_d_b3
y_preds = np.apply_along_axis(self.feedforward, 1, data)
loss = mse_loss(all_y_trues, y_preds)
plt.plot(epoch, loss, '.r')
# --- 计算每个时期结束时的总损失
if epoch % 100 == 0:
print("Epoch %d loss: %.3f" % (epoch, loss))
数据预处理,体重减135,身高减66
定义数据
data = np.array([
[-2, -1], # Alice,133 磅,65 英寸
[25, 6], # Bob,160 磅,72 英寸
[17, 4], # Charlie,152 磅,70 英寸
[-15, -6], # Diana,120 磅,60 英寸
])
all_y_trues = np.array([
1, # Alice,女
0, # Bob,男
0, # Charlie,男
1, # Diana,女
])
训练神经网络
network = OurNeuralNetwork()
network.train(data, all_y_trues)
预测
emily = np.array([-7, -3]) # 128 磅,63 英寸
frank = np.array([20, 2]) # 155 磅,68 英寸
print(“Emily: %.3f” % network.feedforward(emily)) # 0.963 - F
print(“Frank: %.3f” % network.feedforward(frank)) # 0.039 - M
损失函数曲线图
plt.show()
完整代码
# 导入模块
import numpy as np
from matplotlib import pyplot as plt
# 激活函数: f(x) = 1 / (1 + e^(-x))
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 激活函数导数
def deriv_sigmoid(x):
fx = sigmoid(x)
return fx * (1 - fx)
# 使用方差作为损失函数
def mse_loss(y_true, y_pred):
return ((y_true - y_pred) ** 2).mean()
# 神经网络
class OurNeuralNetwork:
'''
神经网络:
- 两个输入层(x[0],x[1])
- 隐含层两个神经元 (h1,h2)
- 输出层一个神经元 (o1)
*** 免责声明 ***:
下面的代码旨在简单和具有教育意义,而不是最佳的。
真正的神经网络代码看起来不像这样。 不要使用此代码。
相反,请阅读/运行它以了解此特定网络的工作原理。
'''
# 随机初始化权重和截距
def __init__(self):
# 权重,Weights
self.w1 = np.random.normal()
self.w2 = np.random.normal()
self.w3 = np.random.normal()
self.w4 = np.random.normal()
self.w5 = np.random.normal()
self.w6 = np.random.normal()
# 截距,Biases
self.b1 = np.random.normal()
self.b2 = np.random.normal()
self.b3 = np.random.normal()
def feedforward(self, x):
# x 是一个有 2 个元素的 numpy 数组
h1 = sigmoid(self.w1 * x[0] + self.w2 * x[1] + self.b1)
h2 = sigmoid(self.w3 * x[0] + self.w4 * x[1] + self.b2)
o1 = sigmoid(self.w5 * h1 + self.w6 * h2 + self.b3)
return o1
def train(self, data, all_y_trues):
'''
- 数据是一个 (n x 2) numpy 数组,n是数据集中的样本数。
- all_y_trues 是一个具有 n 个元素的 numpy 数组,其中的元素对应于数据中的元素。
'''
learn_rate = 0.1 # 学习率
epochs = 1000 # 循环遍历整个数据集的次数(迭代次数)
for epoch in range(epochs):
for x, y_true in zip(data, all_y_trues):
# --- 做一个前馈
sum_h1 = self.w1 * x[0] + self.w2 * x[1] + self.b1
h1 = sigmoid(sum_h1)
sum_h2 = self.w3 * x[0] + self.w4 * x[1] + self.b2
h2 = sigmoid(sum_h2)
sum_o1 = self.w5 * h1 + self.w6 * h2 + self.b3
o1 = sigmoid(sum_o1)
y_pred = o1
# --- 计算偏导数
# --- 命名:d_L_d_w1 代表"L对w1的偏导"
d_L_d_ypred = -2 * (y_true - y_pred)
# 神经元 o1
d_ypred_d_w5 = h1 * deriv_sigmoid(sum_o1)
d_ypred_d_w6 = h2 * deriv_sigmoid(sum_o1)
d_ypred_d_b3 = deriv_sigmoid(sum_o1)
d_ypred_d_h1 = self.w5 * deriv_sigmoid(sum_o1)
d_ypred_d_h2 = self.w6 * deriv_sigmoid(sum_o1)
# 神经元 h1
d_h1_d_w1 = x[0] * deriv_sigmoid(sum_h1)
d_h1_d_w2 = x[1] * deriv_sigmoid(sum_h1)
d_h1_d_b1 = deriv_sigmoid(sum_h1)
# 神经元 h2
d_h2_d_w3 = x[0] * deriv_sigmoid(sum_h2)
d_h2_d_w4 = x[1] * deriv_sigmoid(sum_h2)
d_h2_d_b2 = deriv_sigmoid(sum_h2)
# --- 更新权重和截距
# 神经元 h1
self.w1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w1
self.w2 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w2
self.b1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_b1
# 神经元 h2
self.w3 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_w3
self.w4 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_w4
self.b2 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_b2
# 神经元 o1
self.w5 -= learn_rate * d_L_d_ypred * d_ypred_d_w5
self.w6 -= learn_rate * d_L_d_ypred * d_ypred_d_w6
self.b3 -= learn_rate * d_L_d_ypred * d_ypred_d_b3
y_preds = np.apply_along_axis(self.feedforward, 1, data)
loss = mse_loss(all_y_trues, y_preds)
plt.plot(epoch, loss, '.r')
# --- 计算每个时期结束时的总损失
if epoch % 100 == 0:
print("Epoch %d loss: %.3f" % (epoch, loss))
# 数据预处理,体重减135,身高减66
# 定义数据
data = np.array([
[-2, -1], # Alice,133 磅,65 英寸
[25, 6], # Bob,160 磅,72 英寸
[17, 4], # Charlie,152 磅,70 英寸
[-15, -6], # Diana,120 磅,60 英寸
])
all_y_trues = np.array([
1, # Alice,女
0, # Bob,男
0, # Charlie,男
1, # Diana,女
])
# 训练神经网络
network = OurNeuralNetwork()
network.train(data, all_y_trues)
# 预测
emily = np.array([-7, -3]) # 128 磅,63 英寸
frank = np.array([20, 2]) # 155 磅,68 英寸
print("Emily: %.3f" % network.feedforward(emily)) # 0.963 - F
print("Frank: %.3f" % network.feedforward(frank)) # 0.039 - M
# 损失函数曲线图
plt.show()