NNDL实验三

2023-12-17 09:40
文章标签 实验 nndl

本文主要是介绍NNDL实验三,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2.2线性回归

2.2.1数据集构建

构造一个小的回归数据集:
生成 150 个带噪音的样本,其中 100 个训练样本,50 个测试样本,并打印出训练数据的可视化分布。

import random
import torch
import matplotlib.pyplot as pltdef synthetic_data(w, b, num_examples,x_av=0,x_var=1,y_av=0,y_var=1):#torch.normal生成(均值,方差,形状)的高斯分布数据X = torch.normal(x_av, x_var, (num_examples, len(w)))#这里是x的分布y = torch.matmul(X, w) + b#进行线性变换y += torch.normal(y_av,y_var, y.shape)#这里是y加上变换之后的线性值得偏移return X, y.reshape((-1, 1))true_w = torch.tensor([3.4])
true_b = torch.tensor([4.2])
train_features, train_labels = synthetic_data(true_w, true_b, 100)#训练集
test_features,test_labels=synthetic_data(true_w,true_b,50)#测试集
#创建直线数据
start_train=min(train_features)#以下是取训练集的最大最小值显示未添加高斯噪声的直线
end_train=max(train_features)
line_x=torch.linspace(start_train[0],end_train[0],100)
line_y=torch.matmul(line_x.reshape((-1,1)), true_w) + true_b
#绘图
plt.scatter(train_features,train_labels,s=10,label='train data')
plt.scatter(test_features,test_labels,s=10,c='r',label='test data')
plt.plot(line_x,line_y,c='gray')
plt.legend()#显示标签
plt.show()

输出的图像,因为直线是取得训练集(蓝色)的端点值所以有些红点在直线范围之外

2.2.2模型构建

y = X w + b ( 1 ) y=Xw+b\quad(1) y=Xw+b(1)
其中 X ∈ R N × D \boldsymbol{X}\in\mathbb{R}^{N\times D} XRN×D N \boldsymbol{N} N个样本的特征矩阵, y ∈ R N \boldsymbol{y}\in\mathbb{R}^{N} yRN个预测值组成的列向量。或者写为 f ( x ; θ ) = w ⊤ X + b f(x;\theta)=w^{\top}\boldsymbol{X}+b f(x;θ)=wX+b其中 θ \theta θ包含参数 w w w b b b

def linreg(X, w, b): #@save"""线性回归模型"""return torch.matmul(X, w) + b

2.2.3损失函数

均方误差(mean-square error, MSE)
L ( y , y ^ ) = 1 2 N ∥ y − y ^ ∥ 2 = 1 2 N ∥ X w + b − y ∥ 2 ( 2 ) \mathcal{L}(y,\hat{y})=\frac{1}{2N}\|y-\hat{y}\|^2=\frac{1}{2 N}\|\boldsymbol{X} \boldsymbol{w}+\boldsymbol{b}-\boldsymbol{y}\|^2 \quad(2) L(y,y^)=2N1yy^2=2N1Xw+by2(2)

def squared_loss(y_hat, y): #@save"""均⽅损失"""return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2

其中 y y y ( 1 ) (1) (1)式给出为 N N N个样本的真实标签, y ^ \hat y y^为预测值标签
均方误差除以2的原因为在求导的时候会和指数的平方相抵消以便于书写,在2.2.4中我们可以看到

2.2.4模型优化

经验风险 ( Empirical Risk ),即在训练集上的平均损失。
均方误差对参数 b b b做偏导得到:
∂ L ( y , y ^ ) ∂ b = 1 T ( X w + b − y ) ( 3 ) \frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{y})}{\partial b}=\mathbf{1}^T(\boldsymbol{X} \boldsymbol{w}+\boldsymbol{b}-\boldsymbol{y})\quad(3) bL(y,y^)=1T(Xw+by)(3)
∂ L ( y , y ^ ) ∂ w = ( X − x ˉ T ) T ( ( X − x ˉ T ) w − ( y − y ˉ ) ) ( 4 ) \frac{\partial \mathcal{L}(y, \hat{y})}{\partial w}=\left(X-\bar{x}^T\right)^T\left(\left(X-\bar{x}^T\right) w-(y-\bar{y})\right) \quad(4) wL(y,y^)=(XxˉT)T((XxˉT)w(yyˉ))(4)
令上式等于零得到:
b ∗ = y ˉ − x ˉ T ( 5 ) b^*=\bar{y}-\bar{x}^T \quad(5) b=yˉxˉT(5)
w ∗ = ( ( X − x ˉ T ) T ( X − x ˉ T ) ) − 1 ( X − x ˉ − T ) T ( y − y ˉ ) ( 6 ) w^*=\left(\left(\boldsymbol{X}-\bar{x}^T\right)^T\left(\boldsymbol{X}-\bar{x}^T\right)\right)^{-1}\left(X-\bar{x}^{-T}\right)^T(y-\bar{y})\quad(6) w=((XxˉT)T(XxˉT))1(XxˉT)T(yyˉ)(6)

