神经网络与深度学习实验三线性回归

(大部分代码都是书上给好的,理解加整理写了一天,感觉收获很多)

1.简单线性模型,最小二乘法求解

依据神经网络与深度学习:案例与实践,大多数代码来自这本书,将paddle框架改为pytorch框架

import torch
import matplotlib.pyplot as plt
import numpy as np
torch.seed()  # 设置随机种子
def linear_func(x,w=1.2,b=0.5):# 回归数据集
    y = w*x + b
    return y
# 生成数据集
def create_toy_data(func, interval, sample_num, noise = 0.0, add_outlier = False, outlier_ratio = 0.001):
    """
    根据给定的函数,生成样本
    输入: func:函数 interval: x的取值范围 sample_num: 样本数目 noise: 噪声均方差 add_outlier:是否生成异常值 outlier_ratio:异常值占比
    输出: X: 特征数据,shape=[n_samples,1] y: 标签数据,shape=[n_samples,1]
    """
    # 均匀采样,使用torch.rand在生成sample_num个随机数
    X = torch.rand(size = [sample_num]) * (interval[1]-interval[0]) + interval[0]
    y = func(X)
    # 生成高斯分布的标签噪声
    # 使用torch.normal生成0均值,noise标准差的数据
    epsilon = torch.tensor(np.random.normal(0,noise,size=y.shape[0]))
    y = y + epsilon
    if add_outlier:     # 生成额外的异常点
        outlier_num = int(len(y)*outlier_ratio)
        if outlier_num != 0:
            # 使用torch.randint生成服从均匀分布的、范围在[0, len(y))的随机Tensor
            outlier_idx = torch.randint(len(y),shape = [outlier_num])
            y[outlier_idx] = y[outlier_idx] * 5
    return X, y
func = linear_func
interval = (-10,10)
train_num = 100 # 训练样本数目
test_num = 50 # 测试样本数目
noise = 2
X_train, y_train = create_toy_data(func=func, interval=interval, sample_num=train_num, noise = noise, add_outlier = False) # 训练集
X_test, y_test = create_toy_data(func=func, interval=interval, sample_num=test_num, noise = noise, add_outlier = False) # 测试集

X_train_large, y_train_large = create_toy_data(func=func, interval=interval, sample_num=5000, noise = noise, add_outlier = False)

# torch.linspace返回一个Tensor,Tensor的值为在区间start和stop上均匀间隔的num个值,输出Tensor的长度为num
X_underlying = torch.linspace(interval[0],interval[1],train_num)
y_underlying = linear_func(X_underlying)
plt.scatter(X_train, y_train, marker='*', facecolor="none", edgecolor='#e4007f', s=50, label="train data")
plt.scatter(X_test, y_test, facecolor="none", edgecolor='#f19ec2', s=50, label="test data")
plt.plot(X_underlying, y_underlying, c='#000000', label=r"underlying distribution")
plt.legend(fontsize='x-large')  # 给图像加图例
plt.show()
# 损失函数,基于均方误差
def mean_squared_error(y_true, y_pred):
    """
    输入:
       - y_true: tensor,样本真实标签
       - y_pred: tensor, 样本预测标签
    输出:
       - error: float,误差值
    """
    assert y_true.shape[0] == y_pred.shape[0]
    # torch.square计算输入的平方值
    # torch.mean沿 axis 计算 x 的平均值,默认axis是None,则对输入的全部元素计算平均值。
    error = torch.mean(torch.square(y_true - y_pred))
    return error
# 模型构建
class Op(object):#定义了一个基类 Op,用于实现操作(如神经网络中的前向和反向传播)init方法是构造函数call方法允许实例像函数一样被调用
    def __init__(self):
        pass
    def __call__(self, inputs):
        return self.forward(inputs)
    def forward(self, inputs):
        raise NotImplementedError
    def 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([self.input_size, 1])
        self.params['b'] = torch.zeros(1)
    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.shape
        if self.input_size == 0:
            return torch.full([N, 1], fill_value=self.params['b'])

        assert D == self.input_size  # 输入数据维度合法性验证
        # 使用paddle.matmul计算两个tensor的乘积
        y_pred = torch.matmul(X, self.params['w']) + self.params['b']
        return y_pred
