1.为什么使用多维的特征输入

对于现实世界来说,影响一个事物发展的因素有很多种,拿老师上课的例子来说,例如身高、体重都会影响一个在半年后患糖尿病的概率,会使得输入的数据变成一个二维表的结构

1


2. 多维特征向量输入推导

对于一维的特征向量的输入,有:

y ^ ( i ) = σ ( x ( i ) ∗ ω + b ) \hat{y}^{(i)}=\sigma\left(x^{(i)} * \omega+b\right) y^(i)=σ(x(i)ω+b)

现对于1个样本8个维度的空间向量,由于我们要求的输出结果是这个输入样本(8个维度)有多少的概率是属于第一类的或者是属于第二类的,所以最终的到的结果肯定是一个值,所以我们通过累加将其向量进行加和,可得:

y ^ ( i ) = σ ( ∑ n = 1 8 x n ( i ) ⋅ ω n + b ) \hat{y}^{(i)}=\sigma\left(\sum_{n=1}^{8} x_{n}^{(i)} \cdot \omega_{n}+b\right) y^(i)=σ(n=18xn(i)ωn+b)

若将其括号内的求和式子展开可得:

∑ n = 1 8 x n ( i ) ⋅ ω n = [ x 1 ( i ) ⋯ x N ( i ) ] [ ω 1 ⋮ ω 8 ] \sum_{n=1}^{8} x_{n}^{(i)} \cdot \omega_{n}=\left[\begin{array}{lll} x_{1}^{(i)} & \cdots & x_{N}^{(i)} \end{array}\right]\left[\begin{array}{c} \omega_{1} \\ \vdots \\ \omega_{8} \end{array}\right] n=18xn(i)ωn=[x1(i)xN(i)]ω1ω8

然后将结果待入激活函数(这里说明一下,激活函数的意义就是在线性模型里面引入非线性的变量使得模型的多个神经层在训练的时候都能发挥作用)

y ^ ( i ) = σ ( [ x 1 ( i ) ⋯ x 8 ( i ) ] [ ω 1 ⋮ ω 8 ] + b ) = σ ( z ( i ) ) \begin{aligned} \hat{y}^{(i)} &=\sigma\left(\left[\begin{array}{lll} x_{1}^{(i)} & \cdots & x_{8}^{(i)} \end{array}\right]\left[\begin{array}{c} \omega_{1} \\ \vdots \\ \omega_{8} \end{array}\right]+b\right) \\ &=\sigma\left(z^{(i)}\right) \end{aligned} y^(i)=σ[x1(i)x8(i)]ω1ω8+b=σ(z(i))

按行展开,有:

[ y ^ ( 1 ) ⋮ y ^ ( N ) ] = [ σ ( z ( 1 ) ) ⋮ σ ( z ( N ) ) ] = σ ( [ z ( 1 ) ⋮ z ( N ) ] ) \left[ \begin{array}{c} \hat{y}^{(1)}\\ \vdots\\ \hat{y}^{(N)}\\ \end{array} \right] =\left[ \begin{array}{c} \sigma \left( z^{(1)} \right)\\ \vdots\\ \sigma \left( z^{(N)} \right)\\ \end{array} \right] =\sigma \left( \left[ \begin{array}{c} z^{(1)}\\ \vdots\\ z^{(N)}\\ \end{array} \right] \right) y^(1)y^(N)=σ(z(1))σ(z(N))=σz(1)z(N)

对于每一个Z来说,有:
z ( 1 ) = [ x 1 ( 1 ) ⋯ x 8 ( 1 ) ] [ ω 1 ⋮ ω 8 ] + b z ( N ) = [ x 1 ( N ) ⋯ x 8 ( N ) ] [ ω 1 ⋮ ω 8 ] + b \begin{aligned} &z^{(1)}=\left[\begin{array}{lll} x_{1}^{(1)} & \cdots & x_{8}^{(1)} \end{array}\right]\left[\begin{array}{c} \omega_{1} \\ \vdots \\ \omega_{8} \end{array}\right]+b \\ &z^{(N)}=\left[\begin{array}{lll} x_{1}^{(N)} & \cdots & x_{8}^{(N)} \end{array}\right]\left[\begin{array}{c} \omega_{1} \\ \vdots \\ \omega_{8} \end{array}\right]+b \end{aligned} z(1)=[x1(1)x8(1)]ω1ω8+bz(N)=[x1(N)x8(N)]ω1ω8+b

