</br>
</br>
挑战题:用代码实现两层的神经网络的梯度传播,中间层的尺寸为13【房价预测案例】(教案当前的版本为一层的神经网络),如 图14 所示。
</br>
import numpy as np
class Network(object):
def __init__(self, num_of_weight, num_of_hidden=13):
# 随机产生参数
# 隐藏层数量num_fo_hidden
self.w1 = np.random.randn(num_of_weight, num_of_hidden)
self.b1 = np.zeros((num_of_weight, 1))
self.w2 = np.random.randn(num_of_hidden, 1)
self.b2 = 0.
def forward(self, x):
z1 = np.dot(x, self.w1) + self.b1.T
z2 = np.dot(z1, self.w2) + self.b2
return z1, z2
def loss(self, z, y):
error = z - y
num_samples = error.shape[0]
cost = error * error
cost = np.sum(cost) / num_samples
return cost
def gradient(self, x, y):
z1,z2 = self.forward(x)
N = x.shape[0]
gradient_w2 = (z2 - y) * z1
gradient_w2 = np.mean(gradient_w2, axis=0)
gradient_w2 = gradient_w2[:, np.newaxis]
gradient_b2 = (z2 - y)
gradient_b2 = np.mean(gradient_b2)
gradient_w1 = (z2 - y) * z1
gradient_w1 = np.mean(gradient_w1 * np.dot(x, self.w2), axis=0)
gradient_w1 = gradient_w1[:, np.newaxis]
gradient_b1 = (z2 - y)
gradient_b1 = np.mean(gradient_b2 * self.w2)
return gradient_w1, gradient_b1, gradient_w2, gradient_b2
def update(self, gradient_w1, gradient_b1, gradient_w2, gradient_b2, eta=0.01):
self.w1 = self.w1 - eta * gradient_w1
self.w2 = self.w2 - eta * gradient_w2
self.b1 = self.b1 - eta * gradient_b1
self.b2 = self.b2 - eta * gradient_b2
def train(self, training_data, num_epoches, batch_size=10, eta=0.01):
n = len(training_data)
losses = []
for epoch_id in range(num_epoches):
# 在迭代开始之前将训练数据的顺序随机打乱
# 然后在按每次取batch_size条数据的方式取出
np.random.shuffle(training_data)
# 将训练数据进行拆分,每个mini_batch包含batch_size条数据
mini_batches = [training_data[k : k + batch_size] for k in range(0, n, batch_size)]
for iter_id, mini_batch in enumerate(mini_batches):
x = mini_batch[:, : -1]
y = mini_batch[:, -1 :]
a1, a2 = self.forward(x)
loss = self.loss(a2, y)
gradient_w1, gradient_b1, gradient_w2, gradient_b2 = self.gradient(x, y)
self.update(gradient_w1, gradient_b1, gradient_w2, gradient_b2, eta)
losses.append(loss)
print('Epoch {:3d} / iter {:3d}, loss = {:.4f}'.format(epoch_id, iter_id, loss))
return losses
import matplotlib.pyplot as plt
# 获取数据
train_data, test_data = load_data()
# 创建网络
net = Network(13)
#启动训练
losses = net.train(train_data, num_epoches=50, batch_size=100, eta=0.1)
# 画出损失函数的变化趋势
plot_x = np.arange(len(losses))
plot_y = np.array(losses)
plt.plot(plot_x, plot_y)
plt.show()
在AI Studio上阅读房价预测案例(两个版本)的代码,并运行观察效果。
在本机或服务器上安装Python、jupyter和PaddlePaddle,运行房价预测的案例(两个版本),并观察运行效果。
想一想:基于Python编写的模型和基于飞桨编写的模型在存在哪些异同?如程序结构,编写难易度,模型的预测效果,训练的耗时等等。
相同点:
不同点:
使用NumPy计算tanh激活函数
tanh是神经网络中常用的一种激活函数,其定义如下:
\[y = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}\]请参照讲义中Sigmoid激活函数的计算程序,用NumPy实现tanh函数的计算,并画出其函数曲线。
提交方式:请用NumPy写出计算程序,并画出tanh函数曲线图,$x$的取值范围设置为[-10., 10.]。
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.patches as patches
plt.figure(figsize=(8, 5))
x = np.arange(-10, 10, 0.1)
y=(np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
plt.plot(x,y, color='r')
plt.text(-3.0, 0.9, r'$y=tanh(x)')
plt.show()
统计随机生成矩阵中有多少个元素大于0?
假设使用np.random.randn生成了随机数构成的矩阵:
p = np.random.randn(10, 10)
请写一段程序统计其中有多少个元素大于0?
提示:可以试下使用 $q = (p > 0)$,观察$q$是什么的数据类型和元素的取值。
提交方式:提交计算的代码,能够直接运行输出统计出来的结果。
import numpy as np
p = np.random.randn(10, 10)
s = np.extract(p>0, p)
print(s.size)