# 模型优化
def optimizer_lsm(model, X, y, reg_lambda=0):
    N, D = X.shape
    # 确保 X 和 y 是相同的数据类型,张量数据类型不匹配导致错误
    X = X.float()
    y = y.float()
    # 计算输入特征的均值
    x_bar_tran = X.mean(dim=0, keepdim=True)
    # 计算标签的均值
    y_bar = y.mean()
    # 从输入中减去均值
    x_sub = X - x_bar_tran
    # 检查 x_sub 是否全为零
    if torch.all(x_sub == 0):
        model.params['b'] = y_bar
        model.params['w'] = torch.zeros(D, dtype=X.dtype)  # 使用与 X 相同的数据类型
        return model
    # 计算逆矩阵
    tmp = torch.inverse(torch.matmul(x_sub.T, x_sub) + reg_lambda * torch.eye(D, dtype=X.dtype))
    # 计算权重
    w = torch.matmul(tmp, x_sub.T @ (y - y_bar))
    # 计算偏置
    b = y_bar - torch.matmul(x_bar_tran, w)

    model.params['b'] = b
    model.params['w'] = w.squeeze(-1)

    return model
# 模型训练
input_size = 1
model = Linear(input_size)
model = optimizer_lsm(model,X_train.reshape([-1,1]),y_train.reshape([-1,1]))
print("w_pred:",model.params['w'].item(), "b_pred: ", model.params['b'].item())
y_train_pred = model(X_train.reshape([-1,1])).squeeze()
train_error = mean_squared_error(y_true=y_train, y_pred=y_train_pred).item()
print("train error: ",train_error)
# 模型评估
y_test_pred = model(X_test.reshape([-1,1])).squeeze()
test_error = mean_squared_error(y_true=y_test, y_pred=y_test_pred).item()
print("test error: ",test_error)

代码运行截图

 增加样本数量为10000再次运行

上述损失函数计算error未除2,将其除2后,运行结果为

模型优化采用经验风险最小化,线性回归可以通过最小二乘法求出参数w和b的解析式。x,y若为不同的数据类型,则在运行过程中会报错。

2.多项式回归

import math
import torch
import matplotlib.pyplot as plt
import numpy as np
# 所用线性回归相同的地方:算子,均方误差,优化,评估
class Op(object):# 定义了一个基类 Op,用于实现操作(如神经网络中的前向和反向传播)init方法是构造函数call方法允许实例像函数一样被调用
    def __init__(self):
        pass
    def __call__(self, inputs):
        return self.forward(inputs)
    def forward(self, inputs):
        raise NotImplementedError
    def backward(self, inputs):
        raise NotImplementedError
class Linear(Op):
    def __init__(self, input_size):
        self.input_size = input_size
        # 模型参数
        self.params = {}
        self.params['w'] = torch.randn([self.input_size, 1])
        self.params['b'] = torch.zeros(1)
    def __call__(self, X):
        return self.forward(X)
    # 前向函数
    def forward(self, X):
        N, D = X.shape
        if self.input_size == 0:
            return torch.full([N, 1], fill_value=self.params['b'])

        assert D == self.input_size  # 输入数据维度合法性验证
        # 使用paddle.matmul计算两个tensor的乘积
        y_pred = torch.matmul(X, self.params['w']) + self.params['b']
        return y_pred
def optimizer_lsm(model, X, y, reg_lambda=0):
    N, D = X.shape
    # 确保 X 和 y 是相同的数据类型,张量数据类型不匹配导致错误
    X = X.float()
    y = y.float()
    # 计算输入特征的均值
    x_bar_tran = X.mean(dim=0, keepdim=True)
    # 计算标签的均值
    y_bar = y.mean()
    # 从输入中减去均值
    x_sub = X - x_bar_tran
    # 检查 x_sub 是否全为零
    if torch.all(x_sub == 0):
        model.params['b'] = y_bar
        model.params['w'] = torch.zeros(D, dtype=X.dtype)  # 使用与 X 相同的数据类型
        return model
    # 计算逆矩阵
    tmp = torch.inverse(torch.matmul(x_sub.T, x_sub) + reg_lambda * torch.eye(D, dtype=X.dtype))
    # 计算权重
    w = torch.matmul(tmp, x_sub.T @ (y - y_bar))
    # 计算偏置
    b = y_bar - torch.matmul(x_bar_tran, w)

    model.params['b'] = b
    model.params['w'] = w.squeeze(-1)

    return model
def mean_squared_error(y_true, y_pred):
    assert y_true.shape[0] == y_pred.shape[0]
    # torch.square计算输入的平方值
    # torch.mean沿 axis 计算 x 的平均值,默认axis是None,则对输入的全部元素计算平均值。
    error = torch.mean(torch.square(y_true - y_pred))
    return error
