第一章:零基础入门深度学习
到今天早上才学习完第一章零基础入门深度学习,在上周我才开始接触python,所以对于代码的理解需要费一些功夫,在看到一个新的函数、新的库都要去搜索学习。
但好在飞桨的课程真的是逐步讲解深度学习的每一个步骤与过程,我也跟着学习理解了这个过程。
由于我的专业是数学系,所以对于一些理论推的理解也吸收较快。
概念理解
深度学习参考了人脑结构,运用了神经网络,他比机器学习、人工智能更加复杂,他集中于文字、图像及语言。
神经网络三个核心点:神经元(加权和、非线性变换——激活函数)、多层连接、正向计算(输出)和反向传播(更新参数)
波士顿房价预测任务(机器学习的‘hello world’)
模型:多元线性回归
模型构建:
数据处理:
在这里我们需要导入数据,并且对数据的形状进行一定的处理。接下来将数据集划分为训练集(80%)与测试集。接着将数据集进行归一化处理,这一点非常重要,他将和房价有关的13个参数进行归一化处理,一是使模型训练更高效;二是使特征前的权重大小可以代表该变量对预测结果的贡献度(因为每个特征值本身的范围相同)。最后将这些步骤封装为一个load_data函数。
模型设计(线性回归模型)
我们以类的方式实现前向计算。
1.使用时可生成多个模型案例
2.类成员变量有w和b,在类初始化函数中初始化变量(w随机初始化,b=0)
3.函数成员forward完成输入特征x到输出z的计算过程(即前向计算)
训练配置
通过损失函数Loss来衡量模型的好坏,通过训练配置寻找模型的最优值。
在这里我们选用均方误差,原因也在作业中进行了考核。
接下来我们使用Numpy的广播功能,实现多样本计算,计算Loss。
但我们要找的是能够使Loss达到最小的w和b,所以我们采用梯度下降法寻找合适的w和b。再通过反向运算,更新参数,实现此过程。
最后我们可以确定Loss最小的点。
将上述步骤封装入train函数。
下面我们进行代码实现:
(我会在后面 注解每一部分代码的用途)
import numpy as npimport jsonimport matplotlib.pyplot as plt#定义函数,进行数据处理def load_data():# 从文件导入数据datafile = \'housing.data\'#我将数据和代码放在一个文件夹内data = np.fromfile(datafile, sep=\' \')# 每条数据包括14项,其中前面13项是影响因素,第14项是相应的房屋价格中位数feature_names = [ \'CRIM\', \'ZN\', \'INDUS\', \'CHAS\', \'NOX\', \'RM\', \'AGE\',\'DIS\', \'RAD\', \'TAX\', \'PTRATIO\', \'B\', \'LSTAT\', \'MEDV\' ]feature_num = len(feature_names)# 将原始数据进行Reshape,变成[N, 14]这样的形状data = data.reshape([data.shape[0] // feature_num, feature_num])# 将原数据集拆分成训练集和测试集# 这里使用80%的数据做训练,20%的数据做测试# 测试集和训练集必须是没有交集的ratio = 0.8offset = int(data.shape[0] * ratio)training_data = data[:offset]# 计算训练集的最大值,最小值,平均值maximums, minimums, avgs = training_data.max(axis=0), training_data.min(axis=0), \\training_data.sum(axis=0) / training_data.shape[0]# 对数据进行归一化处理,使参数的范围在0~1内for i in range(feature_num):#print(maximums[i], minimums[i], avgs[i])data[:, i] = (data[:, i] - avgs[i]) / (maximums[i] - minimums[i])# 训练集和测试集的划分比例training_data = data[:offset]test_data = data[offset:]return training_data, test_data#接下来去用类的结构进行模型设计class Network(object):def __init__(self, num_of_weights):# 随机产生w的初始值# 为了保持程序每次运行结果的一致性,此处设置固定的随机数种子np.random.seed(0)self.w = np.random.randn(num_of_weights, 1)self.b = 0.def forward(self, x):z = np.dot(x, self.w) + self.breturn zdef loss(self, z, y):error = z - ynum_samples = error.shape[0]cost = error * errorcost = np.sum(cost) / num_samplesreturn costdef gradient(self, x, y):z = self.forward(x)gradient_w = (z-y)*xgradient_w = np.mean(gradient_w, axis=0)gradient_w = gradient_w[:, np.newaxis]gradient_b = (z - y)gradient_b = np.mean(gradient_b)return gradient_w, gradient_bdef update(self, gradient_w, gradient_b, eta = 0.01):self.w = self.w - eta * gradient_wself.b = self.b - eta * gradient_bdef train(self, x, y, iterations=100, eta=0.01):losses = []for i in range(iterations):z = self.forward(x)L = self.loss(z, y)gradient_w, gradient_b = self.gradient(x, y)self.update(gradient_w, gradient_b, eta)losses.append(L)if (i+1) % 10 == 0: #十的倍数输出训练结果print(\'iter {}, loss {}\'.format(i, L))return losses# 获取数据train_data, test_data = load_data()x = train_data[:, :-1]y = train_data[:, -1:]# 创建网络net = Network(13)num_iterations=1000# 启动训练losses = net.train(x,y, iterations=num_iterations, eta=0.01)# 画出损失函数的变化趋势plot_x = np.arange(num_iterations)plot_y = np.array(losses)plt.plot(plot_x, plot_y)plt.show()
后续还有对梯度下降法的改进,我们采用随机梯度法进行计算。