1)此处省略了 1 N \frac{1}{N} N1并没有很大,经验风险是为了求解w和b的最优值,通过偏导为零的求解方法,式子前的常数并不影响最终的结果,可以将squared_loss函数的表达式改写就可以了
2)最小二乘法是用一个超平面去拟合点集,其本质是对误差函数的优化问题所以在这种简单的模型里解析法和梯度下降法都可以完成如2.2.5中看到的’

2.2.5模型训练

在这里只不过对于最优的参数值的求解方法不同

#代码来自李沐的书,这里的梯度下降用的Torch所以其实没有自己写梯度下降的过程
def synthetic_data(w, b, num_examples): """⽣成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))# 这些样本是随机读取的,没有特定的顺序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices = torch.tensor(indices[i: min(i + batch_size, num_examples)])yield features[batch_indices], labels[batch_indices]def sgd(params, lr, batch_size): """⼩批量随机梯度下降"""with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()def derect_loss(y_hat,y):
'''直接误差'''return (y_hat - y.reshape(y_hat.shape))
#生成数据的w和
true_w = torch.tensor([2, -3.4,10,1.1])
true_b = 4.2
#生成数据和标签
features, labels = synthetic_data(true_w, true_b, 100)
features_test, labels_test = synthetic_data(true_w, true_b, 50)
#为w,b,学习率,小批量个数进行初始化,这里的requires_grad
w = torch.normal(0, 0.01, size=(4,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
lr = 0.03
num_epochs = 3
#选择线性回归模型和均方误差函数
net = linreg
loss = squared_loss
#训练
for epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y)  # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.sum().backward()#在这里w.grad和b.grad才有值得只有在调用.backward方法后w,b的grad才更新,为了下次的导数正确sgd里做了处理sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')
#输出误差
print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差: {true_b - b}')
w的估计误差: tensor([ 2.1696e-05, -2.4271e-04,  7.9155e-05, -3.3510e-04],grad_fn=<SubBackward0>)
b的估计误差: tensor([0.0006], grad_fn=<RsubBackward1>)

可以看到这的w和b的反向传播函数并不相同,这两种方法在于对参数的求导的路径在Torch里实现的不同

2.2.6模型评估

for X, y in data_iter(100, features_test, labels_test):l = derect_loss(linreg(X, w, b), y)  # X和y的小批量损失
l=l.reshape(1,-1)[0]
c=[]
for i in l:c.append(float(i))
print('y平均误差:'sum(c)/len(c))
tensor([[ 2.0000],[-3.4002],[ 9.9998],[ 1.0997]], requires_grad=True) tensor([4.1998], requires_grad=True)
epoch 10, loss 0.000049
len_features: 50
y平均误差:0.0008958221971988678

2.2.7样本数量&正则化系数

调整样本数量

features, labels = synthetic_data(true_w, true_b, 1000)
w的估计误差: tensor([-1.1110e-04,  4.1342e-04, -3.6240e-05, -2.4235e-04],grad_fn=<SubBackward0>)
b的估计误差: tensor([-0.0002], grad_fn=<RsubBackward1>)

对参数w加上ℓ2正则化,则最优的w∗变为
w ∗ = ( ( X − x ˉ T ) T ( X − x T ) + λ I ) − 1 ( X − x ˉ T ) T ( y − y ˉ ) ( 7 ) w^*=\left(\left(\boldsymbol{X}-\bar{x}^T\right)^T\left(\boldsymbol{X}-\boldsymbol{x}^T\right)+\lambda I\right)^{-1}\left(\boldsymbol{X}-\bar{x}^T\right)^T(y-\bar{y})\quad(7) w=((XxˉT)T(XxT)+λI)1(XxˉT)T(yyˉ)(7)
上式是对于解析求解的时候用的比较多其实这里用的是 ∑ i = 1 n ( y i − y ^ ) 2 = ∑ i = 1 n ( y i − ∑ j = 1 k ( w j x i j ) − b ) 2 + λ ∑ j = 1 p w j 2 ( 8 ) \sum_{i=1}^n\left(y_i-\hat{y}\right)^2=\sum_{i=1}^n\left(y_i-\sum_{j=1}^k\left(w_j x_{i j}\right)-b\right)^2+\lambda \sum_{j=1}^p w_j^2\quad(8) i=1n(yiy^)2=i=1n(yij=1k(wjxij)b)2+λj=1pwj2(8)

调整正则化系数

def l2_squared_loss(y_hat,y,w,reg_lambda=2):#print(y_hat,y,w)return ((y_hat - y.reshape(y_hat.shape)) ** 2).sum() +reg_lambda*(w**2).sum()#将本来在loss之外的.sum()移动到里面方便计算
loss=l2_squared_loss
for epoch in range(num_epochs):for X, y in data_iter(batch_size,features, labels):l = loss(net(X, w, b), y,w,reg_lambda=2)  # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.backward()sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels,w,reg_lambda=2)print(w,b)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')#当然这里的mean()就是对一个数求和了改不改都行
print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差: {true_b - b}')
tensor([[ 1.5925],[-2.7842],[ 8.1125],[ 0.8044]], requires_grad=True) tensor([4.0725], requires_grad=True)
epoch 10, loss 4022.816406
w的估计误差: tensor([ 0.4075, -0.6158,  1.8875,  0.2956], grad_fn=<SubBackward0>)
b的估计误差: tensor([0.1275], grad_fn=<RsubBackward1>)

2.3多项式回归

多项式回归是回归任务的一种形式,其中自变量和因变量之间的关系是 M M M 次多项式的一种线性回归形式, 即:
f ( x ; w ) = w 1 x + w 2 x 2 + … + w M x M + b = w T ϕ ( x ) + b ( 9 ) f(\boldsymbol{x} ; \boldsymbol{w})=w_1 x+w_2 x^2+\ldots+w_M x^M+b=w^T \phi(x)+b\quad(9) f(x;w)=w1x+w2x2++wMxM+b=wTϕ(x)+b(9)
其中 M M M 为多项式的阶数, w = [ w 1 , … , w M ] T w=\left[w_1, \ldots, w_M\right]^T w=[w1,,wM]T 为多项式的系数, ϕ = [ x , x 2 , ⋯ , x M ] ⊤ \phi=\left[x,x^2,\cdots,x^M\right]^{\top} ϕ=[x,x2,,xM] 为多项式基函数,将原始特征 x x x映射为 M M M维的向量。当 M = 0 M=0 M=0 时, f ( x ; w ) = b f(x ; w)=b f(x;w)=b.
公式(2.10)展示的是特征维度为1的多项式表达,当特征维度大于1时,存在不同特征之间交互的情况,这是线性回归无法实现。公式(2.11)展示的是当特征维度为2,多项式阶数为2时的多项式回归: f ( x ; w ) = w 1 x 1 + w 2 x 2 + w 3 x 1 2 + w 4 x 1 x 2 + w 5 x 2 2 + b ( 10 ) f(\boldsymbol{x} ; \boldsymbol{w})=w_1 x_1+w_2 x_2+w_3 x_1^2+w_4 x_1 x_2+w_5 x_2^2+b\quad(10) f(x;w)=w1x1+w2x2+w3x12+w4x1x2+w5x22+b(10)
当自变量和因变量之间并不是线性关系时,我们可以定义非线性基函数对特征进行变换,从而可以使得线性回归算法实现非线性的曲线拟合。

2.3.1数据集的构建

import math
def sin(x):y = torch.sin(2 * math.pi * x)return ydef synthetic_data(num_examples): #@save"""⽣成y=Xw+b+噪声"""X = torch.normal(0, 0.3, (num_examples, 1))y = sin(X)y += torch.normal(0, 0.001, y.shape)print(X,y)return X, y.reshape((-1, 1))

请添加图片描述

2.3.2模型的构建

def multinomial_func(x,w,b):'''多项式模型'''len_w=len(w)print(len_w)s_x_t=torch.tensor([],requires_grad=True)for i in range(len_w):x_lp=x**(i+1)s_x_t=torch.cat([s_x_t,x_lp],dim=1)y = torch.matmul(s_x_t,w)+breturn y

在这里将w的输入作为多项式的系数,直接决定输入多项式的阶数

2.3.4模型的评估

#初始化参数
w = torch.normal(0, 1, size=(5,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
lr = 0.03
loss=squared_loss
net=multinomial_func
loss=squared_loss
num_epochs=1
batch_size=10
#训练
for epoch in range(num_epochs):for X, y in data_iter(batch_size,train_features,train_labels):l = loss(net(X, w, b), y)  # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.sum().backward()sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(train_features, w, b), train_labels)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')#画图
len_w=len(w)
x=torch.arange(-1,1,0.001);
y=x*float(w[0])
for i in range(1,len_w):print(i,'---',float(w[i])*x**(i+1))y+=float(w[i])*x**(i+1)
plt.scatter(train_features,train_labels)
plt.plot(x,y)
plt.show()
epoch 1, loss 0.226177
epoch 2, loss 0.352603
epoch 3, loss 0.191461
epoch 4, loss 0.268661
epoch 5, loss 0.264049
tensor([[ 5.1442],[-1.3861],[-7.7268],[-0.7148],[-2.8089]], requires_grad=True) tensor([0.0937], requires_grad=True)

请添加图片描述

训练100轮:

tensor([[  6.7778],[ -1.4367],[-31.4881],[ -0.3723],[ 26.5089]], requires_grad=True) tensor([4.1800], requires_grad=True)

请添加图片描述

使用l2正则之后:

epoch 1, loss 0.180026
epoch 2, loss 0.181556
epoch 3, loss 0.193719
epoch 4, loss 0.219088
epoch 5, loss 0.157274
epoch 6, loss 0.168881
epoch 7, loss 0.109541
epoch 8, loss 0.108288
epoch 9, loss 0.125714
epoch 10, loss 0.099660
epoch 10, loss 0.099660
tensor([[ 2.4389],[ 1.0662],[-9.9077],[ 0.1167],[ 8.2819]], requires_grad=True) tensor([-0.2337], requires_grad=True)

效果反而会较差一些
请添加图片描述

2.4Runner类

这里就修改邱锡鹏老师的代码:

import torch
import osclass Runner(object):def __init__(self, model, optimizer, loss_fn, metric):# 优化器和损失函数为None,不再关注# 模型self.model = model# 评估指标self.metric = metric# 优化器self.optimizer = optimizerdef train(self, dataset, reg_lambda, model_dir):X, y = datasetself.optimizer(self.model, X, y, reg_lambda)# 保存模型self.save_model(model_dir)def evaluate(self, dataset, **kwargs):X, y = datasety_pred = self.model(X)result = self.metric(y_pred, y)return resultdef predict(self, X, **kwargs):return self.model(X)def save_model(self, model_dir):if not os.path.exists(model_dir):os.makedirs(model_dir)params_saved_path = os.path.join(model_dir, 'params.pdtensor')torch.save(self.model.params, params_saved_path)def load_model(self, model_dir):params_saved_path = os.path.join(model_dir, 'params.pdtensor')self.model.params = torch.load(params_saved_path)

2.5基于线性回归的波士顿房价预测

2.5.1数据处理

import pandas as pd
data=pd.read_csv("boston_house_prices.csv")
        CRIM    ZN  INDUS  CHAS    NOX     RM   AGE     DIS  RAD  TAX  \
0    0.00632  18.0   2.31     0  0.538  6.575  65.2  4.0900    1  296   
1    0.02731   0.0   7.07     0  0.469  6.421  78.9  4.9671    2  242   
2    0.02729   0.0   7.07     0  0.469  7.185  61.1  4.9671    2  242   
3    0.03237   0.0   2.18     0  0.458  6.998  45.8  6.0622    3  222   
4    0.06905   0.0   2.18     0  0.458  7.147  54.2  6.0622    3  222   
..       ...   ...    ...   ...    ...    ...   ...     ...  ...  ...   
501  0.06263   0.0  11.93     0  0.573  6.593  69.1  2.4786    1  273   
502  0.04527   0.0  11.93     0  0.573  6.120  76.7  2.2875    1  273   
503  0.06076   0.0  11.93     0  0.573  6.976  91.0  2.1675    1  273   
504  0.10959   0.0  11.93     0  0.573  6.794  89.3  2.3889    1  273   
505  0.04741   0.0  11.93     0  0.573  6.030  80.8  2.5050    1  273   PTRATIO  LSTAT  MEDV  
0       15.3   4.98  24.0  
1       17.8   9.14  21.6  
2       17.8   4.03  34.7  
3       18.7   2.94  33.4  
4       18.7   5.33  36.2  
..       ...    ...   ...  
501     21.0   9.67  22.4  
502     21.0   9.08  20.6  
503     21.0   5.64  23.9  
504     21.0   6.48  22.0  
505     21.0   7.88  11.9  [506 rows x 13 columns]
2.5.1.2数据清洗
print(data.isna().sum())#查看没个标签下的缺失值得情况
CRIM       0
ZN         0
INDUS      0
CHAS       0
NOX        0
RM         0
AGE        0
DIS        0
RAD        0
TAX        0
PTRATIO    0
LSTAT      0
MEDV       0
dtype: int64
#借鉴邱锡鹏
# 箱线图查看异常值分布
def boxplot(data, fig_name):# 绘制每个属性的箱线图data_col = list(data.columns)# 连续画几个图片plt.figure(figsize=(5, 5), dpi=300)# 子图调整plt.subplots_adjust(wspace=0.6)# 每个特征画一个箱线图for i, col_name in enumerate(data_col):plt.subplot(3, 5, i + 1)# 画箱线图plt.boxplot(data[col_name],showmeans=True,meanprops={"markersize": 1, "marker": "D", "markeredgecolor": '#f19ec2'},  # 均值的属性medianprops={"color": '#e4007f'},  # 中位数线的属性whiskerprops={"color": '#e4007f', "linewidth": 0.4, 'linestyle': "--"},flierprops={"markersize": 0.4},)# 图名plt.title(col_name, fontdict={"size": 5}, pad=2)# y方向刻度plt.yticks(fontsize=4, rotation=90)plt.tick_params(pad=0.5)# x方向刻度plt.xticks([])plt.savefig(fig_name)plt.show()num_features = data.select_dtypes(exclude=['object', 'bool']).columns.tolist()for feature in num_features:if feature == 'CHAS':continueQ1 = data[feature].quantile(q=0.25)  # 下四分位Q3 = data[feature].quantile(q=0.75)  # 上四分位IQR = Q3 - Q1top = Q3 + 1.5 * IQR  # 最大估计值bot = Q1 - 1.5 * IQR  # 最小估计值values = data[feature].valuesvalues[values > top] = top  # 临界值取代噪声values[values < bot] = bot  # 临界值取代噪声data[feature] = values.astype(data[feature].dtypes)

在处理完异常值之后:
请添加图片描述

2.5.1.3数据集划分
def train_test_split(X, y, train_percent=0.8):n = len(X)shuffled_indices = torch.randperm(n)  # 返回一个数值在0到n-1、随机排列的1-D Tensortrain_set_size = int(n * train_percent)train_indices = shuffled_indices[:train_set_size]test_indices = shuffled_indices[train_set_size:]X = X.valuesy = y.valuesX_train = X[train_indices]y_train = y[train_indices]X_test = X[test_indices]y_test = y[test_indices]return X_train, X_test, y_train, y_testX = data.drop(['MEDV'], axis=1)
y = data['MEDV']X_train, X_test, y_train, y_test = train_test_split(X, y)  # X_train每一行是个样
2.5.1.4特征工程
#特征工程
X_train = torch.tensor(X_train,dtype=torch.float32)
X_test = torch.tensor(X_test,dtype=torch.float32)
y_train = torch.tensor(y_train,dtype=torch.float32)
y_test = torch.tensor(y_test,dtype=torch.float32)X_min = torch.min(X_train,dim=0)[0]
X_max = torch.max(X_train,dim=0)[0]X_train = (X_train-X_min)/(X_max-X_min)
X_test  = (X_test-X_min)/(X_max-X_min)# 训练集构造
train_dataset=(X_train,y_train)
# 测试集构造
test_dataset=(X_test,y_test)

2.5.2模型构建

def linreg(X, w, b): #@save"""线性回归模型"""return torch.matmul(X, w) + b

2.5.2Runner类,算子

import torch
torch.manual_seed(10) #设置随机种子class Op(object):def __init__(self):passdef __call__(self, inputs):return self.forward(inputs)def forward(self, inputs):raise NotImplementedErrordef backward(self, inputs):raise NotImplementedError# 线性算子
class Linear(Op):def __init__(self, input_size):"""输入:- input_size:模型要处理的数据特征向量长度"""self.input_size = input_size# 模型参数self.params = {}self.params['w'] = torch.randn(size=[self.input_size, 1], dtype=torch.float32)self.params['b'] = torch.zeros(size=[1], dtype=torch.float32)def __call__(self, X):return self.forward(X)# 前向函数def forward(self, X):"""输入:- X: tensor, shape=[N,D]注意这里的X矩阵是由N个x向量的转置拼接成的,与原教材行向量表示方式不一致输出:- y_pred: tensor, shape=[N]"""N, D = X.shapeif self.input_size == 0:return torch.full(size=[N, 1], fill_value=self.params['b'])assert D == self.input_size  # 输入数据维度合法性验证# 使用torch.matmul计算两个tensor的乘积y_pred = torch.matmul(X, self.params['w']) + self.params['b']return y_pred

2.5.4模型训练

lr = 0.03
num_epochs = 100
batch_size = 10
net = linreg
loss = squared_loss
w = torch.normal(0, 0.01, size=(12,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
print(w,b)
for epoch in range(num_epochs):for X, y in data_iter(batch_size,X_train, y_train):#print('load',X,y)l = loss(net(X, w, b), y)  # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.sum().backward()sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数#print(w,b)with torch.no_grad():train_l = loss(net(X_train, w, b), y_train)print(w,b)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')
tensor([[ -4.2613],[  1.0628],[  0.5212],[  2.1252],[ -3.0859],[ 14.2895],[ -0.3103],[ -3.6776],[  3.6394],[ -2.7991],[ -4.5872],[-10.7750]], requires_grad=True) tensor([24.1869], requires_grad=True)
epoch 100, loss 6.996277

2.5.5模型测试```python

for X, y in data_iter(batch_size,X_test, y_test):#print('load',X,y)l_x = loss(net(X, w, b), y)print(f'loss {float(l_x.mean()):f}')y=net(X,w,b)print(y)
loss 7.047848
tensor([[14.2231],[ 5.7950],[18.9050],[15.4746],[28.3919],[14.6761],[16.7302],[10.4911],[24.8447],[26.0152]], grad_fn=<AddBackward0>)
loss 2.432737
tensor([[19.2010],[20.0434],[24.9964],[14.2848],[35.3022],[27.2165],[26.8912],[18.1415],[26.5540],[19.6659]], grad_fn=<AddBackward0>)
loss 4.868561
tensor([[ 9.8344],[22.0588],[28.4817],[28.0053],[25.5395],[19.2421],[15.3564],[34.6426],[17.0798],[12.5536]], grad_fn=<AddBackward0>)
loss 2.791060
tensor([[22.6083],[26.6892],[16.5962],[22.2141],[23.9226],[22.1962],[17.9146],[30.6747],[24.2466],[21.9983]], grad_fn=<AddBackward0>)
loss 4.287356
.......

2.5.6模型预测

yy=y-y_test
yy=yy.reshape(-1,1)
xx=torch.arange(0,len(yy),1)
print(xx.detach().numpy(),'---',yy.detach().numpy())
plt.plot(xx.detach().numpy(),yy.detach().numpy())

请添加图片描述

2.6感想

这些代码使用torch就是用的梯度下降算法,不得不说最主要的就是梯度下降的算法,干脆梯度下降也别用torch了呗,而梯度下降决定了网络可能的形状。
关于op和runner类我只是写了没用,主要是觉得缺点什么先放着
在多项式拟合的时候容易不收敛,对于不同的初始值不容易收敛到最优值,容易陷入局部值,不得说可能是参数量或者数据集不够的问题,感觉可以改改梯度下降。(瞎说的<_<)

这篇关于NNDL实验三的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/503909

相关文章

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

61.以太网数据回环实验(4)以太网数据收发器发送模块

(1)状态转移图: (2)IP数据包格式: (3)UDP数据包格式: (4)以太网发送模块代码: module udp_tx(input wire gmii_txc ,input wire reset_n ,input wire tx_start_en , //以太网开始发送信

LTspice模拟CCM和DCM模式的BUCK电路实验及参数计算

关于BUCK电路的原理可以参考硬件工程师炼成之路写的《 手撕Buck!Buck公式推导过程》.实验内容是将12V~5V的Buck电路仿真,要求纹波电压小于15mv. CCM和DCM的区别: CCM:在一个开关周期内,电感电流从不会到0. DCM:在开关周期内,电感电流总会到0. CCM模式Buck电路仿真: 在用LTspice模拟CCM电路时,MOS管驱动信号频率为100Khz,负载为10R(可自

HCIA--实验十:路由的递归特性

递归路由的理解 一、实验内容 1.需求/要求: 使用4台路由器,在AR1和AR4上分别配置一个LOOPBACK接口,根据路由的递归特性,写一系列的静态路由实现让1.1.1.1和4.4.4.4的双向通信。 二、实验过程 1.拓扑图: 2.步骤: (下列命令行可以直接复制在ensp) 1.如拓扑图所示,配置各路由器的基本信息: 各接口的ip地址及子网掩码,给AR1和AR4分别配置

OpenGL/GLUT实践:流体模拟——数值解法求解Navier-Stokes方程模拟二维流体(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 流体模拟实现2.1.1 网格结构2.1.2 数据结构2.1.3 程序结构1) 更新速度场2) 更新密度值 2.1.4 实现效果 2.2 颜色设置2.2.1 颜色绘制2.2.2 颜色交互2.2.3 实现效果 2.3 障碍设置2.3.1 障碍定义2.3.2 障碍边界条件判定2.3.3 障碍实现2.3.

pta-2024年秋面向对象程序设计实验一-java

文章申明:作者也为初学者,解答仅供参考,不一定是最优解; 一:7-1 sdut-sel-2 汽车超速罚款(选择结构) 答案: import java.util.Scanner;         public class Main { public static void main(String[] arg){         Scanner sc=new Scanner(System

如何校准实验中振镜频率的漂移

在实验过程中,使用共振扫描振镜(如Cambridge Technology的8kHz振镜)时,频率漂移是一个常见问题,尤其是在温度变化或长期运行的情况下。为了确保实验的准确性和稳定性,我们需要采取有效的校准措施。本文将介绍如何监测、调节和校准振镜频率,以减少漂移对实验结果的影响。 1. 温度管理和稳定性控制 振镜的频率变化与温度密切相关,温度的升高会导致机械结构的变化,进而影响振镜的共

实验C语言“union”的最基础语法

目标 最近在看Rust的“菜鸟教程”,看到 Rust 枚举类 时我发现它所定义的“枚举类”虽然也能像C语言枚举类那样使用,但是多了些功能:对于某个枚举的成员,还可以附带独特的数据,这让我想起了C语言中的union。 而我事实上对union没有使用经验,我自己写程序的时候不用它,看其他的项目的程序时印象里也没见过它。所以我对union的设计意图理解不深(可能只是为了节省内存?)。本篇的目标是对其

Oracle高级压缩和透明数据加密组合实验

本文参考了实验DB Security - Advanced Compression with Transparent Data Encryption(TDE),其申请地址在这里。 本文只使用了实验中关于高级压缩和在线重定义的部分。并对要点进行说明及对实验进行了简化。 准备:环境设置 原文中的实验环境实际上是改自Oracle示例Sample Schema,其实唯一的改动就是去掉了SALES表中