# 使用的非线性函数为sin函数
def sin(x):
    y = torch.sin(2 * math.pi * x)
    return y
#数据集构建
def create_toy_data(func, interval, sample_num, noise = 0.0, add_outlier = False, outlier_ratio = 0.001):
    """
    根据给定的函数,生成样本
    输入: func:函数 interval: x的取值范围 sample_num: 样本数目 noise: 噪声均方差 add_outlier:是否生成异常值 outlier_ratio:异常值占比
    输出: X: 特征数据,shape=[n_samples,1] y: 标签数据,shape=[n_samples,1]
    """
    # 均匀采样,使用torch.rand在生成sample_num个随机数
    X = torch.rand(size = [sample_num]) * (interval[1]-interval[0]) + interval[0]
    y = func(X)
    # 生成高斯分布的标签噪声
    # 使用torch.normal生成0均值,noise标准差的数据
    epsilon = torch.tensor(np.random.normal(0,noise,size=y.shape[0]))
    y = y + epsilon
    if add_outlier:     # 生成额外的异常点
        outlier_num = int(len(y)*outlier_ratio)
        if outlier_num != 0:
            # 使用torch.randint生成服从均匀分布的、范围在[0, len(y))的随机Tensor
            outlier_idx = torch.randint(len(y),[outlier_num])
            y[outlier_idx] = y[outlier_idx] * 5
    return X, y
# 生成数据
func = sin
interval = (0,1)
train_num = 50
test_num = 10
noise = 0.5 #0.1
X_train, y_train = create_toy_data(func=func, interval=interval, sample_num=train_num, noise = noise)
X_test, y_test = create_toy_data(func=func, interval=interval, sample_num=test_num, noise = noise)
# 改为pytorch时,将num改为steps
X_underlying = torch.linspace(interval[0],interval[1],steps=100)
y_underlying = sin(X_underlying)
# 绘制图像
plt.rcParams['figure.figsize'] = (8.0, 6.0)
plt.scatter(X_train, y_train, facecolor="none", edgecolor='#e4007f', s=50, label="train data")

plt.plot(X_underlying, y_underlying, c='#000000', label=r"$\sin(2\pi x)$")
plt.legend(fontsize='x-large')
plt.savefig('ml-vis2.pdf')
plt.show()
# 模型构建
def polynomial_basis_function(x, degree=2):
    """
    输入:x: tensor, 输入的数据,shape=[N,1] degree: int, 多项式的阶数example Input: [[2], [3], [4]], degree=2 example Output: [[2^1, 2^2], [3^1, 3^2], [4^1, 4^2]]
       注意:本案例中,在degree>=1时不生成全为1的一列数据;degree为0时生成形状与输入相同,全1的Tensor
    输出:x_result: tensor
    """
    if degree == 0:
        return torch.ones(x.shape, dtype=torch.float32)
    x_tmp = x
    x_result = x_tmp
    for i in range(2, degree + 1):
        x_tmp = torch.multiply(x_tmp, x)  # 逐元素相乘
        x_result = torch.cat((x_result, x_tmp), dim=-1)
    return x_result

# 模型训练
plt.rcParams['figure.figsize'] = (12.0, 8.0)
for i, degree in enumerate([0, 1, 3, 8]):  # []中为多项式的阶数
    model = Linear(degree)
    X_train_transformed = polynomial_basis_function(X_train.reshape([-1, 1]), degree)

    X_underlying_transformed = polynomial_basis_function(X_underlying.reshape([-1, 1]), degree)
    model = optimizer_lsm(model, X_train_transformed, y_train.reshape([-1, 1]))  # 拟合得到参数

    y_underlying_pred = model(X_underlying_transformed).squeeze()

    print(model.params)

    # 绘制图像
    plt.subplot(2, 2, i + 1)
    plt.scatter(X_train, y_train, facecolor="none", edgecolor='#e4007f', s=50, label="train data")
    plt.plot(X_underlying, y_underlying, c='#000000', label=r"$\sin(2\pi x)$")
    plt.plot(X_underlying, y_underlying_pred, c='#f19ec2', label="predicted function")
    plt.ylim(-2, 1.5)
    plt.annotate("M={}".format(degree), xy=(0.95, -1.4))