最后可得:

[ z ( 1 ) ⋮ z Z ( N ) ] = [ x 1 ( 1 ) … x 8 ( 1 ) ⋮ ⋱ ⋮ x 1 ( N ) … x 8 ( N ) ] [ ω 1 ⋮ ω 8 ] + [ b ⋮ b ] \left[\begin{array}{c} z^{(1)} \\ \vdots \\ z_{Z}(N) \end{array}\right]=\left[\begin{array}{ccc} x_{1}^{(1)} & \ldots & x_{8}^{(1)} \\ \vdots & \ddots & \vdots \\ x_{1}^{(N)} & \ldots & x_{8}^{(N)} \end{array}\right]\left[\begin{array}{c} \omega_{1} \\ \vdots \\ \omega_{8} \end{array}\right]+\left[\begin{array}{c} b \\ \vdots \\ b \end{array}\right] z(1)zZ(N)=x1(1)x1(N)x8(1)x8(N)ω1ω8+bb

而对于源代码来说,则只需改变输入层的维度即可:

class Model(torch.nn.Module):
	def __ self:
		super (Model, self ).).__
		self .linear = torch. Linear(8, 1) #修改这里
		self .sigmoid = torch.nn.
	def forward( self , x)
		x = self.sigmoid(self.linear(x)
		return x
model = Model()

3.实现过程

3.1源代码

# -*- coding:utf-8 -8-
"""
Author: Leung
Date: 2021--08--04
"""

import numpy as np
import torch
import matplotlib.pyplot as plt

# 导入数据
xy = np.loadtxt('diabetes.csv.gz', delimiter=',', dtype=np.float32)
# 以逗号作为分隔符,使用32位浮点数,不用double:适应显卡的性能

x_data = torch.from_numpy(xy[:, :-1])  # 选择所有行,从第一列开始,最后一列不要,拿出前面8列
y_data = torch.from_numpy(xy[:, [-1]])  # 所有行,只是拿出最后一列,使用[]是为了数据类型统一为矩阵


# form_numpy是为了转换为Torch类型

# ==================Step2:Design Model using calss========================

class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()

        # 多维转换
        self.linear1 = torch.nn.Linear(8, 6)
        self.linear2 = torch.nn.Linear(6, 4)
        self.Linear3 = torch.nn.Linear(4, 1)
        self.sigmoid = torch.nn.Sigmoid()  # 我们以后只是那它来做计算图,只需要一份
        # self.sigmoid = torch.nn.Tanh()
        # self.sigmoid = torch.nn.ReLU()

    def forward(self, x):
        # 如果模型是序列型的模型,只需要这样做就行了
        x = self.sigmoid(self.linear1(x))  # o1
        x = self.sigmoid(self.linear2(x))  # o2
        x = self.sigmoid(self.Linear3(x))  # y_hat
        return x


model = Model()

# =====================Step3:Construct loss & optimizer=======================
criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 存储迭代数值
lost_vector = []
epoch_vect = np.arange(1, 1001)

# =====================Step4:Training Cycle===================================

#注意我们在这里直接将所有的数据放进来,没有做mini-Batch
for epoch in range(1000):
    # Forward
    y_pred = model(x_data)
    loss = criterion(y_pred, y_data)
    print(epoch, loss.item())
    lost_vector.append(loss.item())

    #Backward
    optimizer.zero_grad()
    loss.backward()

    #Update
    optimizer.step()

# 画图
plt.xlabel("Num of Loops")
plt.ylabel("Loss")
plt.plot(epoch_vect,lost_vector)
plt.show()

3.2训练结果

1


写在最后

本文章为《PyTorch深度学习实践》完结合集课程对应的一些课后习题解答,仅为各位同志学习参考之用

各位看官,都看到这里了,麻烦动动手指头给博主来个点赞8,您的支持作者最大的创作动力哟! <(^-^)>
才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位同志作为学习交流之用,不作任何商业用途,若涉及版权问题请速与作者联系,望悉知

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