1. 生成数据集
我们生成一个包含1000个样本的数据集, 每个样本包含从标准正态分布中采样的2个特征。 我们的合成数据集是一个矩阵
函数synthetic_data()接收线性模型的w,b以及要生成的样本的数量为参数,创建样本的特征矩阵X以及标签向量y,分别返回:
torch.normal(0,1,(nums_examples,len(w)))生成均值为0,方差为1,形状为(nums_examples,len(w))的随机正太分布数据,作为样本的特征矩阵。注意这特征值和标签值都是随机生成的,这是没有任何现实意义的数据集,仅作为熟悉线性回归流程的工具。
注意:如果返回y的时候直接返回y,而不是返回y.reshape(-1,1),会出现这样的问题:X的维度是(nums_examples,len(w)),w的维度是(len(w)),matmul(X,w)下来维度是(nums_examples),而不是(nums_examples,1)。而我们想要的维度是(nums_examples,1)。注意,矩阵向量积虽然mv(X,w)和matmul(X,w)结果是一样的,它们在处理的过程中会将w的维度变成(len(w),1),与X进行计算,但算完了保存结果时,结果的维度是(nums_examples)的。
2. 读取数据集
我们定义一个函数data_iter(batch_size,features,labels),传入整个数据集的features,labels,以及我们每次要读取的batch_size的大小,使用yield让这个函数循环地返回每个batch_size的features以及labels:
首先,我们使用num_examples = len(features)获取整个数据集的样本的个数,然后,创建随机访问的索引indices,函数random.shuffle(indices)用于将列表indices中的数据随机打乱。yield关键词用于返回features[batch_indices]和labels[batch_indices]的值,并与下面的for循环联动,将这些值循环地传入X,y中。
3. 初始化模型参数
注意到模型的参数为w和b。我们将w初始化为均值为0,方差为0.01的正态分布,将b初始化为0:
4. 定义模型
模型的定义是,给定我们输入特征X,以及参数w,b,用来输出样本标注y的函数:
注意,上面的Xw是一个向量,而b是一个标量(Xw和b都是张量),计算Xw+b时,会采用广播机制,Xw的每一个值都会加上b。
5. 定义损失函数
损失函数的定义是,传入真实值y和估计值y_hat,返回在定义的损失函数下的损失的过程。
这里面我们把y给reshape成了y_hat的形状,是为了保证万无一失。(在本例中不reshape也能正常运行)
6. 定义优化算法
优化算法是传入模型的全部参数、学习率以及 batch_size,各个参数根据自己的梯度优化自己的过程:
这里要加with torch.no_grad():,表示下面的过程不需要计算梯度,不加就会报错,暂时搞不清楚什么原因;
注意参数更新完之后,一定要把它们的梯度清零,以便下一个batch_size的训练。
7. 训练
我们首先定义学习率、batch_size、num_epochs,即要训练多少个epoch。
这里面[w,b]是一个list,它的两个元素都是torch.tensor类型的,w是一个有两个元素的tensor,b是一个标量tensor。
对于{float(train_l.mean()):f},用float是将它从tansor强制转换成float型,冒号f,即":f"的意思是要将这个float型变量用六位小数输出。
可以看到,我们每次取出来一个batch_size,都是可以对全局所有的参数进行更新的。
标签:nums,batch,len,维度,001,从零开始,examples,线性,size From: https://www.cnblogs.com/pkuqcy/p/17402847.html