# plt.legend(bbox_to_anchor=(1.05, 0.64), loc=2, borderaxespad=0.)
plt.legend(loc='lower left', fontsize='x-large')
plt.savefig('ml-vis3.pdf')
plt.show()
# 模型评估
# 训练误差和测试误差
training_errors = []
test_errors = []
distribution_errors = []
# 遍历多项式阶数
for i in range(9):
    model = Linear(i)

    X_train_transformed = polynomial_basis_function(X_train.reshape([-1, 1]), i)
    X_test_transformed = polynomial_basis_function(X_test.reshape([-1, 1]), i)
    X_underlying_transformed = polynomial_basis_function(X_underlying.reshape([-1, 1]), i)

    optimizer_lsm(model, X_train_transformed, y_train.reshape([-1, 1]))

    y_train_pred = model(X_train_transformed).squeeze()
    y_test_pred = model(X_test_transformed).squeeze()
    y_underlying_pred = model(X_underlying_transformed).squeeze()

    train_mse = mean_squared_error(y_true=y_train, y_pred=y_train_pred).item()
    training_errors.append(train_mse)

    test_mse = mean_squared_error(y_true=y_test, y_pred=y_test_pred).item()
    test_errors.append(test_mse)

    distribution_mse = mean_squared_error(y_true=y_underlying, y_pred=y_underlying_pred).item()
    distribution_errors.append(distribution_mse)

print("train errors: \n", training_errors)
print("test errors: \n", test_errors)
print ("distribution errors: \n", distribution_errors)

# 绘制图片
plt.rcParams['figure.figsize'] = (8.0, 6.0)
plt.plot(training_errors, '-.', mfc="none", mec='#e4007f', ms=10, c='#e4007f', label="Training")
plt.plot(test_errors, '--', mfc="none", mec='#f19ec2', ms=10, c='#f19ec2', label="Test")
plt.plot(distribution_errors, '-', mfc="none", mec="#3D3D3F", ms=10, c="#3D3D3F", label="Distribution")
plt.legend(fontsize='x-large')
plt.xlabel("degree")
plt.ylabel("MSE")
plt.show()

#针对过拟合的解决情况
degree = 6 # 多项式阶数
reg_lambda = 0.00001 # 正则化系数
X_train_transformed = polynomial_basis_function(X_train.reshape([-1,1]), degree)
X_test_transformed = polynomial_basis_function(X_test.reshape([-1,1]), degree)
X_underlying_transformed = polynomial_basis_function(X_underlying.reshape([-1,1]), degree)

model = Linear(degree)
optimizer_lsm(model,X_train_transformed,y_train.reshape([-1,1]))

y_test_pred=model(X_test_transformed).squeeze()
y_underlying_pred=model(X_underlying_transformed).squeeze()

model_reg = Linear(degree)

optimizer_lsm(model_reg,X_train_transformed,y_train.reshape([-1,1]),reg_lambda)

y_test_pred_reg=model_reg(X_test_transformed).squeeze()
y_underlying_pred_reg=model_reg(X_underlying_transformed).squeeze()

mse = mean_squared_error(y_true = y_test, y_pred = y_test_pred).item()
print("mse:",mse)
mes_reg = mean_squared_error(y_true = y_test, y_pred = y_test_pred_reg).item()
print("mse_with_l2_reg:",mes_reg)

# 绘制图像
plt.scatter(X_train, y_train, facecolor="none", edgecolor="#e4007f", s=50, label="train data")
plt.plot(X_underlying, y_underlying, c='#000000', label=r"$\sin(2\pi x)$")
plt.plot(X_underlying, y_underlying_pred, c='#e4007f', linestyle="--", label="$deg. = 6$")
plt.plot(X_underlying, y_underlying_pred_reg, c='#f19ec2', linestyle="-.", label="$deg. = 6, \ell_2 reg$")
plt.ylim(-1.5, 1.5)
plt.annotate("lambda={}".format(reg_lambda), xy=(0.82, -1.4))
plt.legend(fontsize='large')
plt.show()

 

(1)构建数据集与简单线性回归类似

(2)构建模型后的简单测试

同样学习参数w,只不过需要对输入特征根据多项式阶数进行变换

(3)训练模型

使用简单线性规划中的函数,最小化均方误差

增加训练集个数

(4)模型评估

通过均方误差来衡量训练误差、测试误差以及在没有噪音的加入下sin函数值与多项式回归值之间的误差

(5)针对过拟合处理情况

添加一个惩罚项来避免系数倾向于较大的取值,并加入正则化值

更改项数和正则化的值,再次运行

