在上一篇帖子中,为了更好地理解深度学习是怎么样工作的,我们没有使用强大的深度学习的框架,而现在我们将使用MXnet提供的gluon接口简洁地实现上一篇帖子的内容,我也会尽可能解释上一篇省略了的内容。 1.生成数据集 我们将生成与上一篇贴子里完全一样的数据集。
2.读取数据集 上一篇帖子中,为了读取数据集,我们创建了data_iter函数。而这次通过gluon,我们不用再费力去完成这个函数了。gluon提供data包来读取数据。(注意:由于data容易用于作为变量名所以此处用import data as gdata。调用库的时候,如果名字非常常见且容易想到,最好用这种方法改一改。) 这里我们只用了两行代码就完成了data_iter函数的构建,而在上个帖子中我们花了七行。 dataset=gdata.ArrayDataset(features,labels)你可以理解为将很多个[x1,x2]和它们对应的y打包成一个个小盒子装进一个加做dataset的大仓库里,也就是数据集。 data_iter=gdata.DataLoader(dataset,batch_size,shuffle=True)你可以理解为从名为dataset的大仓库里随机拿出一定数量的小盒子,数量是由batch_size的值来确定的,而shuffle=True则告诉函数我们要随机抽取。 我们可以用for循环来看一看随机抽到的一批数据: 在这个for循环中,我们把抽取到的盒子一个一个拆开,将所有的[x1 ,x2]按循环顺序打印出来,所有的y按循环顺序打印出来,其中X(X=[x1,x2])和y的顺序是一一对应的。 3.定义模型 在完成数据集和读取数据函数的构建后,我们来定义模型。 首先,导入nn模块,nn是nerual networks (神经网络)的缩写。我们先定义一个模型变量net,它是一个Sequential实例。 (解释一下Sequential是什么意思,在一般的语境中:Sequential意指按时间或逻辑上的顺序发生的事物。比如,“sequential process”指的是一个步骤接着一个步骤的过程;“sequential order”指的是按特定顺序排列的事物。在神经网络中:Sequential模型是一种简单的网络结构,其中层按顺序依次排列,数据从输入层开始,经过每一层的处理,最终到达输出层。这种模型的特点是数据流动是线性的,没有分支或合并。适合于简单的前馈网络。) 在gluon中,sequential实例可以看作是一个串联各层的容器,在构建模型时,我们在该层的容器中依次添加层,在给定输入数据时,容器中的每一层将依次计算并将输出作为下一层的输入。 为了帮助理解,接下来给出线性回归的神经网络图,通过这个图我们能直观地感受到它是个单层神经网络。
在图中的神经网络中,输入层有多少个x就有多少个输入个数,输入个数也叫做特征数或特征维度向量。图中网络的输入为o,输出层的输入个数为1。输出层中负责计算o的单位又叫神经元。在线性回归中,o的计算依赖于x1,x2,.....xn,简单地说就是输出层地神经元与输入层中各种输入完全连接,因此,这里地输出层又叫全连接层或稠密层。输出层是不作为层数计算的,所以图中的线性回归神经网络是单层神经网络。 让我们回到代码上,我们已经知道线性回归中输出层是一个全连接层,而在gluon中,全连接层是一个dense实例。(事实上dense层就是全连接层地意思,而dense在英文中有密度的意思,所以全连接层也被叫做稠密层。)现在,我们用代码定义该层输出个数为1:net.add(nn.Dense(1))。 4. 初始化模型参数 在使用神经网络之前,我们需要初始化参数模型,比如线性回归中的权重w和偏差b。我们从MXNet导入init(initializer的缩写,意思是初始化器)模块,该模块提供了各种模型参数初始化的方法。(为什么需要关注初始化的方法?答:如果初始化得不好,所有权重都相同或太大、太小,可能导致训练中的问题,如:梯度消失或梯度爆炸:权重过大或过小,可能导致反向传播时梯度更新不稳定。对称性问题:如果所有权重被初始化为相同的值,网络中每个神经元就会执行相同的计算,无法学习多样化的特征。)
这里我们采取随机初始化的方法。我们通过net.initialize(init.Normal(sigma=0.01))指定权重参数每个元素将在初始化时随机采样于均值为0,标准差为0.01的正态分布。 5. 定义损失函数 在gluon中,loss模块定义了各种损失函数,就跟上文中将data改名为gdata一样,这里把loss改名为gloss,并直接使用他提供的平方损失函数(也叫均方误差)。
6. 定义优化算法 现在我们也不需要再去写个函数实现小批量梯度随机下降了。导入gluon后直接创建一个trainer实例,并指定学习率为0.03的小批量梯度随机下降为优化算法。
7. 训练模型
我们将训练次数(迭代)次数设定为3。l代表着当前训练轮次的损失。 每次训练(迭代)中,代码从data_iter中获取小批量数据,计算损失,反向传播计算梯度,并更新模型参数。 我们可以看到后loss的值随着迭代次数变得越来越小。 8. 检验结果
可以看到训练得到的权重w和偏差b与真实值非常相近。 |