思考:如果训练数据中存在一些异常样本,会对最终模型有何影响?怎样处理可以尽可能减少异常样本对模型的影响?

可能导致过拟合,w,b计算不正确,可以通过数据预处理移除异常值,在回归任务中对正常值和异常值设置不同的权重,添加正则化减少模型复杂度等方法。

3.基于线性回归的波士顿房价分析

import pandas as pd # 开源数据分析和操作工具
import os
import torch
import matplotlib.pyplot as plt
import torch.nn as nn
torch.seed()
# 处理数据集
# 利用pandas加载波士顿房价的数据集
data=pd.read_csv('boston_house_prices.csv')
# 预览前5行数据
print(data.head())
print(data.isna().sum())# 查看缺失值
# 绘制箱线图查看异常值分布
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": "#C54680"},  # 均值的属性
                    medianprops={"color": "#946279"},  # 中位数线的属性
                    whiskerprops={"color": "#8E004D", "linewidth": 0.4, 'linestyle': "--"},
                    flierprops={"markersize": 0.4},
                    )
        plt.title(col_name, fontdict={"size": 5}, pad=2)
        plt.yticks(fontsize=4, rotation=90)
        plt.tick_params(pad=0.5)
        plt.xticks([])
    plt.savefig(fig_name)
    plt.show()
boxplot(data, 'ml-vis5.pdf')
# 四分位处理异常值
num_features = data.select_dtypes(exclude=['object', 'bool']).columns.tolist()
for feature in num_features:
    if feature == 'CHAS':
        continue

    Q1 = data[feature].quantile(q=0.25)  # 下四分位
    Q3 = data[feature].quantile(q=0.75)  # 上四分位

    IQR = Q3 - Q1
    top = Q3 + 1.5 * IQR  # 最大估计值
    bot = Q1 - 1.5 * IQR  # 最小估计值
    values = data[feature].values
    values[values > top] = top  # 临界值取代噪声
    values[values < bot] = bot  # 临界值取代噪声
    data[feature] = values.astype(data[feature].dtypes)
# 再次查看箱线图,异常值已被临界值替换(数据量较多或本身异常值较少时,箱线图展示会不容易体现出来)
boxplot(data, 'ml-vis6.pdf')

# 划分训练集和测试集
def train_test_split(X, y, train_percent=0.8):
    n = len(X)
    shuffled_indices = torch.randperm(n)  # 返回一个数值在0到n-1、随机排列的1-D Tensor
    train_set_size = int(n * train_percent)
    train_indices = shuffled_indices[:train_set_size]
    test_indices = shuffled_indices[train_set_size:]

    X = X.values
    y = y.values
    X_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_test
# 进行归一化处理
X = data.drop(['MEDV'], axis=1)
y = data['MEDV']
X_train, X_test, y_train, y_test = train_test_split(X, y)  # X_train每一行是个样本,shape[N,D]
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).values
X_max = torch.max(X_train, dim=0).values

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)

# 模型构建,用到线性回归中算子
class Op(object):
    def __init__(self):
        pass
    def __call__(self, inputs):
        return self.forward(inputs)
    def forward(self, inputs):
        raise NotImplementedError
    def 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([self.input_size, 1])
        self.params['b'] = torch.zeros(1)
    def __call__(self, X):
        return self.forward(X)
    # 前向函数
    def forward(self, X):
        N, D = X.shape
        if self.input_size == 0:
            return torch.full([N, 1], fill_value=self.params['b'])
        assert D == self.input_size  # 输入数据维度合法性验证
        # 使用paddle.matmul计算两个tensor的乘积
        y_pred = torch.matmul(X, self.params['w']) + self.params['b']
        return y_pred

input_size = 12
model=Linear(input_size)

#完善Runner类,用到线性回归中模型优化函数
def optimizer_lsm(model, X, y, reg_lambda=0):
    N, D = X.shape
    # 确保 X 和 y 是相同的数据类型,张量数据类型不匹配导致错误
    X = X.float()
    y = y.float()
    # 计算输入特征的均值
    x_bar_tran = X.mean(dim=0, keepdim=True)
    # 计算标签的均值
    y_bar = y.mean()
    # 从输入中减去均值
    x_sub = X - x_bar_tran
    # 检查 x_sub 是否全为零
    if torch.all(x_sub == 0):
        model.params['b'] = y_bar
        model.params['w'] = torch.zeros(D, dtype=X.dtype)  # 使用与 X 相同的数据类型
        return model
    # 计算逆矩阵
    tmp = torch.inverse(torch.matmul(x_sub.T, x_sub) + reg_lambda * torch.eye(D, dtype=X.dtype))
    # 计算权重
    w = torch.matmul(tmp, x_sub.T @ (y - y_bar))
    # 计算偏置
    b = y_bar - torch.matmul(x_bar_tran, w)

    model.params['b'] = b
    model.params['w'] = w.squeeze(-1)
class Runner(object):
    def __init__(self, model, optimizer, loss_fn, metric):
        # 优化器和损失函数为None,不再关注

        # 模型
        self.model = model
        # 评估指标
        self.metric = metric
        # 优化器
        self.optimizer = optimizer

    def train(self, dataset, reg_lambda, model_dir):
        X, y = dataset
        self.optimizer(self.model, X, y, reg_lambda)

        # 保存模型
        self.save_model(model_dir)

    def evaluate(self, dataset, **kwargs):
        X, y = dataset

        y_pred = self.model(X)
        result = self.metric(y_pred, y)

        return result

    def 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(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)

optimizer = optimizer_lsm
mse_loss = nn.MSELoss()
# 实例化Runner
runner = Runner(model, optimizer=optimizer, loss_fn=None, metric=mse_loss)

# 模型训练
saved_dir = 'models'
# 启动训练
runner.train(train_dataset,reg_lambda=0,model_dir=saved_dir)
columns_list = data.columns.to_list()
weights = runner.model.params['w'].tolist()
b = runner.model.params['b'].item()
for i in range(len(weights)):
    print(columns_list[i],"weight:",weights[i])
print("b:",b)

# 测试模型
# 加载模型权重
runner.load_model(saved_dir)
mse = runner.evaluate(test_dataset)
print('MSE:', mse.item())

# 用此模型预测房价
runner.load_model(saved_dir)
pred = runner.predict(X_test[:1])
print("真实房价:",y_test[:1].item())
print("预测的房价:",pred.item())

针对于箱线图的具体介绍 

(1)数据处理 :数据清洗、数据集划分、特征工程

 

经过四分位处理后的箱线图 

 

(2)模型构建

用优化器对神经网络进行构建,用与线性模型相同的Linear类实现了线性层的基本功能,包括初始化参数和执行前向传播,允许你通过调用实例来计算线性变换.

(3)模型训练

观察出各种因素与房价之间的关系

(4)模型测试

加载训练好的模型参数,在测试集上得到模型的MSE指标

(5)模型预测

 预测值与真实值相差不多。

### 实验三:线性回归的相关资料教程 以下是关于实验三线性回归以及头歌教育平台相关内容的总结: #### 关于线性回归的基础知识 线性回归是一种用于建立自变量和因变量之间线性关系的统计方法。其核心在于通过最小化误差平方和来估计最佳拟合直线参数[^2]。具体来说,这种方法的目标是找到能够最大程度减少预测值实际观测值之间差异的模型参数。 #### Python实现线性回归 在Python中,可以利用多种工具包完成线性回归分析,例如`scikit-learn`、`numpy`等。这些库提供了便捷的方法构建并评估线性回归模型[^4]。下面是一个简单的例子展示如何使用`scikit-learn`进行线性回归建模: ```python from sklearn.linear_model import LinearRegression import numpy as np # 创建样本数据 X = np.array([[1], [2], [3], [4], [5]]) y = np.array([2, 4, 6, 8, 10]) # 初始化线性回归对象 model = LinearRegression() # 训练模型 model.fit(X, y) # 输出系数和截距 print(f'Coefficients: {model.coef_}') print(f'Intercept: {model.intercept_}') # 预测新数据 new_X = [[6]] prediction = model.predict(new_X) print(f'Prediction for X={new_X}: {prediction}') ``` 此代码片段展示了如何定义一个简单的一元线性回归问题,并计算相应的斜率和截距。 #### MATLAB中的线性回归模拟 对于那些更倾向于MATLAB环境的人来说,也可以采用该软件执行类似的线性回归操作。MATLAB内置了许多强大的功能支持数据分析和可视化处理,非常适合用来验证理论概念或者教学演示[^3]。 #### 头歌教育平台上的资源推荐 虽然未直接提及具体的课程名称或链接地址,但是可以通过访问头歌官网搜索关键词如“线性回归”、“机器学习入门”等相关主题获取更多信息。通常情况下,在这类平台上会提供详细的文档说明加上配套练习题目供学生实践巩固所学知识点[^1]。 ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值